/** * additional formatting for line of source code. * every line of source code in a source code file should be sent * one after the other to this function. * indents event tables * unindents the case blocks * * @param line the original formatted line will be updated if necessary. */ void ASEnhancer::enhance(string &line, bool isInPreprocessor, bool isInSQL) { shouldUnindentLine = true; shouldUnindentComment = false; lineNumber++; // check for beginning of event table if (nextLineIsEventIndent) { isInEventTable = true; nextLineIsEventIndent = false; } // check for beginning of SQL declare section if (nextLineIsDeclareIndent) { isInDeclareSection = true; nextLineIsDeclareIndent = false; } if (line.length() == 0 && ! isInEventTable && ! isInDeclareSection && ! emptyLineFill) return; // test for unindent on attached brackets if (unindentNextLine) { sw.unindentDepth++; sw.unindentCase = true; unindentNextLine = false; } // parse characters in the current line parseCurrentLine(line, isInPreprocessor, isInSQL); if (isInEventTable || isInDeclareSection) { if (line.length() == 0 || line[0] != '#') indentLine(line, 1); } if (shouldUnindentComment && sw.unindentDepth > 0) unindentLine(line, sw.unindentDepth - 1); else if (shouldUnindentLine && sw.unindentDepth > 0) unindentLine(line, sw.unindentDepth); }
/** * process the character at the current index in a switch block. * * @param line a reference to the line to indent. * @param index the current line index. * @return the new line index. */ size_t ASEnhancer::processSwitchBlock(string& line, size_t index) { size_t i = index; bool isPotentialKeyword = isCharPotentialHeader(line, i); if (line[i] == '{') { sw.switchBracketCount++; if (lookingForCaseBracket) // if 1st after case statement { sw.unindentCase = true; // unindenting this case sw.unindentDepth++; lookingForCaseBracket = false; // not looking now } return i; } lookingForCaseBracket = false; // no opening bracket, don't indent if (line[i] == '}') // if close bracket { sw.switchBracketCount--; assert(sw.switchBracketCount <= bracketCount); if (sw.switchBracketCount == 0) // if end of switch statement { int lineUnindent = sw.unindentDepth; if (line.find_first_not_of(" \t") == i && switchStack.size() > 0) lineUnindent = switchStack[switchStack.size()-1].unindentDepth; if (shouldIndentLine) { if (lineUnindent > 0) i -= unindentLine(line, lineUnindent); shouldIndentLine = false; } switchDepth--; sw = switchStack.back(); switchStack.pop_back(); } return i; } if (isPotentialKeyword && (findKeyword(line, i, "case") || findKeyword(line, i, "default"))) { if (sw.unindentCase) // if unindented last case { sw.unindentCase = false; // stop unindenting previous case sw.unindentDepth--; } i = findCaseColon(line, i); i++; for (; i < line.length(); i++) // bypass whitespace { if (!isWhiteSpace(line[i])) break; } if (i < line.length()) { if (line[i] == '{') { bracketCount++; sw.switchBracketCount++; if (!isOneLineBlockReached(line, i)) unindentNextLine = true; return i; } } lookingForCaseBracket = true; i--; // need to process this char return i; } if (isPotentialKeyword) { string name = getCurrentWord(line, i); // bypass the entire name i += name.length() - 1; } return i; }
/** * additional formatting for line of source code. * every line of source code in a source code file should be sent * one after the other to this function. * indents event tables * unindents the case blocks * * @param line the original formatted line will be updated if necessary. */ void ASEnhancer::enhance(string& line, bool isInPreprocessor, bool isInSQL) { bool isSpecialChar = false; // is a backslash escape character shouldIndentLine = true; lineNumber++; // check for beginning of event table if (nextLineIsEventIndent) { isInEventTable = true; nextLineIsEventIndent = false; } // check for beginning of SQL declare section if (nextLineIsDeclareIndent) { isInDeclareSection = true; nextLineIsDeclareIndent = false; } if (line.length() == 0 && ! isInEventTable && ! isInDeclareSection && ! emptyLineFill) return; // test for unindent on attached brackets if (unindentNextLine) { sw.unindentDepth++; sw.unindentCase = true; unindentNextLine = false; } // parse characters in the current line. for (size_t i = 0; i < line.length(); i++) { char ch = line[i]; // bypass whitespace if (isWhiteSpace(ch)) continue; // handle special characters (i.e. backslash+character such as \n, \t, ...) if (isSpecialChar) { isSpecialChar = false; continue; } if (!(isInComment) && line.compare(i, 2, "\\\\") == 0) { i++; continue; } if (!(isInComment) && ch == '\\') { isSpecialChar = true; continue; } // handle quotes (such as 'x' and "Hello Dolly") if (!isInComment && (ch == '"' || ch == '\'')) { if (!isInQuote) { quoteChar = ch; isInQuote = true; } else if (quoteChar == ch) { isInQuote = false; continue; } } if (isInQuote) continue; // handle comments if (!(isInComment) && line.compare(i, 2, "//") == 0) { // check for windows line markers if (line.compare(i + 2, 1, "\xf0") > 0) lineNumber--; break; // finished with the line } else if (!(isInComment) && line.compare(i, 2, "/*") == 0) { isInComment = true; i++; continue; } else if ((isInComment) && line.compare(i, 2, "*/") == 0) { isInComment = false; i++; continue; } if (isInComment) continue; // if we have reached this far then we are NOT in a comment or string of special characters if (line[i] == '{') bracketCount++; if (line[i] == '}') bracketCount--; bool isPotentialKeyword = isCharPotentialHeader(line, i); // ---------------- wxWidgets and MFC macros ---------------------------------- if (isPotentialKeyword) { if (findKeyword(line, i, "BEGIN_EVENT_TABLE") || findKeyword(line, i, "BEGIN_DISPATCH_MAP") || findKeyword(line, i, "BEGIN_EVENT_MAP") || findKeyword(line, i, "BEGIN_MESSAGE_MAP") || findKeyword(line, i, "BEGIN_PROPPAGEIDS")) { nextLineIsEventIndent = true; break; } if (findKeyword(line, i, "END_EVENT_TABLE") || findKeyword(line, i, "END_DISPATCH_MAP") || findKeyword(line, i, "END_EVENT_MAP") || findKeyword(line, i, "END_MESSAGE_MAP") || findKeyword(line, i, "END_PROPPAGEIDS")) { isInEventTable = false; break; } } // ---------------- process SQL ----------------------------------------------- if (isInSQL) { if (isBeginDeclareSectionSQL(line, i)) nextLineIsDeclareIndent = true; if (isEndDeclareSectionSQL(line, i)) isInDeclareSection = false; break; } // ---------------- process switch statements --------------------------------- if (isPotentialKeyword && findKeyword(line, i, "switch")) { switchDepth++; switchStack.push_back(sw); // save current variables sw.switchBracketCount = 0; sw.unindentCase = false; // don't clear case until end of switch i += 5; // bypass switch statement continue; } // just want unindented switch statements from this point if (caseIndent || switchDepth == 0 || (isInPreprocessor && !preprocessorIndent)) { // bypass the entire word if (isPotentialKeyword) { string name = getCurrentWord(line, i); i += name.length() - 1; } continue; } i = processSwitchBlock(line, i); } // end of for loop * end of for loop * end of for loop * end of for loop if (isInEventTable || isInDeclareSection) { if (line.length() == 0 || line[0] != '#') indentLine(line, 1); } if (shouldIndentLine && sw.unindentDepth > 0) unindentLine(line, sw.unindentDepth); }
/** * additional formatting for line of source code. * every line of source code in a source code file should be sent * one after the other to this function. * indents event tables * unindents the case blocks * * @param line the original formatted line will be updated if necessary. */ void ASEnhancer::enhance(string &line) { bool isSpecialChar = false; size_t lineLength; // length of the line being parsed lineNumber++; lineLength = line.length(); // check for beginning of event table if (nextLineIsEventTable) { isInEventTable = true; nextLineIsEventTable = false; } if (lineLength == 0 && ! isInEventTable && ! emptyLineFillX) return; // test for unindent on attached brackets if (unindentNextLine) { sw.unindentDepth++; sw.unindentCase = true; unindentNextLine = false; TRcase(" unindent case ", sw.unindentDepth); } // parse characters in the current line. for (size_t i = 0; i < lineLength; i++) { char ch = line[i]; // bypass whitespace if (isWhiteSpaceX(ch)) continue; // handle special characters (i.e. backslash+character such as \n, \t, ...) if (isSpecialChar) { isSpecialChar = false; continue; } if (!(isInComment) && line.compare(i, 2, "\\\\") == 0) { i++; continue; } if (!(isInComment) && ch == '\\') { isSpecialChar = true; continue; } // handle quotes (such as 'x' and "Hello Dolly") if (!(isInComment) && (ch == '"' || ch == '\'')) { if (!isInQuote) { quoteChar = ch; isInQuote = true; } else if (quoteChar == ch) { isInQuote = false; continue; } } if (isInQuote) continue; // handle comments if (!(isInComment) && line.compare(i, 2, "//") == 0) { // check for windows line markers if (line.compare(i + 2, 1, "\xf0") > 0) lineNumber--; break; // finished with the line } else if (!(isInComment) && line.compare(i, 2, "/*") == 0) { isInComment = true; i++; continue; } else if ((isInComment) && line.compare(i, 2, "*/") == 0) { isInComment = false; i++; continue; } if (isInComment) continue; // if we have reached this far then we are NOT in a comment or string of special characters if (line[i] == '{') // if open bracket bracketCount++; if (line[i] == '}') // if close bracket bracketCount--; // ---------------- process event tables -------------------------------------- // check for event table begin if (findKeyword(line, i, "BEGIN_EVENT_TABLE") || findKeyword(line, i, "BEGIN_MESSAGE_MAP")) nextLineIsEventTable = true; // check for event table end if (findKeyword(line, i, "END_EVENT_TABLE") || findKeyword(line, i, "END_MESSAGE_MAP")) isInEventTable = false; // ---------------- process switch statements --------------------------------- if (findKeyword(line, i, "switch")) // if switch statement { switchDepth++; // bump switch depth TRswitch(" switch ", switchDepth); swVector.push_back(sw); // save current variables sw.switchBracketCount = 0; sw.unindentCase = false; // don't clear case until end of switch i += 5; // bypass switch statement continue; } // just want switch statements from this point if (caseIndentX || switchDepth == 0) // from here just want switch statements continue; // get next char if (line[i] == '{') // if open bracket { sw.switchBracketCount++; if (lookingForCaseBracket) // if 1st after case statement { sw.unindentCase = true; // unindenting this case sw.unindentDepth++; // bump depth lookingForCaseBracket = false; // not looking now TRcase(" unindent case ", sw.unindentDepth); } continue; } lookingForCaseBracket = false; // no opening bracket, don't indent if (line[i] == '}') // if close bracket { sw.switchBracketCount--; if (sw.switchBracketCount == 0) // if end of switch statement { TRswitch(" endsw ", switchDepth); switchDepth--; // one less switch sw = swVector.back(); // restore sw struct swVector.pop_back(); // remove last entry from stack } continue; } // look for case or default header if (findKeyword(line, i, "case") || findKeyword(line, i, "default")) { if (sw.unindentCase) // if unindented last case { sw.unindentCase = false; // stop unindenting previous case sw.unindentDepth--; // reduce depth } bool isInQuote = false; char quoteChar = ' '; for (; i < lineLength; i++) // find colon { if (isInQuote) { if (line[i] == '\\') { i++; // bypass next char continue; } else if (line[i] == quoteChar) // check ending quote { isInQuote = false; quoteChar = ' '; continue; } else { continue; // must close quote before continuing } } if (line[i] == '\'' || line[i] == '\"') // check opening quote { isInQuote = true; quoteChar = line[i]; continue; } if (line[i] == ':') { if ((i + 1 < lineLength) && (line[i + 1] == ':')) i++; // bypass scope resolution operator else break; // found it } } i++; for (; i < lineLength; i++) // bypass whitespace { if (!(isWhiteSpaceX(line[i]))) break; } if (i < lineLength) // check for bracket { if (line[i] == '{') // if bracket found { sw.switchBracketCount++; unindentNextLine = true; // start unindenting on next line continue; } } lookingForCaseBracket = true; // bracket must be on next line i--; // need to check for comments continue; } } // end of for loop if (isInEventTable) // if need to indent indentLine(line, 1); // do it if (sw.unindentDepth > 0) // if need to unindent unindentLine(line, sw.unindentDepth); // do it }