mini.go
func (config *Config) InitializeFromReader(input io.Reader) error {

	var currentSection *configSection

	scanner := bufio.NewScanner(input)
	config.values = make(map[string]interface{})
	config.sections = make(map[string]*configSection)

	for scanner.Scan() {
		curLine := scanner.Text()

		curLine = strings.TrimSpace(curLine)

		if len(curLine) == 0 {
			continue // ignore empty lines
		}

		if strings.HasPrefix(curLine, ";") || strings.HasPrefix(curLine, "#") {
			continue // comment
		}

		if strings.HasPrefix(curLine, "[") {

			if !strings.HasSuffix(curLine, "]") {
				return errors.New("mini: section names must be surrounded by [ and ], as in [section]")
			}

			sectionName := curLine[1 : len(curLine)-1]

			if sect, ok := config.sections[sectionName]; !ok { //reuse sections
				currentSection = new(configSection)
				currentSection.name = sectionName
				currentSection.values = make(map[string]interface{})
				config.sections[currentSection.name] = currentSection
			} else {
				currentSection = sect
			}

			continue
		}

		index := strings.Index(curLine, "=")

		if index <= 0 {
			return errors.New("mini: configuration format requires an equals between the key and value")
		}

		key := strings.ToLower(strings.TrimSpace(curLine[0:index]))
		isArray := strings.HasSuffix(key, "[]")

		if isArray {
			key = key[0 : len(key)-2]
		}

		value := strings.TrimSpace(curLine[index+1:])
		value = strings.Trim(value, "\"'") //clear quotes

		valueMap := config.values

		if currentSection != nil {
			valueMap = currentSection.values
		}

		if isArray {
			arr := valueMap[key]

			if arr == nil {
				arr = make([]interface{}, 0)
				valueMap[key] = arr
			}

			valueMap[key] = append(arr.([]interface{}), value)
		} else {
			valueMap[key] = value
		}
	}

	return scanner.Err()
}
func (config *Config) InitializeFromReader(input io.Reader) error {

	var currentSection *configSection

	scanner := bufio.NewScanner(input)
	config.values = make(map[string]interface{})
	config.sections = make(map[string]*configSection)

	for scanner.Scan() {
		curLine := scanner.Text()

		curLine = strings.TrimSpace(curLine)

		if len(curLine) == 0 {
			continue // ignore empty lines
		}

		if strings.HasPrefix(curLine, ";") || strings.HasPrefix(curLine, "#") {
			continue // comment
		}

		if strings.HasPrefix(curLine, "[") {

			if !strings.HasSuffix(curLine, "]") {
				return errors.New("mini: section names must be surrounded by [ and ], as in [section]")
			}

			sectionName := curLine[1 : len(curLine)-1]

			if sect, ok := config.sections[sectionName]; !ok { //reuse sections
				currentSection = new(configSection)
				currentSection.name = sectionName
				currentSection.values = make(map[string]interface{})
				config.sections[currentSection.name] = currentSection
			} else {
				currentSection = sect
			}

			continue
		}

		index := strings.Index(curLine, "=")

		if index <= 0 {
			return errors.New("mini: configuration format requires an equals between the key and value")
		}

		key := strings.ToLower(strings.TrimSpace(curLine[0:index]))
		isArray := strings.HasSuffix(key, "[]")

		if isArray {
			key = key[0 : len(key)-2]
		}

		value := strings.TrimSpace(curLine[index+1:])
		value = strings.Trim(value, "\"'") //clear quotes

		valueMap := config.values

		if currentSection != nil {
			valueMap = currentSection.values
		}

		if isArray {
			arr := valueMap[key]

			if arr == nil {
				arr = make([]interface{}, 0)
				valueMap[key] = arr
			}

			valueMap[key] = append(arr.([]interface{}), value)
		} else {
			valueMap[key] = value
		}
	}

	return scanner.Err()
}
/*
InitializeFromReader takes a reader and scans it for an ini configuration.
The caller should close the reader.
*/