Callback parser which finds export-ignore rules in git attribute lines

@param string $line A line from .gitattributes

@return array An exclude pattern for filter()
334193
public function parseGitAttributesLine($line)
    {
        $parts = preg_split('#\s+#', $line);

        if (count($parts) != 2) {
            return null;
        }

        if ($parts[1] === 'export-ignore') {
            return $this->generatePattern($parts[0]);
        }
    }
793111
protected function parseControlLine( Line$line ):self
	{
		$node= new ControlNode($this,$line);

		return $this->appendLine($node->open())->openNode($node);
	}
671872
protected function blockInclude($line)
    {
        if ($this->config["include"]
            && preg_match("/^#include[ \t]([\w.]+)$/", $line, $matches)
        ) {
            $file = $this->config["include_base"]."/".$matches[1];

            if (!is_readable($file)) {
                throw new Exception("Could not find include file: '$file'");
            }

            $include = file_get_contents($file);
            $include = str_replace(array("\r\n", "\r"), "\n", $include);
            $include = explode("\n", $include);
            array_splice(
                $this->lines,
                $this->lineNumber - 1,
                1,
                $include
            );

            $this->lineNumber--;
            return true;
        }
    }
199814
protected function validateRequestLine($line)
    {
        $matches = [0 => null, 1 => null];

        if (!preg_match(self::REQUEST_LINE_REGEX, $line, $matches) || !$matches[1]) {
            throw new BadRequestException('Invalid request line', 400);
        }

        return $matches[1];
    }
132544
protected function parseTag($line)
    {
        $tagAndValue = preg_split('/\\s/', $line, 2);
        $tag = substr($tagAndValue[0], 1);
        if (count($tagAndValue) > 1) {
            $this->tags[$tag][] = trim($tagAndValue[1]);
        } else {
            $this->tags[$tag] = [];
        }
    }
549934
private function parseLine($line)
    {
        if (!$line) {
            return array();
        }

        $line = trim($line);

        if (!$line) {
            return array();
        }

        $array = array();
        $group = $this->nodeContainsGroup($line);

        if ($group) {
            $this->addGroup($line, $group);
            $line = $this->stripGroup ($line, $group);
        }
        if ($this->startsMappedSequence($line)) {
            return $this->returnMappedSequence($line);
        }
        if ($this->startsMappedValue($line)) {
            return $this->returnMappedValue($line);
        }
        if ($this->isArrayElement($line)) {
            return $this->returnArrayElement($line);
        }
        if ($this->isPlainArray($line)) {
            return $this->returnPlainArray($line);
        }

        return $this->returnKeyValuePair($line);
    }
791214
protected function parseExpressionLine( Line$line ):self
	{
		$content=  $line->slice(1);
		$ent_flag= var_export($this->htsl->getConfig('ENT_flags',$this->docType),true);
		$charset=   var_export($this->htsl->getConfig('charset'),true);

		return $this->openNode(new StringNode($this,$line))->appendLine("<?=htmlentities($content,$ent_flag,$charset,false)?>");
	}
69357
public function parse($line)
    {
        $object = new \stdClass();
        $matches = [];

        foreach ($this->getPatterns() as $key => $pattern) {
            $result = preg_match($pattern, $line, $matches);

            if (1 !== $result) {
                continue;
            }

            $object->$key = $matches[1];
        }

        if (false === property_exists($object, 'date')) {
            throw new FormatException;
        }

        if (false === property_exists($object, 'type')) {
            throw new FormatException;
        }

        return $object;
    }
448868
protected function decodeLine($line)
    {
        $tokens = [];
        $stack = [];
        /*
            We start to decode the response here. The understood tokens are:
                literal
                "literal" or also "lit\\er\"al"
                (literals*)
            All tokens are returned in an array. Literals in braces (the last understood
            token in the list) are returned as an array of tokens. I.e. the following response:
                "foo" baz bar ("f\\\"oo" bar)
            would be returned as:
                array('foo', 'baz', 'bar', array('f\\\"oo', 'bar'));
        */
        //  replace any trailing <NL> including spaces with a single space
        $line = rtrim($line) . ' ';
        while (($pos = strpos($line, ' ')) !== false) {
            $token = substr($line, 0, $pos);
            if (!strlen($token)) {
                continue;
            }
            while ($token[0] === '(') {
                array_push($stack, $tokens);
                $tokens = [];
                $token = substr($token, 1);
            }
            if ($token[0] === '"') {
                if (preg_match('%^\(*"((.|\\\\|\\")*?)" *%', $line, $matches)) {
                    $tokens[] = $matches[1];
                    $line = substr($line, strlen($matches[0]));
                    continue;
                }
            }
            if ($stack && $token[strlen($token) - 1] === ')') {
                // closing braces are not separated by spaces, so we need to count them
                $braces = strlen($token);
                $token = rtrim($token, ')');
                // only count braces if more than one
                $braces -= strlen($token) + 1;
                // only add if token had more than just closing braces
                if (rtrim($token) != '') {
                    $tokens[] = rtrim($token);
                }
                $token = $tokens;
                $tokens = array_pop($stack);
                // special handline if more than one closing brace
                while ($braces-- > 0) {
                    $tokens[] = $token;
                    $token = $tokens;
                    $tokens = array_pop($stack);
                }
            }
            $tokens[] = $token;
            $line = substr($line, $pos + 1);
        }
        // maybe the server forgot to send some closing braces
        while ($stack) {
            $child = $tokens;
            $tokens = array_pop($stack);
            $tokens[] = $child;
        }
        return $tokens;
    }
173106
private static function parseContent(string $line): array
    {
        /* Get position of separator */
        $separatePosition = strpos($line, self::$separator);

        /* Get config key */
        $configName = trim(substr($line, 0, $separatePosition));

        /* Get config value */
        $configValue = trim(rtrim(substr($line, $separatePosition + strlen(self::$separator)), "\n"));

        /* Transform config value to number */
        if (is_numeric($configValue)) {
            /* Is int */
            if ((int)$configValue == $configValue) {
                $configValue = (int)$configValue;
            }

            /* Is float */
            else {
                $configValue = (float)$configValue;
            }
        }

        return ['key' => $configName, 'value' => $configValue];
    }
970300
protected function parseLine($line)
    {
        // Start of a new component
        if ('BEGIN:' === strtoupper(substr($line, 0, 6))) {
            if (substr($line, 6) === $this->root->name) {
                throw new ParseException('Invalid MimeDir file. Unexpected component: "'.$line.'" in document type '.$this->root->name);
            }
            $component = $this->root->createComponent(substr($line, 6), [], false);

            while (true) {
                // Reading until we hit END:
                $line = $this->readLine();
                if ('END:' === strtoupper(substr($line, 0, 4))) {
                    break;
                }
                $result = $this->parseLine($line);
                if ($result) {
                    $component->add($result);
                }
            }

            $name = strtoupper(substr($line, 4));
            if ($name !== $component->name) {
                throw new ParseException('Invalid MimeDir file. expected: "END:'.$component->name.'" got: "END:'.$name.'"');
            }

            return $component;
        } else {
            // Property reader
            $property = $this->readProperty($line);
            if (!$property) {
                // Ignored line
                return false;
            }

            return $property;
        }
    }
419639
public function parse($line)
    {
        $this->error = false;
        $this->currentTextLineContainer = $this->textLineContainers[$this->config->defaultTextLineContainer];
        $firsttag = clone ($this->currentTextLineContainer->tag);

        $this->str = preg_split($this->currentTextLineContainer->pattern, $line, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        $this->end = count($this->str);

        if ($this->end > 1) {
            $pos = -1;
            $this->_parse($firsttag, $pos);

            return $firsttag->getContent();
        } else {
            $firsttag->addContentString($line);

            return $firsttag->getContent();
        }
    }
423585
protected function convertToArray(&$line)
    {
        $implodeStr = $this->multipleValueSeparator;
        $arr = array_map(
            function ($value, $key) use (&$implodeStr) {
                if (is_array($value) && is_numeric($key)) {
                    $this->convertToArray($value);
                    $implodeStr = '|';
                    return $value;
                }
                return sprintf("%s=%s", $key, $value);
            },
            $line,
            array_keys($line)
        );

        $line = implode(
            $implodeStr, $arr
        );
    }
540807
private function parse($line)
    {
        $uriParser = new UriParser($line);
        $line = $uriParser->encode();
        if ($uriParser->validateIP() ||
            !$uriParser->validateHost() ||
            (
                parse_url($line, PHP_URL_SCHEME) !== null &&
                !$uriParser->validateScheme()
            )
        ) {
            return false;
        }
        $parts = $this->getParts($line);
        return $parts['scheme'] . $parts['host'] . $parts['port'];
    }
381781
protected function parseLine(&$line)
    {
        switch ($this->state) {
        case self::STATE_BEGIN:
            if (trim($line)) {
                if ($this->isListLine($line)) {
                    $this->state = self::STATE_LIST;
                    $this->buffer = $this->kernel->build('Nodes\ListNode');
                    $this->lineInfo = null;
                    $this->listFlow = true;
                    return false;
                } else if ($this->isBlockLine($line)) {
                    if ($this->isCode) {
                        $this->state = self::STATE_CODE;
                    } else {
                        $this->state = self::STATE_BLOCK;
                    }
                    return false;
                } else if ($this->isDirective($line)) {
                    $this->state = self::STATE_DIRECTIVE;
                    $this->buffer = array();
                    $this->flush();
                    $this->initDirective($line);
                } else if ($this->parseLink($line)) {
                    return true;
                } else if ($parts = $this->parseTableLine($line)) {
                    $this->state = self::STATE_TABLE;
                    $this->buffer = $this->kernel->build('Nodes\TableNode', $parts);
                } else {
                    $this->state = self::STATE_NORMAL;
                    return false;
                }
            }
            break;

        case self::STATE_LIST:
            if (!$this->pushListLine($line)) {
                $this->flush();
                $this->state = self::STATE_BEGIN;
                return false;
            }
            break;

        case self::STATE_TABLE:
            if (!trim($line)) {
                $this->flush();
                $this->state = self::STATE_BEGIN;
            } else {
                $parts = $this->parseTableLine($line);

                if (!$this->buffer->push($parts, $line)) {
                    $this->flush();
                    $this->state = self::STATE_BEGIN;
                    return false;
                }
            }

            break;

        case self::STATE_NORMAL:
            if (trim($line)) {
                $specialLetter = $this->isSpecialLine($line);

                if ($specialLetter) {
                    $this->specialLetter = $specialLetter;
                    $lastLine = array_pop($this->buffer);

                    if ($lastLine) {
                        $this->buffer = array($lastLine);
                        $this->state = self::STATE_TITLE;
                    } else {
                        $this->buffer[] = $line;
                        $this->state = self::STATE_SEPARATOR;
                    }
                    $this->flush();
                    $this->state = self::STATE_BEGIN;
                } else {
                    if ($this->isDirective($line)) {
                        $this->flush();
                        $this->state = self::STATE_BEGIN;
                        return false;
                    }
                    if ($this->isComment($line)) {
                        $this->flush();
                        $this->state = self::STATE_COMMENT;
                    } else {
                        $this->buffer[] = $line;
                    }
                }
            } else {
                $this->flush();
                $this->state = self::STATE_BEGIN;
            }
            break;
        
        case self::STATE_COMMENT:
            $isComment = false;

            if (!$this->isComment($line) && (!trim($line) || $line[0] != ' ')) {
                $this->state = self::STATE_BEGIN;
                return false;
            }
            break;

        case self::STATE_BLOCK:
        case self::STATE_CODE:
            if (!$this->isBlockLine($line)) {
                $this->flush();
                $this->state = self::STATE_BEGIN;
                return false;
            } else {
                $this->buffer[] = $line;
            }
            break;

        case self::STATE_DIRECTIVE:
            if (!$this->directiveAddOption($line)) {
                if ($this->isDirective($line)) {
                    $this->flush();
                    $this->initDirective($line);
                } else {
                    $directive = $this->getCurrentDirective();
                    $this->isCode = $directive ? $directive->wantCode() : false;
                    $this->state = self::STATE_BEGIN;
                    return false;
                }
            }
            break;

        default:
            $this->getEnvironment()->getErrorManager()->error('Parser ended in an unexcepted state');
        }

        return true;
    }
379055
protected function extractElements($line)
    {
        $elements = [];
        $buffer   = '';
        $quote    = false;

        foreach (\str_split($line) as $character)
        {
            if (\in_array($character, ['\'', '"']))
            {
                $quote = ! $quote;

                continue;
            }

            if ((':' == $character) and ! $quote)
            {
                $elements[] = $buffer;

                $buffer = '';

                continue;
            }

            $buffer .= $character;
        }

        if ($buffer)
        {
            $elements[] = $buffer;
        }

        return $elements;
    }
1164329
private function getLinesNumbers(string $line)
    {
        $matches = [];
        preg_match('/@@ -(.*) \+(.*) @@?(.*)/', $line, $matches);
        if (!strpos($matches[1], ',')) {
            // one line
            $this->originStartLine = $matches[1];
            $this->originEndLine = $matches[1];
        } else {
            list($this->originStartLine, $this->originEndLine) = explode(',', $matches[1]);
        }

        if (!strpos($matches[2], ',')) {
            // one line
            $this->destStartLine = $matches[2];
            $this->destEndLine = $matches[2];
        } else {
            list($this->destStartLine, $this->destEndLine) = explode(',', $matches[2]);
        }
    }