// Sets multiLine to true if the identifier list spans multiple lines.
// If indent is set, a multi-line identifier list is indented after the
// first linebreak encountered.
968858
func (p *printer) identList(list []*ast.Ident, indent bool, multiLine *bool) {
	// convert into an expression list so we can re-use exprList formatting
	xlist := make([]ast.Expr, len(list))
	for i, x := range list {
		xlist[i] = x
	}
	mode := commaSep
	if !indent {
		mode |= noIndent
	}
	p.exprList(token.NoPos, xlist, 1, mode, multiLine, token.NoPos)
}
60678
func lineSplit(s string, margin int) []string {
	var ret []string
	var buf bytes.Buffer
	for _, r := range s {
		if r == '\n' {
			ret = append(ret, stripWhitespace(buf.String(), margin))
			buf.Reset()
		} else {
			buf.WriteRune(r)
		}
	}
	return append(ret, stripWhitespace(buf.String(), margin))
}
1316123
func (this *import_data_parser) expect_ident(ident string) {
	tok := this.expect(scanner.Ident)
	if tok != ident {
		this.errorf("expected identifier: \"%s\", got: \"%s\"", ident, tok)
	}
}
1165735
func IndentTextWithMaxLength(text, indent string, maxTextLineCharWidth int, isIndentFirstLine bool) string {
	if maxTextLineCharWidth < 1 {
		return ""
	}

	formattedText := ""

	addLine := func(line string) {
		isFirstLine := (formattedText == "")
		if isFirstLine && !isIndentFirstLine {
			formattedText = line
		} else {
			if !isFirstLine {
				formattedText += "\n"
			}
			formattedText += indent + line
		}
	}

	scanner := bufio.NewScanner(strings.NewReader(text))
	for scanner.Scan() {
		line := scanner.Text()
		lineLength := len(line)
		if lineLength > maxTextLineCharWidth {
			lineCnt := math.Ceil(float64(lineLength) / float64(maxTextLineCharWidth))
			for i := 0; i < int(lineCnt); i++ {
				startIdx := i * maxTextLineCharWidth
				endIdx := startIdx + maxTextLineCharWidth
				if endIdx > lineLength {
					endIdx = lineLength
				}
				addLine(line[startIdx:endIdx])
			}
		} else {
			addLine(line)
		}
	}

	return formattedText
}
474964
func (ltype LineType) Equals(other core.DxfElement) bool {
	if otherLtype, ok := other.(*LineType); ok {
		if ltype.Name != otherLtype.Name ||
			ltype.Description != otherLtype.Description ||
			!core.FloatEquals(ltype.Length, otherLtype.Length) ||
			len(ltype.Pattern) != len(otherLtype.Pattern) {

			return false
		}

		for i, pattern1 := range ltype.Pattern {
			pattern2 := otherLtype.Pattern[i]

			if !pattern1.Equals(*pattern2) {
				return false
			}
		}
		return true
	}
	return false
}
162086
func (p *Parser) parseIdentifiersList() (sets.String, error) {
	s := sets.NewString()
	for {
		tok, lit := p.consume(Values)
		switch tok {
		case IdentifierToken:
			s.Insert(lit)
			tok2, lit2 := p.lookahead(Values)
			switch tok2 {
			case CommaToken:
				continue
			case ClosedParToken:
				return s, nil
			default:
				return nil, fmt.Errorf("found '%s', expected: ',' or ')'", lit2)
			}
		case CommaToken: // handled here since we can have "(,"
			if s.Len() == 0 {
				s.Insert("") // to handle (,
			}
			tok2, _ := p.lookahead(Values)
			if tok2 == ClosedParToken {
				s.Insert("") // to handle ,)  Double "" removed by StringSet
				return s, nil
			}
			if tok2 == CommaToken {
				p.consume(Values)
				s.Insert("") // to handle ,, Double "" removed by StringSet
			}
		default: // it can be operator
			return s, fmt.Errorf("found '%s', expected: ',', or identifier", lit)
		}
	}
}
32274
func (p *printer) unindent(buf []byte) []byte {
	var res []byte
	for i := 0; i < len(buf); i++ {
		skip := len(buf)-i <= len(unindent)
		if !skip {
			skip = !bytes.Equal(unindent, buf[i:i+len(unindent)])
		}
		if skip {
			res = append(res, buf[i])
			continue
		}

		// We have a marker. we have to backtrace here and clean out
		// any whitespace ahead of our tombstone up to a \n
		for j := len(res) - 1; j >= 0; j-- {
			if res[j] == '\n' {
				break
			}

			res = res[:j]
		}

		// Skip the entire unindent marker
		i += len(unindent) - 1
	}

	return res
}
284652
func (u *UI) Line(format string, a ...interface{}) {
	u.LineIndent(0, format, a...)
}
1224627
func wrap(text string, length int, isIndented bool) string {
	var buf bytes.Buffer
	var last rune
	var lastNL bool
	var col int

	for _, c := range text {
		switch c {
		case '\r': // ignore this
			continue // and also don't track `last`
		case '\n': // ignore this too, but reset col
			if col >= length || last == '\n' {
				buf.WriteString("\n")
			}
			buf.WriteString("\n")
			col = 0
		case ' ', '\t': // opportunity to split
			if col >= length {
				buf.WriteByte('\n')
				col = 0
				if isIndented {
					buf.WriteString(indent)
					col += 3
				}
			} else {
				// We only want to write a leading space if the col is greater than zero.
				// This will provide the proper spacing for documentation.
				buf.WriteRune(c)
				col++ // count column
			}
		default:
			buf.WriteRune(c)
			col++
		}
		lastNL = c == '\n'
		_ = lastNL
		last = c
	}
	return buf.String()
}
697209
func (l *lexer) lexWhitespace() (int, int) {
	r := l.next()
	indent := 0
	newLines := 0
	for ; isWhitespace(r); r = l.next() {
		switch r {
		case '\r':
			// Ignore.
			break

		case '\n':
			indent = 0
			newLines++
			break

		case ' ':
			indent++
			break

		// This only works for \t at the beginning of lines, but we strip it everywhere else
		// anyway.  The only case where this will cause a problem is spaces followed by \t
		// at the beginning of a line.  However that is rare, ill-advised, and if re-indentation
		// is enabled it will be fixed later.
		case '\t':
			indent += 8
			break
		}
	}
	l.backup()
	return newLines, indent
}
6730
func (i IdentifierSet) AddIdentifiers(idents Identifiers) {
	for _, ident := range idents {
		i.Add(ident)
	}
}
920874
func (ln *line) isMixinDeclaration() bool {
	if !ln.isTopIndent() {
		return false
	}

	_, _, err := mixinNP(ln, true)

	return err == nil
}
35311
func idents(ids []*syntax.Ident) []Ident {
	res := make([]Ident, len(ids))
	for i, id := range ids {
		res[i].Name = id.Name
		res[i].Pos = id.NamePos
	}
	return res
}
787271
func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
	*end_mark = parser.mark

	// Eat the intendation spaces and line breaks.
	max_indent := 0
	for {
		// Eat the intendation spaces.
		if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
			return false
		}
		for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
			skip(parser)
			if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
				return false
			}
		}
		if parser.mark.column > max_indent {
			max_indent = parser.mark.column
		}

		// Check for a tab character messing the intendation.
		if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
			return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
				start_mark, "found a tab character where an intendation space is expected")
		}

		// Have we found a non-empty line?
		if !is_break(parser.buffer, parser.buffer_pos) {
			break
		}

		// Consume the line break.
		if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
			return false
		}
		// [Go] Should really be returning breaks instead.
		*breaks = read_line(parser, *breaks)
		*end_mark = parser.mark
	}

	// Determine the indentation level if needed.
	if *indent == 0 {
		*indent = max_indent
		if *indent < parser.indent+1 {
			*indent = parser.indent + 1
		}
		if *indent < 1 {
			*indent = 1
		}
	}
	return true
}
230901
func (i IdentifierSet) ToOrderedSlice() []Identifier {
	var s []Identifier
	for v := range i {
		s = append(s, v)
	}
	sort.Sort(identifierSorter(s))
	return s
}
696402
func MultiLine(logFn func(args ...interface{}), output string) {
	scanner := bufio.NewScanner(bytes.NewReader([]byte(output)))
	for scanner.Scan() {
		logFn(scanner.Text())
	}
}
912170
func (d *Dispenser) isNewLine() bool {
	if d.cursor < 1 {
		return true
	}
	if d.cursor > len(d.tokens)-1 {
		return false
	}
	return d.tokens[d.cursor-1].File != d.tokens[d.cursor].File ||
		d.tokens[d.cursor-1].Line+d.numLineBreaks(d.cursor-1) < d.tokens[d.cursor].Line
}