void caseBranch (CaseItemPtr& caseItemHead, CaseItemPtr& caseItemTail, long& caseLabelCount, TypePtr expressionType) { //static CaseItemPtr oldCaseItemTail = NULL; CaseItemPtr oldCaseItemTail = caseItemTail; bool anotherLabel; do { TypePtr labelType = caseLabel(caseItemHead, caseItemTail, caseLabelCount); if (expressionType != labelType) syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES); getToken(); if (curToken == TKN_COMMA) { getToken(); if (tokenIn(CaseLabelStartList)) anotherLabel = true; else { syntaxError(ABL_ERR_SYNTAX_MISSING_CONSTANT); anotherLabel = false; } } else anotherLabel = false; } while (anotherLabel); //-------------- // Error sync... synchronize(FollowCaseLabelList, statementStartList, NULL); ifTokenGetElseError(TKN_COLON, ABL_ERR_SYNTAX_MISSING_COLON); //----------------------------------------------------------------- // Fill in the branch location for each CaseItem for this branch... CaseItemPtr caseItem = (!oldCaseItemTail ? caseItemHead : oldCaseItemTail->next); //oldCaseItemTail = CaseItemTail; while (caseItem) { caseItem->branchLocation = codeBufferPtr; caseItem = caseItem->next; } if (curToken != TKN_END_CASE) do { statement(); while (curToken == TKN_SEMICOLON) getToken(); if (curToken == TKN_END_CASE) break; } while (tokenIn(statementStartList)); ifTokenGetElseError(TKN_END_CASE, ABL_ERR_SYNTAX_MISSING_END_CASE); ifTokenGetElseError(TKN_SEMICOLON, ABL_ERR_SYNTAX_MISSING_SEMICOLON); }
/* Returns the recommended indent for the bottom line of program. Unless null, typedIn stores the character of yyProgram that triggered reindentation. This function works better if typedIn is set properly; it is slightly more conservative if typedIn is completely wild, and slighly more liberal if typedIn is always null. The user might be annoyed by the liberal behavior. */ int indentForBottomLine( const QStringList& program, QChar typedIn ) { if ( program.isEmpty() ) return 0; initializeIndenter(); yyProgram = new QStringList( program ); startLinizer(); const QString& bottomLine = program.last(); QChar firstCh = firstNonWhiteSpace( bottomLine ); int indent; if ( bottomLineStartsInCComment() ) { /* The bottom line starts in a C-style comment. Indent it smartly, unless the user has already played around with it, in which case it's better to leave her stuff alone. */ if ( isOnlyWhiteSpace(bottomLine) ) { indent = indentWhenBottomLineStartsInCComment(); } else { indent = indentOfLine( bottomLine ); } } else if ( okay(typedIn, '#') && firstCh == QChar('#') ) { /* Preprocessor directives go flush left. */ indent = 0; } else { if ( isUnfinishedLine() ) { indent = indentForContinuationLine(); } else { indent = indentForStandaloneLine(); } if ( okay(typedIn, '}') && firstCh == QChar('}') ) { /* A closing brace is one level more to the left than the code it follows. */ indent -= ppIndentSize; } else if ( okay(typedIn, ':') ) { QRegExp caseLabel( "\\s*(?:case\\b(?:[^:]|::)+" "|(?:public|protected|private|signals|default)(?:\\s+slots)?\\s*" ")?:.*" ); if ( caseLabel.exactMatch(bottomLine) ) { /* Move a case label (or the ':' in front of a constructor initialization list) one level to the left, but only if the user did not play around with it yet. Some users have exotic tastes in the matter, and most users probably are not patient enough to wait for the final ':' to format their code properly. We don't attempt the same for goto labels, as the user is probably the middle of "foo::bar". (Who uses goto, anyway?) */ if ( indentOfLine(bottomLine) <= indent ) indent -= ppIndentSize; else indent = indentOfLine( bottomLine ); } } } delete yyProgram; terminateIndenter(); return qMax( 0, indent ); }