Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Solution: Parse ini file

package main

import (
	"bufio"
	"fmt"
	"os"
	"regexp"
)

func main() {

}

func parseIni(filename string) (map[string]map[string]string, error) {
	ini := make(map[string]map[string]string)
	var head string

	fh, err := os.Open(filename)
	if err != nil {
		return ini, fmt.Errorf("Could not open file '%v': %v", filename, err)
	}
	sectionHead := regexp.MustCompile(`^\[([^]]*)\]\s*$`)
	keyValue := regexp.MustCompile(`^(\w*)\s*=\s*(.*?)\s*$`)
	reader := bufio.NewReader(fh)
	for {
		line, _ := reader.ReadString('\n')
		//fmt.Print(line)
		result := sectionHead.FindStringSubmatch(line)
		if len(result) > 0 {
			head = result[1]
			//fmt.Printf("found: %s\n", head)
			ini[head] = make(map[string]string)
			continue
		}

		result = keyValue.FindStringSubmatch(line)
		if len(result) > 0 {
			key, value := result[1], result[2]
			//fmt.Printf("kv: '%q'\n", result)
			ini[head][key] = value
			continue
		}

		if line == "" {
			break
		}
	}

	//ini["foo"] = "bar"

	return ini, nil
}
package main

import (
	"fmt"
	"testing"
)

func TestParseIni(t *testing.T) {
	actual, err := parseIni("data.ini")
	if err != nil {
		t.Error(fmt.Sprintf("Error in parsing: '%v'", err))
	}
	expected := make(map[string]map[string]string)
	expected["first section"] = make(map[string]string)
	expected["first section"]["a"] = "23"
	expected["first section"]["b"] = "12"
	expected["second section"] = make(map[string]string)
	expected["second section"]["a"] = "42"
	if !compareMapMap(actual, expected) {
		t.Error(fmt.Sprintf("Expected '%v', Actual '%v'", expected, actual))
	}
}

func compareMapMap(a, b map[string]map[string]string) bool {
	//fmt.Println(a)
	//fmt.Println(b)
	if len(a) != len(b) {
		return false
	}
	for key, value := range a {
		if !compareMap(value, b[key]) {
			return false
		}
	}
	for key, value := range b {
		if !compareMap(value, a[key]) {
			return false
		}
	}
	return true
}

func compareMap(a, b map[string]string) bool {
	//fmt.Println(a)
	//fmt.Println(b)
	if len(a) != len(b) {
		return false
	}
	for key, value := range a {
		if value != b[key] {
			return false
		}
	}
	for key, value := range b {
		if value != a[key] {
			return false
		}
	}
	return true
}