equal
deleted
inserted
replaced
140 } |
140 } |
141 |
141 |
142 return secs[0], err |
142 return secs[0], err |
143 } |
143 } |
144 |
144 |
|
145 // HasSection returns true if the file contains a section with given name. |
|
146 func (f *File) HasSection(name string) bool { |
|
147 section, _ := f.GetSection(name) |
|
148 return section != nil |
|
149 } |
|
150 |
145 // SectionsByName returns all sections with given name. |
151 // SectionsByName returns all sections with given name. |
146 func (f *File) SectionsByName(name string) ([]*Section, error) { |
152 func (f *File) SectionsByName(name string) ([]*Section, error) { |
147 if len(name) == 0 { |
153 if len(name) == 0 { |
148 name = DefaultSection |
154 name = DefaultSection |
149 } |
155 } |
166 |
172 |
167 // Section assumes named section exists and returns a zero-value when not. |
173 // Section assumes named section exists and returns a zero-value when not. |
168 func (f *File) Section(name string) *Section { |
174 func (f *File) Section(name string) *Section { |
169 sec, err := f.GetSection(name) |
175 sec, err := f.GetSection(name) |
170 if err != nil { |
176 if err != nil { |
171 // Note: It's OK here because the only possible error is empty section name, |
177 if name == "" { |
172 // but if it's empty, this piece of code won't be executed. |
178 name = DefaultSection |
|
179 } |
173 sec, _ = f.NewSection(name) |
180 sec, _ = f.NewSection(name) |
174 return sec |
181 return sec |
175 } |
182 } |
176 return sec |
183 return sec |
177 } |
184 } |
333 equalSign = fmt.Sprintf(" %s ", f.options.KeyValueDelimiterOnWrite) |
340 equalSign = fmt.Sprintf(" %s ", f.options.KeyValueDelimiterOnWrite) |
334 } |
341 } |
335 |
342 |
336 // Use buffer to make sure target is safe until finish encoding. |
343 // Use buffer to make sure target is safe until finish encoding. |
337 buf := bytes.NewBuffer(nil) |
344 buf := bytes.NewBuffer(nil) |
|
345 lastSectionIdx := len(f.sectionList) - 1 |
338 for i, sname := range f.sectionList { |
346 for i, sname := range f.sectionList { |
339 sec := f.SectionWithIndex(sname, f.sectionIndexes[i]) |
347 sec := f.SectionWithIndex(sname, f.sectionIndexes[i]) |
340 if len(sec.Comment) > 0 { |
348 if len(sec.Comment) > 0 { |
341 // Support multiline comments |
349 // Support multiline comments |
342 lines := strings.Split(sec.Comment, LineBreak) |
350 lines := strings.Split(sec.Comment, LineBreak) |
362 if len(sec.keyList) == 0 { |
370 if len(sec.keyList) == 0 { |
363 continue |
371 continue |
364 } |
372 } |
365 } |
373 } |
366 |
374 |
|
375 isLastSection := i == lastSectionIdx |
367 if sec.isRawSection { |
376 if sec.isRawSection { |
368 if _, err := buf.WriteString(sec.rawBody); err != nil { |
377 if _, err := buf.WriteString(sec.rawBody); err != nil { |
369 return nil, err |
378 return nil, err |
370 } |
379 } |
371 |
380 |
372 if PrettySection { |
381 if PrettySection && !isLastSection { |
373 // Put a line between sections |
382 // Put a line between sections |
374 if _, err := buf.WriteString(LineBreak); err != nil { |
383 if _, err := buf.WriteString(LineBreak); err != nil { |
375 return nil, err |
384 return nil, err |
376 } |
385 } |
377 } |
386 } |
433 kname = "`" + kname + "`" |
442 kname = "`" + kname + "`" |
434 case strings.Contains(kname, "`"): |
443 case strings.Contains(kname, "`"): |
435 kname = `"""` + kname + `"""` |
444 kname = `"""` + kname + `"""` |
436 } |
445 } |
437 |
446 |
438 for _, val := range key.ValueWithShadows() { |
447 writeKeyValue := func(val string) (bool, error) { |
439 if _, err := buf.WriteString(kname); err != nil { |
448 if _, err := buf.WriteString(kname); err != nil { |
440 return nil, err |
449 return false, err |
441 } |
450 } |
442 |
451 |
443 if key.isBooleanType { |
452 if key.isBooleanType { |
444 if kname != sec.keyList[len(sec.keyList)-1] { |
453 buf.WriteString(LineBreak) |
445 buf.WriteString(LineBreak) |
454 return true, nil |
446 } |
|
447 continue KeyList |
|
448 } |
455 } |
449 |
456 |
450 // Write out alignment spaces before "=" sign |
457 // Write out alignment spaces before "=" sign |
451 if PrettyFormat { |
458 if PrettyFormat { |
452 buf.Write(alignSpaces[:alignLength-len(kname)]) |
459 buf.Write(alignSpaces[:alignLength-len(kname)]) |
459 val = "`" + val + "`" |
466 val = "`" + val + "`" |
460 } else if len(strings.TrimSpace(val)) != len(val) { |
467 } else if len(strings.TrimSpace(val)) != len(val) { |
461 val = `"` + val + `"` |
468 val = `"` + val + `"` |
462 } |
469 } |
463 if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil { |
470 if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil { |
|
471 return false, err |
|
472 } |
|
473 return false, nil |
|
474 } |
|
475 |
|
476 shadows := key.ValueWithShadows() |
|
477 if len(shadows) == 0 { |
|
478 if _, err := writeKeyValue(""); err != nil { |
464 return nil, err |
479 return nil, err |
|
480 } |
|
481 } |
|
482 |
|
483 for _, val := range shadows { |
|
484 exitLoop, err := writeKeyValue(val) |
|
485 if err != nil { |
|
486 return nil, err |
|
487 } else if exitLoop { |
|
488 continue KeyList |
465 } |
489 } |
466 } |
490 } |
467 |
491 |
468 for _, val := range key.nestedValues { |
492 for _, val := range key.nestedValues { |
469 if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil { |
493 if _, err := buf.WriteString(indent + " " + val + LineBreak); err != nil { |
470 return nil, err |
494 return nil, err |
471 } |
495 } |
472 } |
496 } |
473 } |
497 } |
474 |
498 |
475 if PrettySection { |
499 if PrettySection && !isLastSection { |
476 // Put a line between sections |
500 // Put a line between sections |
477 if _, err := buf.WriteString(LineBreak); err != nil { |
501 if _, err := buf.WriteString(LineBreak); err != nil { |
478 return nil, err |
502 return nil, err |
479 } |
503 } |
480 } |
504 } |