The parsing function for .pro file is in QMakeParser::read. It uses two buffers:
- tokBuff: store the parsed tokens of a .pro file
- xprBuff: only store a line(or part of a line) of a .pro file.
c is current char, cur points to the char next to c. At first, ptr and xprPtr points to the same location of xprBuff. cur points to the beginning of a line in .pro file, cptr points to the end of the line. end also points to the end of the line. Then cur and ptr move forward(scanning), meanwhile, the chars in the line of the .pro file are copied to xprBuff at location pointed by ptr. If the scanning meets a space, it has gotten a TokHashLiteral. It copy the TokHashLiteral from input to xprBuff. The TokHashLiteral not only includes the chars from the input buffer, but also includes other information(fields) that describe the string literal. Specifically, it includes the type of the string literal(TokHashLiteral), the hash of the literal, the length of the literal, and the string literal itself:
After constructing the TokHashLiteral, ptr and xprPtr move forward in xprBuff to get ready to receive the next word. If the next word is a operator such as “+=”, ptr will move backward, and it will add a TokLine in the tokBuff. A TokLine contains its type “TokLine” and the current line number in the .pro file. The tokPtr pointer which points to a location in the tokBuff is moved forward accordingly. Then the TokHashLiteral(including the string literal and its 4 description fields-8 bytes) will be copied from xprBuff to tokBuff, and tokPtr is moved forward accordingly. We just said the scanner met a “+=” operator so a TokAppend will be added to tokBuff. The TokAppend token is simple, just contains its type “TokAppend”(3-ushort). Now, the scanner expects a value followed the “+=” operator so it changes the context from the inital CtxTest to CtxValue. Now ptr switches from pointing to xprBuff to tokBuff and points to the same location as tokPtr. Now get the next token. xprPtr is changed to be the same as ptr pointing to tokBuff instead of xprBuff. We expect the next token will be copied from input to tokBuff, not xprBuff. The next token is gotten in the same way, i.e., cur is moved forward to scan the input, ptr is moved forward to receive the token. As the next token is the last token in current line, cur will be adjusted to cptr, i.e., the beginning of next line, and FLUSH_LITERAL is called to store the token. The value token is simpler than the TokHashLiteral token in that it has only two information fields: the type(“TokLiteral”) and the length of the value string literal. Remember xprPtr always points to the beginning of the string literal, while ptr points to the end of the string literal. The information fields are put before xprPtr. Note that the right value token does not follow the left hand token immediately. They are separated by a “\0″ ushort. A TokValueTerminator token is added to the end of the value token. So after parsing the line “Qt += sql”, the tokBuff would be:
The scanner repeats the process for every line in the .pro file. But ptr and xprPtr switch back to xprBuff from tokBuff at the beginning of processing a new line. tokPtr will never switch. Note that FLUSH_LHS_LITERAL, FLUSH_RHS_LITERAL, FLUSH_LITERAL don’t adjust tokPtr, but FLUSH_VALUE_LIST, putTok, putBlock adjust tokPtr.
Now, the .pro file has been transformed to a sequence of tokens, which is set to the m_proitems member of a ProFile object. What is the sequence of tokens used for? Well, QMakeEvaluator::visitProFile will visit it. Specifically, it will call QMakeEvaluator::visitProBlock(tokPtr) to handle this sequence of tokens. Most tokens are expressions. Call evaluateExpression(tokPtr,…) to evaluate them. For operator tokens such as TokAppend, call visitProVariable(tok, curr, tokPtr).