xref: /aosp_15_r20/external/bazelbuild-rules_android/src/common/golang/ini.go (revision 9e965d6fece27a77de5377433c2f7e6999b8cc0b)
1*9e965d6fSRomain Jobredeaux// Copyright 2018 The Bazel Authors. All rights reserved.
2*9e965d6fSRomain Jobredeaux//
3*9e965d6fSRomain Jobredeaux// Licensed under the Apache License, Version 2.0 (the "License");
4*9e965d6fSRomain Jobredeaux// you may not use this file except in compliance with the License.
5*9e965d6fSRomain Jobredeaux// You may obtain a copy of the License at
6*9e965d6fSRomain Jobredeaux//
7*9e965d6fSRomain Jobredeaux//    http://www.apache.org/licenses/LICENSE-2.0
8*9e965d6fSRomain Jobredeaux//
9*9e965d6fSRomain Jobredeaux// Unless required by applicable law or agreed to in writing, software
10*9e965d6fSRomain Jobredeaux// distributed under the License is distributed on an "AS IS" BASIS,
11*9e965d6fSRomain Jobredeaux// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9e965d6fSRomain Jobredeaux// See the License for the specific language governing permissions and
13*9e965d6fSRomain Jobredeaux// limitations under the License.
14*9e965d6fSRomain Jobredeaux
15*9e965d6fSRomain Jobredeaux// Package ini provides utility functions to read and write ini files.
16*9e965d6fSRomain Jobredeauxpackage ini
17*9e965d6fSRomain Jobredeaux
18*9e965d6fSRomain Jobredeauximport (
19*9e965d6fSRomain Jobredeaux	"fmt"
20*9e965d6fSRomain Jobredeaux	"io"
21*9e965d6fSRomain Jobredeaux	"io/ioutil"
22*9e965d6fSRomain Jobredeaux	"log"
23*9e965d6fSRomain Jobredeaux	"os"
24*9e965d6fSRomain Jobredeaux	"sort"
25*9e965d6fSRomain Jobredeaux	"strings"
26*9e965d6fSRomain Jobredeaux)
27*9e965d6fSRomain Jobredeaux
28*9e965d6fSRomain Jobredeauxfunc parse(in string) map[string]string {
29*9e965d6fSRomain Jobredeaux	m := make(map[string]string)
30*9e965d6fSRomain Jobredeaux	lines := strings.Split(in, "\n")
31*9e965d6fSRomain Jobredeaux	for i, l := range lines {
32*9e965d6fSRomain Jobredeaux		l = strings.TrimSpace(l)
33*9e965d6fSRomain Jobredeaux		if len(l) == 0 {
34*9e965d6fSRomain Jobredeaux			// Skip empty line
35*9e965d6fSRomain Jobredeaux			continue
36*9e965d6fSRomain Jobredeaux		}
37*9e965d6fSRomain Jobredeaux		if strings.HasPrefix(l, ";") || strings.HasPrefix(l, "#") {
38*9e965d6fSRomain Jobredeaux			// Skip comment
39*9e965d6fSRomain Jobredeaux			continue
40*9e965d6fSRomain Jobredeaux		}
41*9e965d6fSRomain Jobredeaux		kv := strings.SplitN(l, "=", 2)
42*9e965d6fSRomain Jobredeaux		if len(kv) < 2 {
43*9e965d6fSRomain Jobredeaux			log.Printf("Invalid line in ini file at line:%v %q\n", i, l)
44*9e965d6fSRomain Jobredeaux			// Skip invalid line
45*9e965d6fSRomain Jobredeaux			continue
46*9e965d6fSRomain Jobredeaux		}
47*9e965d6fSRomain Jobredeaux		k := strings.TrimSpace(kv[0])
48*9e965d6fSRomain Jobredeaux		v := strings.TrimSpace(kv[1])
49*9e965d6fSRomain Jobredeaux		if ov, ok := m[k]; ok {
50*9e965d6fSRomain Jobredeaux			log.Printf("Overwrite \"%s=%s\", duplicate found at line:%v %q\n", k, ov, i, l)
51*9e965d6fSRomain Jobredeaux		}
52*9e965d6fSRomain Jobredeaux		m[k] = v
53*9e965d6fSRomain Jobredeaux	}
54*9e965d6fSRomain Jobredeaux	return m
55*9e965d6fSRomain Jobredeaux}
56*9e965d6fSRomain Jobredeaux
57*9e965d6fSRomain Jobredeauxfunc write(f io.Writer, m map[string]string) {
58*9e965d6fSRomain Jobredeaux	var keys []string
59*9e965d6fSRomain Jobredeaux	for k := range m {
60*9e965d6fSRomain Jobredeaux		keys = append(keys, k)
61*9e965d6fSRomain Jobredeaux	}
62*9e965d6fSRomain Jobredeaux	sort.Strings(keys)
63*9e965d6fSRomain Jobredeaux	for _, k := range keys {
64*9e965d6fSRomain Jobredeaux		fmt.Fprintf(f, "%s=%s\n", k, m[k])
65*9e965d6fSRomain Jobredeaux	}
66*9e965d6fSRomain Jobredeaux}
67*9e965d6fSRomain Jobredeaux
68*9e965d6fSRomain Jobredeaux// Read reads an ini file.
69*9e965d6fSRomain Jobredeauxfunc Read(n string) (map[string]string, error) {
70*9e965d6fSRomain Jobredeaux	c, err := ioutil.ReadFile(n)
71*9e965d6fSRomain Jobredeaux	if err != nil {
72*9e965d6fSRomain Jobredeaux		return nil, err
73*9e965d6fSRomain Jobredeaux	}
74*9e965d6fSRomain Jobredeaux	return parse(string(c)), nil
75*9e965d6fSRomain Jobredeaux}
76*9e965d6fSRomain Jobredeaux
77*9e965d6fSRomain Jobredeaux// Write writes an ini file.
78*9e965d6fSRomain Jobredeauxfunc Write(n string, m map[string]string) error {
79*9e965d6fSRomain Jobredeaux	f, err := os.Create(n)
80*9e965d6fSRomain Jobredeaux	if err != nil {
81*9e965d6fSRomain Jobredeaux		return err
82*9e965d6fSRomain Jobredeaux	}
83*9e965d6fSRomain Jobredeaux	defer f.Close()
84*9e965d6fSRomain Jobredeaux	write(f, m)
85*9e965d6fSRomain Jobredeaux	return nil
86*9e965d6fSRomain Jobredeaux}
87