123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660 |
- // ASBeautifier.cpp
- // Copyright (c) 2017 by Jim Pattee <jimp03@email.com>.
- // This code is licensed under the MIT License.
- // License.md describes the conditions under which this software may be distributed.
- //-----------------------------------------------------------------------------
- // headers
- //-----------------------------------------------------------------------------
- #include "astyle.h"
- #include <algorithm>
- //-----------------------------------------------------------------------------
- // astyle namespace
- //-----------------------------------------------------------------------------
- namespace astyle {
- //
- // this must be global
- static int g_preprocessorCppExternCBrace;
- //-----------------------------------------------------------------------------
- // ASBeautifier class
- //-----------------------------------------------------------------------------
- /**
- * ASBeautifier's constructor
- * This constructor is called only once for each source file.
- * The cloned ASBeautifier objects are created with the copy constructor.
- */
- ASBeautifier::ASBeautifier()
- {
- waitingBeautifierStack = nullptr;
- activeBeautifierStack = nullptr;
- waitingBeautifierStackLengthStack = nullptr;
- activeBeautifierStackLengthStack = nullptr;
- headerStack = nullptr;
- tempStacks = nullptr;
- squareBracketDepthStack = nullptr;
- blockStatementStack = nullptr;
- parenStatementStack = nullptr;
- braceBlockStateStack = nullptr;
- continuationIndentStack = nullptr;
- continuationIndentStackSizeStack = nullptr;
- parenIndentStack = nullptr;
- preprocIndentStack = nullptr;
- sourceIterator = nullptr;
- isModeManuallySet = false;
- shouldForceTabIndentation = false;
- setSpaceIndentation(4);
- setContinuationIndentation(1);
- setMinConditionalIndentOption(MINCOND_TWO);
- setMaxContinuationIndentLength(40);
- classInitializerIndents = 1;
- tabLength = 0;
- setClassIndent(false);
- setModifierIndent(false);
- setSwitchIndent(false);
- setCaseIndent(false);
- setBlockIndent(false);
- setBraceIndent(false);
- setBraceIndentVtk(false);
- setNamespaceIndent(false);
- setAfterParenIndent(false);
- setLabelIndent(false);
- setEmptyLineFill(false);
- setCStyle();
- setPreprocDefineIndent(false);
- setPreprocConditionalIndent(false);
- setAlignMethodColon(false);
- // initialize ASBeautifier member vectors
- beautifierFileType = 9; // reset to an invalid type
- headers = new vector<const string*>;
- nonParenHeaders = new vector<const string*>;
- assignmentOperators = new vector<const string*>;
- nonAssignmentOperators = new vector<const string*>;
- preBlockStatements = new vector<const string*>;
- preCommandHeaders = new vector<const string*>;
- indentableHeaders = new vector<const string*>;
- }
- /**
- * ASBeautifier's copy constructor
- * Copy the vector objects to vectors in the new ASBeautifier
- * object so the new object can be destroyed without deleting
- * the vector objects in the copied vector.
- * This is the reason a copy constructor is needed.
- *
- * Must explicitly call the base class copy constructor.
- */
- ASBeautifier::ASBeautifier(const ASBeautifier& other) : ASBase(other)
- {
- // these don't need to copy the stack
- waitingBeautifierStack = nullptr;
- activeBeautifierStack = nullptr;
- waitingBeautifierStackLengthStack = nullptr;
- activeBeautifierStackLengthStack = nullptr;
- // vector '=' operator performs a DEEP copy of all elements in the vector
- headerStack = new vector<const string*>;
- *headerStack = *other.headerStack;
- tempStacks = copyTempStacks(other);
- squareBracketDepthStack = new vector<int>;
- *squareBracketDepthStack = *other.squareBracketDepthStack;
- blockStatementStack = new vector<bool>;
- *blockStatementStack = *other.blockStatementStack;
- parenStatementStack = new vector<bool>;
- *parenStatementStack = *other.parenStatementStack;
- braceBlockStateStack = new vector<bool>;
- *braceBlockStateStack = *other.braceBlockStateStack;
- continuationIndentStack = new vector<int>;
- *continuationIndentStack = *other.continuationIndentStack;
- continuationIndentStackSizeStack = new vector<int>;
- *continuationIndentStackSizeStack = *other.continuationIndentStackSizeStack;
- parenIndentStack = new vector<int>;
- *parenIndentStack = *other.parenIndentStack;
- preprocIndentStack = new vector<pair<int, int> >;
- *preprocIndentStack = *other.preprocIndentStack;
- // Copy the pointers to vectors.
- // This is ok because the original ASBeautifier object
- // is not deleted until end of job.
- beautifierFileType = other.beautifierFileType;
- headers = other.headers;
- nonParenHeaders = other.nonParenHeaders;
- assignmentOperators = other.assignmentOperators;
- nonAssignmentOperators = other.nonAssignmentOperators;
- preBlockStatements = other.preBlockStatements;
- preCommandHeaders = other.preCommandHeaders;
- indentableHeaders = other.indentableHeaders;
- // protected variables
- // variables set by ASFormatter
- // must also be updated in activeBeautifierStack
- inLineNumber = other.inLineNumber;
- runInIndentContinuation = other.runInIndentContinuation;
- nonInStatementBrace = other.nonInStatementBrace;
- objCColonAlignSubsequent = other.objCColonAlignSubsequent;
- lineCommentNoBeautify = other.lineCommentNoBeautify;
- isElseHeaderIndent = other.isElseHeaderIndent;
- isCaseHeaderCommentIndent = other.isCaseHeaderCommentIndent;
- isNonInStatementArray = other.isNonInStatementArray;
- isSharpAccessor = other.isSharpAccessor;
- isSharpDelegate = other.isSharpDelegate;
- isInExternC = other.isInExternC;
- isInBeautifySQL = other.isInBeautifySQL;
- isInIndentableStruct = other.isInIndentableStruct;
- isInIndentablePreproc = other.isInIndentablePreproc;
- // private variables
- sourceIterator = other.sourceIterator;
- currentHeader = other.currentHeader;
- previousLastLineHeader = other.previousLastLineHeader;
- probationHeader = other.probationHeader;
- lastLineHeader = other.lastLineHeader;
- indentString = other.indentString;
- verbatimDelimiter = other.verbatimDelimiter;
- isInQuote = other.isInQuote;
- isInVerbatimQuote = other.isInVerbatimQuote;
- haveLineContinuationChar = other.haveLineContinuationChar;
- isInAsm = other.isInAsm;
- isInAsmOneLine = other.isInAsmOneLine;
- isInAsmBlock = other.isInAsmBlock;
- isInComment = other.isInComment;
- isInPreprocessorComment = other.isInPreprocessorComment;
- isInRunInComment = other.isInRunInComment;
- isInCase = other.isInCase;
- isInQuestion = other.isInQuestion;
- isContinuation = other.isContinuation;
- isInHeader = other.isInHeader;
- isInTemplate = other.isInTemplate;
- isInDefine = other.isInDefine;
- isInDefineDefinition = other.isInDefineDefinition;
- classIndent = other.classIndent;
- isIndentModeOff = other.isIndentModeOff;
- isInClassHeader = other.isInClassHeader;
- isInClassHeaderTab = other.isInClassHeaderTab;
- isInClassInitializer = other.isInClassInitializer;
- isInClass = other.isInClass;
- isInObjCMethodDefinition = other.isInObjCMethodDefinition;
- isInObjCMethodCall = other.isInObjCMethodCall;
- isInObjCMethodCallFirst = other.isInObjCMethodCallFirst;
- isImmediatelyPostObjCMethodDefinition = other.isImmediatelyPostObjCMethodDefinition;
- isImmediatelyPostObjCMethodCall = other.isImmediatelyPostObjCMethodCall;
- isInIndentablePreprocBlock = other.isInIndentablePreprocBlock;
- isInObjCInterface = other.isInObjCInterface;
- isInEnum = other.isInEnum;
- isInEnumTypeID = other.isInEnumTypeID;
- isInLet = other.isInLet;
- modifierIndent = other.modifierIndent;
- switchIndent = other.switchIndent;
- caseIndent = other.caseIndent;
- namespaceIndent = other.namespaceIndent;
- braceIndent = other.braceIndent;
- braceIndentVtk = other.braceIndentVtk;
- blockIndent = other.blockIndent;
- shouldIndentAfterParen = other.shouldIndentAfterParen;
- labelIndent = other.labelIndent;
- isInConditional = other.isInConditional;
- isModeManuallySet = other.isModeManuallySet;
- shouldForceTabIndentation = other.shouldForceTabIndentation;
- emptyLineFill = other.emptyLineFill;
- lineOpensWithLineComment = other.lineOpensWithLineComment;
- lineOpensWithComment = other.lineOpensWithComment;
- lineStartsInComment = other.lineStartsInComment;
- backslashEndsPrevLine = other.backslashEndsPrevLine;
- blockCommentNoIndent = other.blockCommentNoIndent;
- blockCommentNoBeautify = other.blockCommentNoBeautify;
- previousLineProbationTab = other.previousLineProbationTab;
- lineBeginsWithOpenBrace = other.lineBeginsWithOpenBrace;
- lineBeginsWithCloseBrace = other.lineBeginsWithCloseBrace;
- lineBeginsWithComma = other.lineBeginsWithComma;
- lineIsCommentOnly = other.lineIsCommentOnly;
- lineIsLineCommentOnly = other.lineIsLineCommentOnly;
- shouldIndentBracedLine = other.shouldIndentBracedLine;
- isInSwitch = other.isInSwitch;
- foundPreCommandHeader = other.foundPreCommandHeader;
- foundPreCommandMacro = other.foundPreCommandMacro;
- shouldAlignMethodColon = other.shouldAlignMethodColon;
- shouldIndentPreprocDefine = other.shouldIndentPreprocDefine;
- shouldIndentPreprocConditional = other.shouldIndentPreprocConditional;
- indentCount = other.indentCount;
- spaceIndentCount = other.spaceIndentCount;
- spaceIndentObjCMethodAlignment = other.spaceIndentObjCMethodAlignment;
- bracePosObjCMethodAlignment = other.bracePosObjCMethodAlignment;
- colonIndentObjCMethodAlignment = other.colonIndentObjCMethodAlignment;
- lineOpeningBlocksNum = other.lineOpeningBlocksNum;
- lineClosingBlocksNum = other.lineClosingBlocksNum;
- fileType = other.fileType;
- minConditionalOption = other.minConditionalOption;
- minConditionalIndent = other.minConditionalIndent;
- parenDepth = other.parenDepth;
- indentLength = other.indentLength;
- tabLength = other.tabLength;
- continuationIndent = other.continuationIndent;
- blockTabCount = other.blockTabCount;
- maxContinuationIndent = other.maxContinuationIndent;
- classInitializerIndents = other.classInitializerIndents;
- templateDepth = other.templateDepth;
- squareBracketCount = other.squareBracketCount;
- prevFinalLineSpaceIndentCount = other.prevFinalLineSpaceIndentCount;
- prevFinalLineIndentCount = other.prevFinalLineIndentCount;
- defineIndentCount = other.defineIndentCount;
- preprocBlockIndent = other.preprocBlockIndent;
- quoteChar = other.quoteChar;
- prevNonSpaceCh = other.prevNonSpaceCh;
- currentNonSpaceCh = other.currentNonSpaceCh;
- currentNonLegalCh = other.currentNonLegalCh;
- prevNonLegalCh = other.prevNonLegalCh;
- }
- /**
- * ASBeautifier's destructor
- */
- ASBeautifier::~ASBeautifier()
- {
- deleteBeautifierContainer(waitingBeautifierStack);
- deleteBeautifierContainer(activeBeautifierStack);
- deleteContainer(waitingBeautifierStackLengthStack);
- deleteContainer(activeBeautifierStackLengthStack);
- deleteContainer(headerStack);
- deleteTempStacksContainer(tempStacks);
- deleteContainer(squareBracketDepthStack);
- deleteContainer(blockStatementStack);
- deleteContainer(parenStatementStack);
- deleteContainer(braceBlockStateStack);
- deleteContainer(continuationIndentStack);
- deleteContainer(continuationIndentStackSizeStack);
- deleteContainer(parenIndentStack);
- deleteContainer(preprocIndentStack);
- }
- /**
- * initialize the ASBeautifier.
- *
- * This init() should be called every time a ABeautifier object is to start
- * beautifying a NEW source file.
- * It is called only when a new ASFormatter object is created.
- * init() receives a pointer to a ASSourceIterator object that will be
- * used to iterate through the source code.
- *
- * @param iter a pointer to the ASSourceIterator or ASStreamIterator object.
- */
- void ASBeautifier::init(ASSourceIterator* iter)
- {
- sourceIterator = iter;
- initVectors();
- ASBase::init(getFileType());
- g_preprocessorCppExternCBrace = 0;
- initContainer(waitingBeautifierStack, new vector<ASBeautifier*>);
- initContainer(activeBeautifierStack, new vector<ASBeautifier*>);
- initContainer(waitingBeautifierStackLengthStack, new vector<int>);
- initContainer(activeBeautifierStackLengthStack, new vector<int>);
- initContainer(headerStack, new vector<const string*>);
- initTempStacksContainer(tempStacks, new vector<vector<const string*>*>);
- tempStacks->emplace_back(new vector<const string*>);
- initContainer(squareBracketDepthStack, new vector<int>);
- initContainer(blockStatementStack, new vector<bool>);
- initContainer(parenStatementStack, new vector<bool>);
- initContainer(braceBlockStateStack, new vector<bool>);
- braceBlockStateStack->push_back(true);
- initContainer(continuationIndentStack, new vector<int>);
- initContainer(continuationIndentStackSizeStack, new vector<int>);
- continuationIndentStackSizeStack->emplace_back(0);
- initContainer(parenIndentStack, new vector<int>);
- initContainer(preprocIndentStack, new vector<pair<int, int> >);
- previousLastLineHeader = nullptr;
- currentHeader = nullptr;
- isInQuote = false;
- isInVerbatimQuote = false;
- haveLineContinuationChar = false;
- isInAsm = false;
- isInAsmOneLine = false;
- isInAsmBlock = false;
- isInComment = false;
- isInPreprocessorComment = false;
- isInRunInComment = false;
- isContinuation = false;
- isInCase = false;
- isInQuestion = false;
- isIndentModeOff = false;
- isInClassHeader = false;
- isInClassHeaderTab = false;
- isInClassInitializer = false;
- isInClass = false;
- isInObjCMethodDefinition = false;
- isInObjCMethodCall = false;
- isInObjCMethodCallFirst = false;
- isImmediatelyPostObjCMethodDefinition = false;
- isImmediatelyPostObjCMethodCall = false;
- isInIndentablePreprocBlock = false;
- isInObjCInterface = false;
- isInEnum = false;
- isInEnumTypeID = false;
- isInLet = false;
- isInHeader = false;
- isInTemplate = false;
- isInConditional = false;
- indentCount = 0;
- spaceIndentCount = 0;
- spaceIndentObjCMethodAlignment = 0;
- bracePosObjCMethodAlignment = 0;
- colonIndentObjCMethodAlignment = 0;
- lineOpeningBlocksNum = 0;
- lineClosingBlocksNum = 0;
- templateDepth = 0;
- squareBracketCount = 0;
- parenDepth = 0;
- blockTabCount = 0;
- prevFinalLineSpaceIndentCount = 0;
- prevFinalLineIndentCount = 0;
- defineIndentCount = 0;
- preprocBlockIndent = 0;
- prevNonSpaceCh = '{';
- currentNonSpaceCh = '{';
- prevNonLegalCh = '{';
- currentNonLegalCh = '{';
- quoteChar = ' ';
- probationHeader = nullptr;
- lastLineHeader = nullptr;
- backslashEndsPrevLine = false;
- lineOpensWithLineComment = false;
- lineOpensWithComment = false;
- lineStartsInComment = false;
- isInDefine = false;
- isInDefineDefinition = false;
- lineCommentNoBeautify = false;
- isElseHeaderIndent = false;
- isCaseHeaderCommentIndent = false;
- blockCommentNoIndent = false;
- blockCommentNoBeautify = false;
- previousLineProbationTab = false;
- lineBeginsWithOpenBrace = false;
- lineBeginsWithCloseBrace = false;
- lineBeginsWithComma = false;
- lineIsCommentOnly = false;
- lineIsLineCommentOnly = false;
- shouldIndentBracedLine = true;
- isInSwitch = false;
- foundPreCommandHeader = false;
- foundPreCommandMacro = false;
- isNonInStatementArray = false;
- isSharpAccessor = false;
- isSharpDelegate = false;
- isInExternC = false;
- isInBeautifySQL = false;
- isInIndentableStruct = false;
- isInIndentablePreproc = false;
- inLineNumber = 0;
- runInIndentContinuation = 0;
- nonInStatementBrace = 0;
- objCColonAlignSubsequent = 0;
- }
- /*
- * initialize the vectors
- */
- void ASBeautifier::initVectors()
- {
- if (fileType == beautifierFileType) // don't build unless necessary
- return;
- beautifierFileType = fileType;
- headers->clear();
- nonParenHeaders->clear();
- assignmentOperators->clear();
- nonAssignmentOperators->clear();
- preBlockStatements->clear();
- preCommandHeaders->clear();
- indentableHeaders->clear();
- ASResource::buildHeaders(headers, fileType, true);
- ASResource::buildNonParenHeaders(nonParenHeaders, fileType, true);
- ASResource::buildAssignmentOperators(assignmentOperators);
- ASResource::buildNonAssignmentOperators(nonAssignmentOperators);
- ASResource::buildPreBlockStatements(preBlockStatements, fileType);
- ASResource::buildPreCommandHeaders(preCommandHeaders, fileType);
- ASResource::buildIndentableHeaders(indentableHeaders);
- }
- /**
- * set indentation style to C/C++.
- */
- void ASBeautifier::setCStyle()
- {
- fileType = C_TYPE;
- }
- /**
- * set indentation style to Java.
- */
- void ASBeautifier::setJavaStyle()
- {
- fileType = JAVA_TYPE;
- }
- /**
- * set indentation style to C#.
- */
- void ASBeautifier::setSharpStyle()
- {
- fileType = SHARP_TYPE;
- }
- /**
- * set mode manually set flag
- */
- void ASBeautifier::setModeManuallySet(bool state)
- {
- isModeManuallySet = state;
- }
- /**
- * set tabLength equal to indentLength.
- * This is done when tabLength is not explicitly set by
- * "indent=force-tab-x"
- *
- */
- void ASBeautifier::setDefaultTabLength()
- {
- tabLength = indentLength;
- }
- /**
- * indent using a different tab setting for indent=force-tab
- *
- * @param length number of spaces per tab.
- */
- void ASBeautifier::setForceTabXIndentation(int length)
- {
- // set tabLength instead of indentLength
- indentString = "\t";
- tabLength = length;
- shouldForceTabIndentation = true;
- }
- /**
- * indent using one tab per indentation
- */
- void ASBeautifier::setTabIndentation(int length, bool forceTabs)
- {
- indentString = "\t";
- indentLength = length;
- shouldForceTabIndentation = forceTabs;
- }
- /**
- * indent using a number of spaces per indentation.
- *
- * @param length number of spaces per indent.
- */
- void ASBeautifier::setSpaceIndentation(int length)
- {
- indentString = string(length, ' ');
- indentLength = length;
- }
- /**
- * indent continuation lines using a number of indents.
- *
- * @param indent number of indents per line.
- */
- void ASBeautifier::setContinuationIndentation(int indent)
- {
- continuationIndent = indent;
- }
- /**
- * set the maximum indentation between two lines in a multi-line statement.
- *
- * @param max maximum indentation length.
- */
- void ASBeautifier::setMaxContinuationIndentLength(int max)
- {
- maxContinuationIndent = max;
- }
- // retained for compatability with release 2.06
- // "MaxInStatementIndent" has been changed to "MaxContinuationIndent" in 3.0
- // it is referenced only by the old "MaxInStatementIndent" options
- void ASBeautifier::setMaxInStatementIndentLength(int max)
- {
- setMaxContinuationIndentLength(max);
- }
- /**
- * set the minimum conditional indentation option.
- *
- * @param min minimal indentation option.
- */
- void ASBeautifier::setMinConditionalIndentOption(int min)
- {
- minConditionalOption = min;
- }
- /**
- * set minConditionalIndent from the minConditionalOption.
- */
- void ASBeautifier::setMinConditionalIndentLength()
- {
- if (minConditionalOption == MINCOND_ZERO)
- minConditionalIndent = 0;
- else if (minConditionalOption == MINCOND_ONE)
- minConditionalIndent = indentLength;
- else if (minConditionalOption == MINCOND_ONEHALF)
- minConditionalIndent = indentLength / 2;
- // minConditionalOption = INDENT_TWO
- else
- minConditionalIndent = indentLength * 2;
- }
- /**
- * set the state of the brace indent option. If true, braces will
- * be indented one additional indent.
- *
- * @param state state of option.
- */
- void ASBeautifier::setBraceIndent(bool state)
- {
- braceIndent = state;
- }
- /**
- * set the state of the brace indent VTK option. If true, braces will
- * be indented one additional indent, except for the opening brace.
- *
- * @param state state of option.
- */
- void ASBeautifier::setBraceIndentVtk(bool state)
- {
- // need to set both of these
- setBraceIndent(state);
- braceIndentVtk = state;
- }
- /**
- * set the state of the block indentation option. If true, entire blocks
- * will be indented one additional indent, similar to the GNU indent style.
- *
- * @param state state of option.
- */
- void ASBeautifier::setBlockIndent(bool state)
- {
- blockIndent = state;
- }
- /**
- * set the state of the class indentation option. If true, C++ class
- * definitions will be indented one additional indent.
- *
- * @param state state of option.
- */
- void ASBeautifier::setClassIndent(bool state)
- {
- classIndent = state;
- }
- /**
- * set the state of the modifier indentation option. If true, C++ class
- * access modifiers will be indented one-half an indent.
- *
- * @param state state of option.
- */
- void ASBeautifier::setModifierIndent(bool state)
- {
- modifierIndent = state;
- }
- /**
- * set the state of the switch indentation option. If true, blocks of 'switch'
- * statements will be indented one additional indent.
- *
- * @param state state of option.
- */
- void ASBeautifier::setSwitchIndent(bool state)
- {
- switchIndent = state;
- }
- /**
- * set the state of the case indentation option. If true, lines of 'case'
- * statements will be indented one additional indent.
- *
- * @param state state of option.
- */
- void ASBeautifier::setCaseIndent(bool state)
- {
- caseIndent = state;
- }
- /**
- * set the state of the namespace indentation option.
- * If true, blocks of 'namespace' statements will be indented one
- * additional indent. Otherwise, NO indentation will be added.
- *
- * @param state state of option.
- */
- void ASBeautifier::setNamespaceIndent(bool state)
- {
- namespaceIndent = state;
- }
- /**
- * set the state of the indent after parens option.
- *
- * @param state state of option.
- */
- void ASBeautifier::setAfterParenIndent(bool state)
- {
- shouldIndentAfterParen = state;
- }
- /**
- * set the state of the label indentation option.
- * If true, labels will be indented one indent LESS than the
- * current indentation level.
- * If false, labels will be flushed to the left with NO
- * indent at all.
- *
- * @param state state of option.
- */
- void ASBeautifier::setLabelIndent(bool state)
- {
- labelIndent = state;
- }
- /**
- * set the state of the preprocessor indentation option.
- * If true, multi-line #define statements will be indented.
- *
- * @param state state of option.
- */
- void ASBeautifier::setPreprocDefineIndent(bool state)
- {
- shouldIndentPreprocDefine = state;
- }
- void ASBeautifier::setPreprocConditionalIndent(bool state)
- {
- shouldIndentPreprocConditional = state;
- }
- /**
- * set the state of the empty line fill option.
- * If true, empty lines will be filled with the whitespace.
- * of their previous lines.
- * If false, these lines will remain empty.
- *
- * @param state state of option.
- */
- void ASBeautifier::setEmptyLineFill(bool state)
- {
- emptyLineFill = state;
- }
- void ASBeautifier::setAlignMethodColon(bool state)
- {
- shouldAlignMethodColon = state;
- }
- /**
- * get the file type.
- */
- int ASBeautifier::getFileType() const
- {
- return fileType;
- }
- /**
- * get the number of spaces per indent
- *
- * @return value of indentLength option.
- */
- int ASBeautifier::getIndentLength() const
- {
- return indentLength;
- }
- /**
- * get the char used for indentation, space or tab
- *
- * @return the char used for indentation.
- */
- string ASBeautifier::getIndentString() const
- {
- return indentString;
- }
- /**
- * get mode manually set flag
- */
- bool ASBeautifier::getModeManuallySet() const
- {
- return isModeManuallySet;
- }
- /**
- * get the state of the force tab indentation option.
- *
- * @return state of force tab indentation.
- */
- bool ASBeautifier::getForceTabIndentation() const
- {
- return shouldForceTabIndentation;
- }
- /**
- * Get the state of the Objective-C align method colon option.
- *
- * @return state of shouldAlignMethodColon option.
- */
- bool ASBeautifier::getAlignMethodColon() const
- {
- return shouldAlignMethodColon;
- }
- /**
- * get the state of the block indentation option.
- *
- * @return state of blockIndent option.
- */
- bool ASBeautifier::getBlockIndent() const
- {
- return blockIndent;
- }
- /**
- * get the state of the brace indentation option.
- *
- * @return state of braceIndent option.
- */
- bool ASBeautifier::getBraceIndent() const
- {
- return braceIndent;
- }
- /**
- * Get the state of the namespace indentation option. If true, blocks
- * of the 'namespace' statement will be indented one additional indent.
- *
- * @return state of namespaceIndent option.
- */
- bool ASBeautifier::getNamespaceIndent() const
- {
- return namespaceIndent;
- }
- /**
- * Get the state of the class indentation option. If true, blocks of
- * the 'class' statement will be indented one additional indent.
- *
- * @return state of classIndent option.
- */
- bool ASBeautifier::getClassIndent() const
- {
- return classIndent;
- }
- /**
- * Get the state of the class access modifier indentation option.
- * If true, the class access modifiers will be indented one-half indent.
- *
- * @return state of modifierIndent option.
- */
- bool ASBeautifier::getModifierIndent() const
- {
- return modifierIndent;
- }
- /**
- * get the state of the switch indentation option. If true, blocks of
- * the 'switch' statement will be indented one additional indent.
- *
- * @return state of switchIndent option.
- */
- bool ASBeautifier::getSwitchIndent() const
- {
- return switchIndent;
- }
- /**
- * get the state of the case indentation option. If true, lines of 'case'
- * statements will be indented one additional indent.
- *
- * @return state of caseIndent option.
- */
- bool ASBeautifier::getCaseIndent() const
- {
- return caseIndent;
- }
- /**
- * get the state of the empty line fill option.
- * If true, empty lines will be filled with the whitespace.
- * of their previous lines.
- * If false, these lines will remain empty.
- *
- * @return state of emptyLineFill option.
- */
- bool ASBeautifier::getEmptyLineFill() const
- {
- return emptyLineFill;
- }
- /**
- * get the state of the preprocessor indentation option.
- * If true, preprocessor "define" lines will be indented.
- * If false, preprocessor "define" lines will be unchanged.
- *
- * @return state of shouldIndentPreprocDefine option.
- */
- bool ASBeautifier::getPreprocDefineIndent() const
- {
- return shouldIndentPreprocDefine;
- }
- /**
- * get the length of the tab indentation option.
- *
- * @return length of tab indent option.
- */
- int ASBeautifier::getTabLength() const
- {
- return tabLength;
- }
- /**
- * beautify a line of source code.
- * every line of source code in a source code file should be sent
- * one after the other to the beautify method.
- *
- * @return the indented line.
- * @param originalLine the original unindented line.
- */
- string ASBeautifier::beautify(const string& originalLine)
- {
- string line;
- bool isInQuoteContinuation = isInVerbatimQuote || haveLineContinuationChar;
- currentHeader = nullptr;
- lastLineHeader = nullptr;
- blockCommentNoBeautify = blockCommentNoIndent;
- isInClass = false;
- isInSwitch = false;
- lineBeginsWithOpenBrace = false;
- lineBeginsWithCloseBrace = false;
- lineBeginsWithComma = false;
- lineIsCommentOnly = false;
- lineIsLineCommentOnly = false;
- shouldIndentBracedLine = true;
- isInAsmOneLine = false;
- lineOpensWithLineComment = false;
- lineOpensWithComment = false;
- lineStartsInComment = isInComment;
- previousLineProbationTab = false;
- lineOpeningBlocksNum = 0;
- lineClosingBlocksNum = 0;
- if (isImmediatelyPostObjCMethodDefinition)
- clearObjCMethodDefinitionAlignment();
- if (isImmediatelyPostObjCMethodCall)
- {
- isImmediatelyPostObjCMethodCall = false;
- isInObjCMethodCall = false;
- objCColonAlignSubsequent = 0;
- }
- // handle and remove white spaces around the line:
- // If not in comment, first find out size of white space before line,
- // so that possible comments starting in the line continue in
- // relation to the preliminary white-space.
- if (isInQuoteContinuation)
- {
- // trim a single space added by ASFormatter, otherwise leave it alone
- if (!(originalLine.length() == 1 && originalLine[0] == ' '))
- line = originalLine;
- }
- else if (isInComment || isInBeautifySQL)
- {
- // trim the end of comment and SQL lines
- line = originalLine;
- size_t trimEnd = line.find_last_not_of(" \t");
- if (trimEnd == string::npos)
- trimEnd = 0;
- else
- trimEnd++;
- if (trimEnd < line.length())
- line.erase(trimEnd);
- // does a brace open the line
- size_t firstChar = line.find_first_not_of(" \t");
- if (firstChar != string::npos)
- {
- if (line[firstChar] == '{')
- lineBeginsWithOpenBrace = true;
- else if (line[firstChar] == '}')
- lineBeginsWithCloseBrace = true;
- else if (line[firstChar] == ',')
- lineBeginsWithComma = true;
- }
- }
- else
- {
- line = trim(originalLine);
- if (line.length() > 0)
- {
- if (line[0] == '{')
- lineBeginsWithOpenBrace = true;
- else if (line[0] == '}')
- lineBeginsWithCloseBrace = true;
- else if (line[0] == ',')
- lineBeginsWithComma = true;
- else if (line.compare(0, 2, "//") == 0)
- lineIsLineCommentOnly = true;
- else if (line.compare(0, 2, "/*") == 0)
- {
- if (line.find("*/", 2) != string::npos)
- lineIsCommentOnly = true;
- }
- }
- isInRunInComment = false;
- size_t j = line.find_first_not_of(" \t{");
- if (j != string::npos && line.compare(j, 2, "//") == 0)
- lineOpensWithLineComment = true;
- if (j != string::npos && line.compare(j, 2, "/*") == 0)
- {
- lineOpensWithComment = true;
- size_t k = line.find_first_not_of(" \t");
- if (k != string::npos && line.compare(k, 1, "{") == 0)
- isInRunInComment = true;
- }
- }
- // When indent is OFF the lines must still be processed by ASBeautifier.
- // Otherwise the lines immediately following may not be indented correctly.
- if ((lineIsLineCommentOnly || lineIsCommentOnly)
- && line.find("*INDENT-OFF*", 0) != string::npos)
- isIndentModeOff = true;
- if (line.length() == 0)
- {
- if (backslashEndsPrevLine)
- {
- backslashEndsPrevLine = false;
- // check if this line ends a multi-line #define
- // if so, remove the #define's cloned beautifier from the active
- // beautifier stack and delete it.
- if (isInDefineDefinition && !isInDefine)
- {
- isInDefineDefinition = false;
- ASBeautifier* defineBeautifier = activeBeautifierStack->back();
- activeBeautifierStack->pop_back();
- delete defineBeautifier;
- }
- }
- if (emptyLineFill && !isInQuoteContinuation)
- {
- if (isInIndentablePreprocBlock)
- return preLineWS(preprocBlockIndent, 0);
- if (!headerStack->empty() || isInEnum)
- return preLineWS(prevFinalLineIndentCount, prevFinalLineSpaceIndentCount);
- // must fall thru here
- }
- else
- return line;
- }
- // handle preprocessor commands
- if (isInIndentablePreprocBlock
- && line.length() > 0
- && line[0] != '#')
- {
- string indentedLine;
- if (isInClassHeaderTab || isInClassInitializer)
- {
- // parsing is turned off in ASFormatter by indent-off
- // the originalLine will probably never be returned here
- indentedLine = preLineWS(prevFinalLineIndentCount, prevFinalLineSpaceIndentCount) + line;
- return getIndentedLineReturn(indentedLine, originalLine);
- }
- indentedLine = preLineWS(preprocBlockIndent, 0) + line;
- return getIndentedLineReturn(indentedLine, originalLine);
- }
- if (!isInComment
- && !isInQuoteContinuation
- && line.length() > 0
- && ((line[0] == '#' && !isIndentedPreprocessor(line, 0))
- || backslashEndsPrevLine))
- {
- if (line[0] == '#' && !isInDefine)
- {
- string preproc = extractPreprocessorStatement(line);
- processPreprocessor(preproc, line);
- if (isInIndentablePreprocBlock || isInIndentablePreproc)
- {
- string indentedLine;
- if ((preproc.length() >= 2 && preproc.substr(0, 2) == "if")) // #if, #ifdef, #ifndef
- {
- indentedLine = preLineWS(preprocBlockIndent, 0) + line;
- preprocBlockIndent += 1;
- isInIndentablePreprocBlock = true;
- }
- else if (preproc == "else" || preproc == "elif")
- {
- indentedLine = preLineWS(preprocBlockIndent - 1, 0) + line;
- }
- else if (preproc == "endif")
- {
- preprocBlockIndent -= 1;
- indentedLine = preLineWS(preprocBlockIndent, 0) + line;
- if (preprocBlockIndent == 0)
- isInIndentablePreprocBlock = false;
- }
- else
- indentedLine = preLineWS(preprocBlockIndent, 0) + line;
- return getIndentedLineReturn(indentedLine, originalLine);
- }
- if (shouldIndentPreprocConditional && preproc.length() > 0)
- {
- string indentedLine;
- if (preproc.length() >= 2 && preproc.substr(0, 2) == "if") // #if, #ifdef, #ifndef
- {
- pair<int, int> entry; // indentCount, spaceIndentCount
- if (!isInDefine && activeBeautifierStack != nullptr && !activeBeautifierStack->empty())
- entry = activeBeautifierStack->back()->computePreprocessorIndent();
- else
- entry = computePreprocessorIndent();
- preprocIndentStack->emplace_back(entry);
- indentedLine = preLineWS(preprocIndentStack->back().first,
- preprocIndentStack->back().second) + line;
- return getIndentedLineReturn(indentedLine, originalLine);
- }
- if (preproc == "else" || preproc == "elif")
- {
- if (!preprocIndentStack->empty()) // if no entry don't indent
- {
- indentedLine = preLineWS(preprocIndentStack->back().first,
- preprocIndentStack->back().second) + line;
- return getIndentedLineReturn(indentedLine, originalLine);
- }
- }
- else if (preproc == "endif")
- {
- if (!preprocIndentStack->empty()) // if no entry don't indent
- {
- indentedLine = preLineWS(preprocIndentStack->back().first,
- preprocIndentStack->back().second) + line;
- preprocIndentStack->pop_back();
- return getIndentedLineReturn(indentedLine, originalLine);
- }
- }
- }
- }
- // check if the last char is a backslash
- if (line.length() > 0)
- backslashEndsPrevLine = (line[line.length() - 1] == '\\');
- // comments within the definition line can be continued without the backslash
- if (isInPreprocessorUnterminatedComment(line))
- backslashEndsPrevLine = true;
- // check if this line ends a multi-line #define
- // if so, use the #define's cloned beautifier for the line's indentation
- // and then remove it from the active beautifier stack and delete it.
- if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine)
- {
- isInDefineDefinition = false;
- ASBeautifier* defineBeautifier = activeBeautifierStack->back();
- activeBeautifierStack->pop_back();
- string indentedLine = defineBeautifier->beautify(line);
- delete defineBeautifier;
- return getIndentedLineReturn(indentedLine, originalLine);
- }
- // unless this is a multi-line #define, return this precompiler line as is.
- if (!isInDefine && !isInDefineDefinition)
- return originalLine;
- }
- // if there exists any worker beautifier in the activeBeautifierStack,
- // then use it instead of me to indent the current line.
- // variables set by ASFormatter must be updated.
- if (!isInDefine && activeBeautifierStack != nullptr && !activeBeautifierStack->empty())
- {
- activeBeautifierStack->back()->inLineNumber = inLineNumber;
- activeBeautifierStack->back()->runInIndentContinuation = runInIndentContinuation;
- activeBeautifierStack->back()->nonInStatementBrace = nonInStatementBrace;
- activeBeautifierStack->back()->objCColonAlignSubsequent = objCColonAlignSubsequent;
- activeBeautifierStack->back()->lineCommentNoBeautify = lineCommentNoBeautify;
- activeBeautifierStack->back()->isElseHeaderIndent = isElseHeaderIndent;
- activeBeautifierStack->back()->isCaseHeaderCommentIndent = isCaseHeaderCommentIndent;
- activeBeautifierStack->back()->isNonInStatementArray = isNonInStatementArray;
- activeBeautifierStack->back()->isSharpAccessor = isSharpAccessor;
- activeBeautifierStack->back()->isSharpDelegate = isSharpDelegate;
- activeBeautifierStack->back()->isInExternC = isInExternC;
- activeBeautifierStack->back()->isInBeautifySQL = isInBeautifySQL;
- activeBeautifierStack->back()->isInIndentableStruct = isInIndentableStruct;
- activeBeautifierStack->back()->isInIndentablePreproc = isInIndentablePreproc;
- // must return originalLine not the trimmed line
- return activeBeautifierStack->back()->beautify(originalLine);
- }
- // Flag an indented header in case this line is a one-line block.
- // The header in the header stack will be deleted by a one-line block.
- bool isInExtraHeaderIndent = false;
- if (!headerStack->empty()
- && lineBeginsWithOpenBrace
- && (headerStack->back() != &AS_OPEN_BRACE
- || probationHeader != nullptr))
- isInExtraHeaderIndent = true;
- size_t iPrelim = headerStack->size();
- // calculate preliminary indentation based on headerStack and data from past lines
- computePreliminaryIndentation();
- // parse characters in the current line.
- parseCurrentLine(line);
- // handle special cases of indentation
- adjustParsedLineIndentation(iPrelim, isInExtraHeaderIndent);
- if (isInObjCMethodDefinition)
- adjustObjCMethodDefinitionIndentation(line);
- if (isInObjCMethodCall)
- adjustObjCMethodCallIndentation(line);
- if (isInDefine)
- {
- if (line.length() > 0 && line[0] == '#')
- {
- // the 'define' does not have to be attached to the '#'
- string preproc = trim(line.substr(1));
- if (preproc.compare(0, 6, "define") == 0)
- {
- if (!continuationIndentStack->empty()
- && continuationIndentStack->back() > 0)
- {
- defineIndentCount = indentCount;
- }
- else
- {
- defineIndentCount = indentCount - 1;
- --indentCount;
- }
- }
- }
- indentCount -= defineIndentCount;
- }
- if (indentCount < 0)
- indentCount = 0;
- if (lineCommentNoBeautify || blockCommentNoBeautify || isInQuoteContinuation)
- indentCount = spaceIndentCount = 0;
- // finally, insert indentations into beginning of line
- string indentedLine = preLineWS(indentCount, spaceIndentCount) + line;
- indentedLine = getIndentedLineReturn(indentedLine, originalLine);
- prevFinalLineSpaceIndentCount = spaceIndentCount;
- prevFinalLineIndentCount = indentCount;
- if (lastLineHeader != nullptr)
- previousLastLineHeader = lastLineHeader;
- if ((lineIsLineCommentOnly || lineIsCommentOnly)
- && line.find("*INDENT-ON*", 0) != string::npos)
- isIndentModeOff = false;
- return indentedLine;
- }
- const string& ASBeautifier::getIndentedLineReturn(const string& newLine, const string& originalLine) const
- {
- if (isIndentModeOff)
- return originalLine;
- return newLine;
- }
- string ASBeautifier::preLineWS(int lineIndentCount, int lineSpaceIndentCount) const
- {
- if (shouldForceTabIndentation)
- {
- if (tabLength != indentLength)
- {
- // adjust for different tab length
- int indentCountOrig = lineIndentCount;
- int spaceIndentCountOrig = lineSpaceIndentCount;
- lineIndentCount = ((indentCountOrig * indentLength) + spaceIndentCountOrig) / tabLength;
- lineSpaceIndentCount = ((indentCountOrig * indentLength) + spaceIndentCountOrig) % tabLength;
- }
- else
- {
- lineIndentCount += lineSpaceIndentCount / indentLength;
- lineSpaceIndentCount = lineSpaceIndentCount % indentLength;
- }
- }
- string ws;
- for (int i = 0; i < lineIndentCount; i++)
- ws += indentString;
- while ((lineSpaceIndentCount--) > 0)
- ws += string(" ");
- return ws;
- }
- /**
- * register a continuation indent.
- */
- void ASBeautifier::registerContinuationIndent(const string& line, int i, int spaceIndentCount_,
- int tabIncrementIn, int minIndent, bool updateParenStack)
- {
- int remainingCharNum = line.length() - i;
- int nextNonWSChar = getNextProgramCharDistance(line, i);
- // if indent is around the last char in the line OR indent-after-paren is requested,
- // indent with the continuation indent
- if (nextNonWSChar == remainingCharNum || shouldIndentAfterParen)
- {
- int previousIndent = spaceIndentCount_;
- if (!continuationIndentStack->empty())
- previousIndent = continuationIndentStack->back();
- int currIndent = continuationIndent * indentLength + previousIndent;
- if (currIndent > maxContinuationIndent && line[i] != '{')
- currIndent = indentLength * 2 + spaceIndentCount_;
- continuationIndentStack->emplace_back(currIndent);
- if (updateParenStack)
- parenIndentStack->emplace_back(previousIndent);
- return;
- }
- if (updateParenStack)
- parenIndentStack->emplace_back(i + spaceIndentCount_ - runInIndentContinuation);
- int tabIncrement = tabIncrementIn;
- // check for following tabs
- for (int j = i + 1; j < (i + nextNonWSChar); j++)
- {
- if (line[j] == '\t')
- tabIncrement += convertTabToSpaces(j, tabIncrement);
- }
- int continuationIndentCount = i + nextNonWSChar + spaceIndentCount_ + tabIncrement;
- // check for run-in statement
- if (i > 0 && line[0] == '{')
- continuationIndentCount -= indentLength;
- if (continuationIndentCount < minIndent)
- continuationIndentCount = minIndent + spaceIndentCount_;
- // this is not done for an in-statement array
- if (continuationIndentCount > maxContinuationIndent
- && !(prevNonLegalCh == '=' && currentNonLegalCh == '{'))
- continuationIndentCount = indentLength * 2 + spaceIndentCount_;
- if (!continuationIndentStack->empty()
- && continuationIndentCount < continuationIndentStack->back())
- continuationIndentCount = continuationIndentStack->back();
- // the block opener is not indented for a NonInStatementArray
- if ((isNonInStatementArray && line[i] == '{')
- && !isInEnum && !braceBlockStateStack->empty() && braceBlockStateStack->back())
- continuationIndentCount = 0;
- continuationIndentStack->emplace_back(continuationIndentCount);
- }
- /**
- * Register a continuation indent for a class header or a class initializer colon.
- */
- void ASBeautifier::registerContinuationIndentColon(const string& line, int i, int tabIncrementIn)
- {
- assert(line[i] == ':');
- assert(isInClassInitializer || isInClassHeaderTab);
- // register indent at first word after the colon
- size_t firstChar = line.find_first_not_of(" \t");
- if (firstChar == (size_t) i) // firstChar is ':'
- {
- size_t firstWord = line.find_first_not_of(" \t", firstChar + 1);
- if (firstChar != string::npos)
- {
- int continuationIndentCount = firstWord + spaceIndentCount + tabIncrementIn;
- continuationIndentStack->emplace_back(continuationIndentCount);
- isContinuation = true;
- }
- }
- }
- /**
- * Compute indentation for a preprocessor #if statement.
- * This may be called for the activeBeautiferStack
- * instead of the active ASBeautifier object.
- */
- pair<int, int> ASBeautifier::computePreprocessorIndent()
- {
- computePreliminaryIndentation();
- pair<int, int> entry(indentCount, spaceIndentCount);
- if (!headerStack->empty()
- && entry.first > 0
- && (headerStack->back() == &AS_IF
- || headerStack->back() == &AS_ELSE
- || headerStack->back() == &AS_FOR
- || headerStack->back() == &AS_WHILE))
- --entry.first;
- return entry;
- }
- /**
- * get distance to the next non-white space, non-comment character in the line.
- * if no such character exists, return the length remaining to the end of the line.
- */
- int ASBeautifier::getNextProgramCharDistance(const string& line, int i) const
- {
- bool inComment = false;
- int remainingCharNum = line.length() - i;
- int charDistance;
- char ch;
- for (charDistance = 1; charDistance < remainingCharNum; charDistance++)
- {
- ch = line[i + charDistance];
- if (inComment)
- {
- if (line.compare(i + charDistance, 2, "*/") == 0)
- {
- charDistance++;
- inComment = false;
- }
- continue;
- }
- else if (isWhiteSpace(ch))
- continue;
- else if (ch == '/')
- {
- if (line.compare(i + charDistance, 2, "//") == 0)
- return remainingCharNum;
- if (line.compare(i + charDistance, 2, "/*") == 0)
- {
- charDistance++;
- inComment = true;
- }
- }
- else
- return charDistance;
- }
- return charDistance;
- }
- /**
- * find the index number of a string element in a container of strings
- *
- * @return the index number of element in the container. -1 if element not found.
- * @param container a vector of strings.
- * @param element the element to find .
- */
- int ASBeautifier::indexOf(const vector<const string*>& container, const string* element) const
- {
- vector<const string*>::const_iterator where;
- where = find(container.begin(), container.end(), element);
- if (where == container.end())
- return -1;
- return (int) (where - container.begin());
- }
- /**
- * convert tabs to spaces.
- * i is the position of the character to convert to spaces.
- * tabIncrementIn is the increment that must be added for tab indent characters
- * to get the correct column for the current tab.
- */
- int ASBeautifier::convertTabToSpaces(int i, int tabIncrementIn) const
- {
- int tabToSpacesAdjustment = indentLength - 1 - ((tabIncrementIn + i) % indentLength);
- return tabToSpacesAdjustment;
- }
- /**
- * trim removes the white space surrounding a line.
- *
- * @return the trimmed line.
- * @param str the line to trim.
- */
- string ASBeautifier::trim(const string& str) const
- {
- int start = 0;
- int end = str.length() - 1;
- while (start < end && isWhiteSpace(str[start]))
- start++;
- while (start <= end && isWhiteSpace(str[end]))
- end--;
- // don't trim if it ends in a continuation
- if (end > -1 && str[end] == '\\')
- end = str.length() - 1;
- string returnStr(str, start, end + 1 - start);
- return returnStr;
- }
- /**
- * rtrim removes the white space from the end of a line.
- *
- * @return the trimmed line.
- * @param str the line to trim.
- */
- string ASBeautifier::rtrim(const string& str) const
- {
- size_t len = str.length();
- size_t end = str.find_last_not_of(" \t");
- if (end == string::npos
- || end == len - 1)
- return str;
- string returnStr(str, 0, end + 1);
- return returnStr;
- }
- /**
- * Copy tempStacks for the copy constructor.
- * The value of the vectors must also be copied.
- */
- vector<vector<const string*>*>* ASBeautifier::copyTempStacks(const ASBeautifier& other) const
- {
- vector<vector<const string*>*>* tempStacksNew = new vector<vector<const string*>*>;
- vector<vector<const string*>*>::iterator iter;
- for (iter = other.tempStacks->begin();
- iter != other.tempStacks->end();
- ++iter)
- {
- vector<const string*>* newVec = new vector<const string*>;
- *newVec = **iter;
- tempStacksNew->emplace_back(newVec);
- }
- return tempStacksNew;
- }
- /**
- * delete a member vectors to eliminate memory leak reporting
- */
- void ASBeautifier::deleteBeautifierVectors()
- {
- beautifierFileType = 9; // reset to an invalid type
- delete headers;
- delete nonParenHeaders;
- delete preBlockStatements;
- delete preCommandHeaders;
- delete assignmentOperators;
- delete nonAssignmentOperators;
- delete indentableHeaders;
- }
- /**
- * delete a vector object
- * T is the type of vector
- * used for all vectors except tempStacks
- */
- template<typename T>
- void ASBeautifier::deleteContainer(T& container)
- {
- if (container != nullptr)
- {
- container->clear();
- delete (container);
- container = nullptr;
- }
- }
- /**
- * Delete the ASBeautifier vector object.
- * This is a vector of pointers to ASBeautifier objects allocated with the 'new' operator.
- * Therefore the ASBeautifier objects have to be deleted in addition to the
- * ASBeautifier pointer entries.
- */
- void ASBeautifier::deleteBeautifierContainer(vector<ASBeautifier*>*& container)
- {
- if (container != nullptr)
- {
- vector<ASBeautifier*>::iterator iter = container->begin();
- while (iter < container->end())
- {
- delete *iter;
- ++iter;
- }
- container->clear();
- delete (container);
- container = nullptr;
- }
- }
- /**
- * Delete the tempStacks vector object.
- * The tempStacks is a vector of pointers to strings allocated with the 'new' operator.
- * Therefore the strings have to be deleted in addition to the tempStacks entries.
- */
- void ASBeautifier::deleteTempStacksContainer(vector<vector<const string*>*>*& container)
- {
- if (container != nullptr)
- {
- vector<vector<const string*>*>::iterator iter = container->begin();
- while (iter < container->end())
- {
- delete *iter;
- ++iter;
- }
- container->clear();
- delete (container);
- container = nullptr;
- }
- }
- /**
- * initialize a vector object
- * T is the type of vector used for all vectors
- */
- template<typename T>
- void ASBeautifier::initContainer(T& container, T value)
- {
- // since the ASFormatter object is never deleted,
- // the existing vectors must be deleted before creating new ones
- if (container != nullptr)
- deleteContainer(container);
- container = value;
- }
- /**
- * Initialize the tempStacks vector object.
- * The tempStacks is a vector of pointers to strings allocated with the 'new' operator.
- * Any residual entries are deleted before the vector is initialized.
- */
- void ASBeautifier::initTempStacksContainer(vector<vector<const string*>*>*& container,
- vector<vector<const string*>*>* value)
- {
- if (container != nullptr)
- deleteTempStacksContainer(container);
- container = value;
- }
- /**
- * Determine if an assignment statement ends with a comma
- * that is not in a function argument. It ends with a
- * comma if a comma is the last char on the line.
- *
- * @return true if line ends with a comma, otherwise false.
- */
- bool ASBeautifier::statementEndsWithComma(const string& line, int index) const
- {
- assert(line[index] == '=');
- bool isInComment_ = false;
- bool isInQuote_ = false;
- int parenCount = 0;
- size_t lineLength = line.length();
- size_t i = 0;
- char quoteChar_ = ' ';
- for (i = index + 1; i < lineLength; ++i)
- {
- char ch = line[i];
- if (isInComment_)
- {
- if (line.compare(i, 2, "*/") == 0)
- {
- isInComment_ = false;
- ++i;
- }
- continue;
- }
- if (ch == '\\')
- {
- ++i;
- continue;
- }
- if (isInQuote_)
- {
- if (ch == quoteChar_)
- isInQuote_ = false;
- continue;
- }
- if (ch == '"'
- || (ch == '\'' && !isDigitSeparator(line, i)))
- {
- isInQuote_ = true;
- quoteChar_ = ch;
- continue;
- }
- if (line.compare(i, 2, "//") == 0)
- break;
- if (line.compare(i, 2, "/*") == 0)
- {
- if (isLineEndComment(line, i))
- break;
- else
- {
- isInComment_ = true;
- ++i;
- continue;
- }
- }
- if (ch == '(')
- parenCount++;
- if (ch == ')')
- parenCount--;
- }
- if (isInComment_
- || isInQuote_
- || parenCount > 0)
- return false;
- size_t lastChar = line.find_last_not_of(" \t", i - 1);
- if (lastChar == string::npos || line[lastChar] != ',')
- return false;
- return true;
- }
- /**
- * check if current comment is a line-end comment
- *
- * @return is before a line-end comment.
- */
- bool ASBeautifier::isLineEndComment(const string& line, int startPos) const
- {
- assert(line.compare(startPos, 2, "/*") == 0);
- // comment must be closed on this line with nothing after it
- size_t endNum = line.find("*/", startPos + 2);
- if (endNum != string::npos)
- {
- size_t nextChar = line.find_first_not_of(" \t", endNum + 2);
- if (nextChar == string::npos)
- return true;
- }
- return false;
- }
- /**
- * get the previous word index for an assignment operator
- *
- * @return is the index to the previous word (the in statement indent).
- */
- int ASBeautifier::getContinuationIndentAssign(const string& line, size_t currPos) const
- {
- assert(line[currPos] == '=');
- if (currPos == 0)
- return 0;
- // get the last legal word (may be a number)
- size_t end = line.find_last_not_of(" \t", currPos - 1);
- if (end == string::npos || !isLegalNameChar(line[end]))
- return 0;
- int start; // start of the previous word
- for (start = end; start > -1; start--)
- {
- if (!isLegalNameChar(line[start]) || line[start] == '.')
- break;
- }
- start++;
- return start;
- }
- /**
- * get the instatement indent for a comma
- *
- * @return is the indent to the second word on the line (the in statement indent).
- */
- int ASBeautifier::getContinuationIndentComma(const string& line, size_t currPos) const
- {
- assert(line[currPos] == ',');
- // get first word on a line
- size_t indent = line.find_first_not_of(" \t");
- if (indent == string::npos || !isLegalNameChar(line[indent]))
- return 0;
- // bypass first word
- for (; indent < currPos; indent++)
- {
- if (!isLegalNameChar(line[indent]))
- break;
- }
- indent++;
- if (indent >= currPos || indent < 4)
- return 0;
- // point to second word or assignment operator
- indent = line.find_first_not_of(" \t", indent);
- if (indent == string::npos || indent >= currPos)
- return 0;
- return indent;
- }
- /**
- * get the next word on a line
- * the argument 'currPos' must point to the current position.
- *
- * @return is the next word or an empty string if none found.
- */
- string ASBeautifier::getNextWord(const string& line, size_t currPos) const
- {
- size_t lineLength = line.length();
- // get the last legal word (may be a number)
- if (currPos == lineLength - 1)
- return string();
- size_t start = line.find_first_not_of(" \t", currPos + 1);
- if (start == string::npos || !isLegalNameChar(line[start]))
- return string();
- size_t end; // end of the current word
- for (end = start + 1; end <= lineLength; end++)
- {
- if (!isLegalNameChar(line[end]) || line[end] == '.')
- break;
- }
- return line.substr(start, end - start);
- }
- /**
- * Check if a preprocessor directive is always indented.
- * C# "region" and "endregion" are always indented.
- * C/C++ "pragma omp" is always indented.
- *
- * @return is true or false.
- */
- bool ASBeautifier::isIndentedPreprocessor(const string& line, size_t currPos) const
- {
- assert(line[0] == '#');
- string nextWord = getNextWord(line, currPos);
- if (nextWord == "region" || nextWord == "endregion")
- return true;
- // is it #pragma omp
- if (nextWord == "pragma")
- {
- // find pragma
- size_t start = line.find("pragma");
- if (start == string::npos || !isLegalNameChar(line[start]))
- return false;
- // bypass pragma
- for (; start < line.length(); start++)
- {
- if (!isLegalNameChar(line[start]))
- break;
- }
- start++;
- if (start >= line.length())
- return false;
- // point to start of second word
- start = line.find_first_not_of(" \t", start);
- if (start == string::npos)
- return false;
- // point to end of second word
- size_t end;
- for (end = start; end < line.length(); end++)
- {
- if (!isLegalNameChar(line[end]))
- break;
- }
- // check for "pragma omp"
- string word = line.substr(start, end - start);
- if (word == "omp" || word == "region" || word == "endregion")
- return true;
- }
- return false;
- }
- /**
- * Check if a preprocessor directive is checking for __cplusplus defined.
- *
- * @return is true or false.
- */
- bool ASBeautifier::isPreprocessorConditionalCplusplus(const string& line) const
- {
- string preproc = trim(line.substr(1));
- if (preproc.compare(0, 5, "ifdef") == 0 && getNextWord(preproc, 4) == "__cplusplus")
- return true;
- if (preproc.compare(0, 2, "if") == 0)
- {
- // check for " #if defined(__cplusplus)"
- size_t charNum = 2;
- charNum = preproc.find_first_not_of(" \t", charNum);
- if (charNum != string::npos && preproc.compare(charNum, 7, "defined") == 0)
- {
- charNum += 7;
- charNum = preproc.find_first_not_of(" \t", charNum);
- if (preproc.compare(charNum, 1, "(") == 0)
- {
- ++charNum;
- charNum = preproc.find_first_not_of(" \t", charNum);
- if (preproc.compare(charNum, 11, "__cplusplus") == 0)
- return true;
- }
- }
- }
- return false;
- }
- /**
- * Check if a preprocessor definition contains an unterminated comment.
- * Comments within a preprocessor definition can be continued without the backslash.
- *
- * @return is true or false.
- */
- bool ASBeautifier::isInPreprocessorUnterminatedComment(const string& line)
- {
- if (!isInPreprocessorComment)
- {
- size_t startPos = line.find("/*");
- if (startPos == string::npos)
- return false;
- }
- size_t endNum = line.find("*/");
- if (endNum != string::npos)
- {
- isInPreprocessorComment = false;
- return false;
- }
- isInPreprocessorComment = true;
- return true;
- }
- void ASBeautifier::popLastContinuationIndent()
- {
- assert(!continuationIndentStackSizeStack->empty());
- int previousIndentStackSize = continuationIndentStackSizeStack->back();
- if (continuationIndentStackSizeStack->size() > 1)
- continuationIndentStackSizeStack->pop_back();
- while (previousIndentStackSize < (int) continuationIndentStack->size())
- continuationIndentStack->pop_back();
- }
- // for unit testing
- int ASBeautifier::getBeautifierFileType() const
- { return beautifierFileType; }
- /**
- * Process preprocessor statements and update the beautifier stacks.
- */
- void ASBeautifier::processPreprocessor(const string& preproc, const string& line)
- {
- // When finding a multi-lined #define statement, the original beautifier
- // 1. sets its isInDefineDefinition flag
- // 2. clones a new beautifier that will be used for the actual indentation
- // of the #define. This clone is put into the activeBeautifierStack in order
- // to be called for the actual indentation.
- // The original beautifier will have isInDefineDefinition = true, isInDefine = false
- // The cloned beautifier will have isInDefineDefinition = true, isInDefine = true
- if (shouldIndentPreprocDefine && preproc == "define" && line[line.length() - 1] == '\\')
- {
- if (!isInDefineDefinition)
- {
- // this is the original beautifier
- isInDefineDefinition = true;
- // push a new beautifier into the active stack
- // this beautifier will be used for the indentation of this define
- ASBeautifier* defineBeautifier = new ASBeautifier(*this);
- activeBeautifierStack->emplace_back(defineBeautifier);
- }
- else
- {
- // the is the cloned beautifier that is in charge of indenting the #define.
- isInDefine = true;
- }
- }
- else if (preproc.length() >= 2 && preproc.substr(0, 2) == "if")
- {
- if (isPreprocessorConditionalCplusplus(line) && !g_preprocessorCppExternCBrace)
- g_preprocessorCppExternCBrace = 1;
- // push a new beautifier into the stack
- waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size());
- activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size());
- if (activeBeautifierStackLengthStack->back() == 0)
- waitingBeautifierStack->emplace_back(new ASBeautifier(*this));
- else
- waitingBeautifierStack->emplace_back(new ASBeautifier(*activeBeautifierStack->back()));
- }
- else if (preproc == "else")
- {
- if ((waitingBeautifierStack != nullptr) && !waitingBeautifierStack->empty())
- {
- // MOVE current waiting beautifier to active stack.
- activeBeautifierStack->emplace_back(waitingBeautifierStack->back());
- waitingBeautifierStack->pop_back();
- }
- }
- else if (preproc == "elif")
- {
- if ((waitingBeautifierStack != nullptr) && !waitingBeautifierStack->empty())
- {
- // append a COPY current waiting beautifier to active stack, WITHOUT deleting the original.
- activeBeautifierStack->emplace_back(new ASBeautifier(*(waitingBeautifierStack->back())));
- }
- }
- else if (preproc == "endif")
- {
- int stackLength = 0;
- ASBeautifier* beautifier = nullptr;
- if (waitingBeautifierStackLengthStack != nullptr && !waitingBeautifierStackLengthStack->empty())
- {
- stackLength = waitingBeautifierStackLengthStack->back();
- waitingBeautifierStackLengthStack->pop_back();
- while ((int) waitingBeautifierStack->size() > stackLength)
- {
- beautifier = waitingBeautifierStack->back();
- waitingBeautifierStack->pop_back();
- delete beautifier;
- }
- }
- if (!activeBeautifierStackLengthStack->empty())
- {
- stackLength = activeBeautifierStackLengthStack->back();
- activeBeautifierStackLengthStack->pop_back();
- while ((int) activeBeautifierStack->size() > stackLength)
- {
- beautifier = activeBeautifierStack->back();
- activeBeautifierStack->pop_back();
- delete beautifier;
- }
- }
- }
- }
- // Compute the preliminary indentation based on data in the headerStack
- // and data from previous lines.
- // Update the class variable indentCount.
- void ASBeautifier::computePreliminaryIndentation()
- {
- indentCount = 0;
- spaceIndentCount = 0;
- isInClassHeaderTab = false;
- if (isInObjCMethodDefinition && !continuationIndentStack->empty())
- spaceIndentObjCMethodAlignment = continuationIndentStack->back();
- if (!continuationIndentStack->empty())
- spaceIndentCount = continuationIndentStack->back();
- for (size_t i = 0; i < headerStack->size(); i++)
- {
- isInClass = false;
- if (blockIndent)
- {
- // do NOT indent opening block for these headers
- if (!((*headerStack)[i] == &AS_NAMESPACE
- || (*headerStack)[i] == &AS_MODULE
- || (*headerStack)[i] == &AS_CLASS
- || (*headerStack)[i] == &AS_STRUCT
- || (*headerStack)[i] == &AS_UNION
- || (*headerStack)[i] == &AS_INTERFACE
- || (*headerStack)[i] == &AS_THROWS
- || (*headerStack)[i] == &AS_STATIC))
- ++indentCount;
- }
- else if (!(i > 0 && (*headerStack)[i - 1] != &AS_OPEN_BRACE
- && (*headerStack)[i] == &AS_OPEN_BRACE))
- ++indentCount;
- if (!isJavaStyle() && !namespaceIndent && i > 0
- && ((*headerStack)[i - 1] == &AS_NAMESPACE
- || (*headerStack)[i - 1] == &AS_MODULE)
- && (*headerStack)[i] == &AS_OPEN_BRACE)
- --indentCount;
- if (isCStyle() && i >= 1
- && (*headerStack)[i - 1] == &AS_CLASS
- && (*headerStack)[i] == &AS_OPEN_BRACE)
- {
- if (classIndent)
- ++indentCount;
- isInClass = true;
- }
- // is the switchIndent option is on, indent switch statements an additional indent.
- else if (switchIndent && i > 1
- && (*headerStack)[i - 1] == &AS_SWITCH
- && (*headerStack)[i] == &AS_OPEN_BRACE)
- {
- ++indentCount;
- isInSwitch = true;
- }
- } // end of for loop
- if (isInClassHeader)
- {
- if (!isJavaStyle())
- isInClassHeaderTab = true;
- if (lineOpensWithLineComment || lineStartsInComment || lineOpensWithComment)
- {
- if (!lineBeginsWithOpenBrace)
- --indentCount;
- if (!continuationIndentStack->empty())
- spaceIndentCount -= continuationIndentStack->back();
- }
- else if (blockIndent)
- {
- if (!lineBeginsWithOpenBrace)
- ++indentCount;
- }
- }
- if (isInClassInitializer || isInEnumTypeID)
- {
- indentCount += classInitializerIndents;
- }
- if (isInEnum && lineBeginsWithComma && !continuationIndentStack->empty())
- {
- // unregister '=' indent from the previous line
- continuationIndentStack->pop_back();
- isContinuation = false;
- spaceIndentCount = 0;
- }
- // Objective-C interface continuation line
- if (isInObjCInterface)
- ++indentCount;
- // unindent a class closing brace...
- if (!lineStartsInComment
- && isCStyle()
- && isInClass
- && classIndent
- && headerStack->size() >= 2
- && (*headerStack)[headerStack->size() - 2] == &AS_CLASS
- && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACE
- && lineBeginsWithCloseBrace
- && braceBlockStateStack->back())
- --indentCount;
- // unindent an indented switch closing brace...
- else if (!lineStartsInComment
- && isInSwitch
- && switchIndent
- && headerStack->size() >= 2
- && (*headerStack)[headerStack->size() - 2] == &AS_SWITCH
- && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACE
- && lineBeginsWithCloseBrace)
- --indentCount;
- // handle special case of run-in comment in an indented class statement
- if (isInClass
- && classIndent
- && isInRunInComment
- && !lineOpensWithComment
- && headerStack->size() > 1
- && (*headerStack)[headerStack->size() - 2] == &AS_CLASS)
- --indentCount;
- if (isInConditional)
- --indentCount;
- if (g_preprocessorCppExternCBrace >= 4)
- --indentCount;
- }
- void ASBeautifier::adjustParsedLineIndentation(size_t iPrelim, bool isInExtraHeaderIndent)
- {
- if (lineStartsInComment)
- return;
- // unindent a one-line statement in a header indent
- if (!blockIndent
- && lineBeginsWithOpenBrace
- && headerStack->size() < iPrelim
- && isInExtraHeaderIndent
- && (lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum)
- && shouldIndentBracedLine)
- --indentCount;
- /*
- * if '{' doesn't follow an immediately previous '{' in the headerStack
- * (but rather another header such as "for" or "if", then unindent it
- * by one indentation relative to its block.
- */
- else if (!blockIndent
- && lineBeginsWithOpenBrace
- && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum)
- && (headerStack->size() > 1 && (*headerStack)[headerStack->size() - 2] != &AS_OPEN_BRACE)
- && shouldIndentBracedLine)
- --indentCount;
- // must check one less in headerStack if more than one header on a line (allow-addins)...
- else if (headerStack->size() > iPrelim + 1
- && !blockIndent
- && lineBeginsWithOpenBrace
- && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum <= lineClosingBlocksNum)
- && (headerStack->size() > 2 && (*headerStack)[headerStack->size() - 3] != &AS_OPEN_BRACE)
- && shouldIndentBracedLine)
- --indentCount;
- // unindent a closing brace...
- else if (lineBeginsWithCloseBrace
- && shouldIndentBracedLine)
- --indentCount;
- // correctly indent one-line-blocks...
- else if (lineOpeningBlocksNum > 0
- && lineOpeningBlocksNum == lineClosingBlocksNum
- && previousLineProbationTab)
- --indentCount;
- if (indentCount < 0)
- indentCount = 0;
- // take care of extra brace indentation option...
- if (!lineStartsInComment
- && braceIndent
- && shouldIndentBracedLine
- && (lineBeginsWithOpenBrace || lineBeginsWithCloseBrace))
- {
- if (!braceIndentVtk)
- ++indentCount;
- else
- {
- // determine if a style VTK brace is indented
- bool haveUnindentedBrace = false;
- for (size_t i = 0; i < headerStack->size(); i++)
- {
- if (((*headerStack)[i] == &AS_NAMESPACE
- || (*headerStack)[i] == &AS_MODULE
- || (*headerStack)[i] == &AS_CLASS
- || (*headerStack)[i] == &AS_STRUCT)
- && i + 1 < headerStack->size()
- && (*headerStack)[i + 1] == &AS_OPEN_BRACE)
- i++;
- else if (lineBeginsWithOpenBrace)
- {
- // don't double count the current brace
- if (i + 1 < headerStack->size()
- && (*headerStack)[i] == &AS_OPEN_BRACE)
- haveUnindentedBrace = true;
- }
- else if ((*headerStack)[i] == &AS_OPEN_BRACE)
- haveUnindentedBrace = true;
- } // end of for loop
- if (haveUnindentedBrace)
- ++indentCount;
- }
- }
- }
- /**
- * Compute indentCount adjustment when in a series of else-if statements
- * and shouldBreakElseIfs is requested.
- * It increments by one for each 'else' in the tempStack.
- */
- int ASBeautifier::adjustIndentCountForBreakElseIfComments() const
- {
- assert(isElseHeaderIndent && !tempStacks->empty());
- int indentCountIncrement = 0;
- vector<const string*>* lastTempStack = tempStacks->back();
- if (lastTempStack != nullptr)
- {
- for (size_t i = 0; i < lastTempStack->size(); i++)
- {
- if (*lastTempStack->at(i) == AS_ELSE)
- indentCountIncrement++;
- }
- }
- return indentCountIncrement;
- }
- /**
- * Extract a preprocessor statement without the #.
- * If a error occurs an empty string is returned.
- */
- string ASBeautifier::extractPreprocessorStatement(const string& line) const
- {
- string preproc;
- size_t start = line.find_first_not_of("#/ \t");
- if (start == string::npos)
- return preproc;
- size_t end = line.find_first_of("/ \t", start);
- if (end == string::npos)
- end = line.length();
- preproc = line.substr(start, end - start);
- return preproc;
- }
- void ASBeautifier::adjustObjCMethodDefinitionIndentation(const string& line_)
- {
- // register indent for Objective-C continuation line
- if (line_.length() > 0
- && (line_[0] == '-' || line_[0] == '+'))
- {
- if (shouldAlignMethodColon && objCColonAlignSubsequent != -1)
- {
- string convertedLine = getIndentedSpaceEquivalent(line_);
- colonIndentObjCMethodAlignment = convertedLine.find(':');
- int objCColonAlignSubsequentIndent = objCColonAlignSubsequent + indentLength;
- if (objCColonAlignSubsequentIndent > colonIndentObjCMethodAlignment)
- colonIndentObjCMethodAlignment = objCColonAlignSubsequentIndent;
- }
- else if (continuationIndentStack->empty()
- || continuationIndentStack->back() == 0)
- {
- continuationIndentStack->emplace_back(indentLength);
- isContinuation = true;
- }
- }
- // set indent for last definition line
- else if (!lineBeginsWithOpenBrace)
- {
- if (shouldAlignMethodColon)
- spaceIndentCount = computeObjCColonAlignment(line_, colonIndentObjCMethodAlignment);
- else if (continuationIndentStack->empty())
- spaceIndentCount = spaceIndentObjCMethodAlignment;
- }
- }
- void ASBeautifier::adjustObjCMethodCallIndentation(const string& line_)
- {
- static int keywordIndentObjCMethodAlignment = 0;
- if (shouldAlignMethodColon && objCColonAlignSubsequent != -1)
- {
- if (isInObjCMethodCallFirst)
- {
- isInObjCMethodCallFirst = false;
- string convertedLine = getIndentedSpaceEquivalent(line_);
- bracePosObjCMethodAlignment = convertedLine.find('[');
- keywordIndentObjCMethodAlignment =
- getObjCFollowingKeyword(convertedLine, bracePosObjCMethodAlignment);
- colonIndentObjCMethodAlignment = convertedLine.find(':');
- if (colonIndentObjCMethodAlignment >= 0)
- {
- int objCColonAlignSubsequentIndent = objCColonAlignSubsequent + indentLength;
- if (objCColonAlignSubsequentIndent > colonIndentObjCMethodAlignment)
- colonIndentObjCMethodAlignment = objCColonAlignSubsequentIndent;
- if (lineBeginsWithOpenBrace)
- colonIndentObjCMethodAlignment -= indentLength;
- }
- }
- else
- {
- if (line_.find(':') != string::npos)
- {
- if (colonIndentObjCMethodAlignment < 0)
- spaceIndentCount += computeObjCColonAlignment(line_, objCColonAlignSubsequent);
- else if (objCColonAlignSubsequent > colonIndentObjCMethodAlignment)
- spaceIndentCount = computeObjCColonAlignment(line_, objCColonAlignSubsequent);
- else
- spaceIndentCount = computeObjCColonAlignment(line_, colonIndentObjCMethodAlignment);
- }
- else
- {
- if (spaceIndentCount < colonIndentObjCMethodAlignment)
- spaceIndentCount += keywordIndentObjCMethodAlignment;
- }
- }
- }
- else // align keywords instead of colons
- {
- if (isInObjCMethodCallFirst)
- {
- isInObjCMethodCallFirst = false;
- string convertedLine = getIndentedSpaceEquivalent(line_);
- bracePosObjCMethodAlignment = convertedLine.find('[');
- keywordIndentObjCMethodAlignment =
- getObjCFollowingKeyword(convertedLine, bracePosObjCMethodAlignment);
- }
- else
- {
- if (spaceIndentCount < keywordIndentObjCMethodAlignment + bracePosObjCMethodAlignment)
- spaceIndentCount += keywordIndentObjCMethodAlignment;
- }
- }
- }
- /**
- * Clear the variables used to align the Objective-C method definitions.
- */
- void ASBeautifier::clearObjCMethodDefinitionAlignment()
- {
- assert(isImmediatelyPostObjCMethodDefinition);
- spaceIndentCount = 0;
- spaceIndentObjCMethodAlignment = 0;
- colonIndentObjCMethodAlignment = 0;
- isInObjCMethodDefinition = false;
- isImmediatelyPostObjCMethodDefinition = false;
- if (!continuationIndentStack->empty())
- continuationIndentStack->pop_back();
- }
- /**
- * Compute the spaceIndentCount necessary to align the current line colon
- * with the colon position in the argument.
- * If it cannot be aligned indentLength is returned and a new colon
- * position is calculated.
- */
- int ASBeautifier::computeObjCColonAlignment(const string& line, int colonAlignPosition) const
- {
- int colonPosition = line.find(':');
- if (colonPosition < 0 || colonPosition > colonAlignPosition)
- return indentLength;
- return (colonAlignPosition - colonPosition);
- }
- /*
- * Compute postition of the keyword following the method call object.
- */
- int ASBeautifier::getObjCFollowingKeyword(const string& line, int bracePos) const
- {
- assert(line[bracePos] == '[');
- size_t firstText = line.find_first_not_of(" \t", bracePos + 1);
- if (firstText == string::npos)
- return -(indentCount * indentLength - 1);
- size_t searchBeg = firstText;
- size_t objectEnd = 0; // end of object text
- if (line[searchBeg] == '[')
- {
- objectEnd = line.find(']', searchBeg + 1);
- if (objectEnd == string::npos)
- return 0;
- }
- else
- {
- if (line[searchBeg] == '(')
- {
- searchBeg = line.find(')', searchBeg + 1);
- if (searchBeg == string::npos)
- return 0;
- }
- // bypass the object name
- objectEnd = line.find_first_of(" \t", searchBeg + 1);
- if (objectEnd == string::npos)
- return 0;
- --objectEnd;
- }
- size_t keyPos = line.find_first_not_of(" \t", objectEnd + 1);
- if (keyPos == string::npos)
- return 0;
- return keyPos - firstText;
- }
- /**
- * Get a line using the current space indent with all tabs replaced by spaces.
- * The indentCount is NOT included
- * Needed to compute an accurate alignment.
- */
- string ASBeautifier::getIndentedSpaceEquivalent(const string& line_) const
- {
- string spaceIndent;
- spaceIndent.append(spaceIndentCount, ' ');
- string convertedLine = spaceIndent + line_;
- for (size_t i = spaceIndent.length(); i < convertedLine.length(); i++)
- {
- if (convertedLine[i] == '\t')
- {
- size_t numSpaces = indentLength - (i % indentLength);
- convertedLine.replace(i, 1, numSpaces, ' ');
- i += indentLength - 1;
- }
- }
- return convertedLine;
- }
- /**
- * Parse the current line to update indentCount and spaceIndentCount.
- */
- void ASBeautifier::parseCurrentLine(const string& line)
- {
- bool isInLineComment = false;
- bool isInOperator = false;
- bool isSpecialChar = false;
- bool haveCaseIndent = false;
- bool haveAssignmentThisLine = false;
- bool closingBraceReached = false;
- bool previousLineProbation = (probationHeader != nullptr);
- char ch = ' ';
- int tabIncrementIn = 0;
- if (isInQuote
- && !haveLineContinuationChar
- && !isInVerbatimQuote
- && !isInAsm)
- isInQuote = false; // missing closing quote
- haveLineContinuationChar = false;
- for (size_t i = 0; i < line.length(); i++)
- {
- ch = line[i];
- if (isInBeautifySQL)
- continue;
- // handle special characters (i.e. backslash+character such as \n, \t, ...)
- if (isInQuote && !isInVerbatimQuote)
- {
- if (isSpecialChar)
- {
- isSpecialChar = false;
- continue;
- }
- if (line.compare(i, 2, "\\\\") == 0)
- {
- i++;
- continue;
- }
- if (ch == '\\')
- {
- if (peekNextChar(line, i) == ' ') // is this '\' at end of line
- haveLineContinuationChar = true;
- else
- isSpecialChar = true;
- continue;
- }
- }
- else if (isInDefine && ch == '\\')
- continue;
- // bypass whitespace here
- if (isWhiteSpace(ch))
- {
- if (ch == '\t')
- tabIncrementIn += convertTabToSpaces(i, tabIncrementIn);
- continue;
- }
- // handle quotes (such as 'x' and "Hello Dolly")
- if (!(isInComment || isInLineComment)
- && (ch == '"'
- || (ch == '\'' && !isDigitSeparator(line, i))))
- {
- if (!isInQuote)
- {
- quoteChar = ch;
- isInQuote = true;
- char prevCh = i > 0 ? line[i - 1] : ' ';
- if (isCStyle() && prevCh == 'R')
- {
- int parenPos = line.find('(', i);
- if (parenPos != -1)
- {
- isInVerbatimQuote = true;
- verbatimDelimiter = line.substr(i + 1, parenPos - i - 1);
- }
- }
- else if (isSharpStyle() && prevCh == '@')
- isInVerbatimQuote = true;
- // check for "C" following "extern"
- else if (g_preprocessorCppExternCBrace == 2 && line.compare(i, 3, "\"C\"") == 0)
- ++g_preprocessorCppExternCBrace;
- }
- else if (isInVerbatimQuote && ch == '"')
- {
- if (isCStyle())
- {
- string delim = ')' + verbatimDelimiter;
- int delimStart = i - delim.length();
- if (delimStart > 0 && line.substr(delimStart, delim.length()) == delim)
- {
- isInQuote = false;
- isInVerbatimQuote = false;
- }
- }
- else if (isSharpStyle())
- {
- if (line.compare(i, 2, "\"\"") == 0)
- i++;
- else
- {
- isInQuote = false;
- isInVerbatimQuote = false;
- continue;
- }
- }
- }
- else if (quoteChar == ch)
- {
- isInQuote = false;
- isContinuation = true;
- continue;
- }
- }
- if (isInQuote)
- continue;
- // handle comments
- if (!(isInComment || isInLineComment) && line.compare(i, 2, "//") == 0)
- {
- // if there is a 'case' statement after these comments unindent by 1
- if (isCaseHeaderCommentIndent)
- --indentCount;
- // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested
- // if there is an 'else' after these comments a tempStacks indent is required
- if (isElseHeaderIndent && lineOpensWithLineComment && !tempStacks->empty())
- indentCount += adjustIndentCountForBreakElseIfComments();
- isInLineComment = true;
- i++;
- continue;
- }
- else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0)
- {
- // if there is a 'case' statement after these comments unindent by 1
- if (isCaseHeaderCommentIndent && lineOpensWithComment)
- --indentCount;
- // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested
- // if there is an 'else' after these comments a tempStacks indent is required
- if (isElseHeaderIndent && lineOpensWithComment && !tempStacks->empty())
- indentCount += adjustIndentCountForBreakElseIfComments();
- isInComment = true;
- i++;
- if (!lineOpensWithComment) // does line start with comment?
- blockCommentNoIndent = true; // if no, cannot indent continuation lines
- continue;
- }
- else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0)
- {
- size_t firstText = line.find_first_not_of(" \t");
- // if there is a 'case' statement after these comments unindent by 1
- // only if the ending comment is the first entry on the line
- if (isCaseHeaderCommentIndent && firstText == i)
- --indentCount;
- // if this comment close starts the line, must check for else-if indent
- // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested
- // if there is an 'else' after these comments a tempStacks indent is required
- if (firstText == i)
- {
- if (isElseHeaderIndent && !lineOpensWithComment && !tempStacks->empty())
- indentCount += adjustIndentCountForBreakElseIfComments();
- }
- isInComment = false;
- i++;
- blockCommentNoIndent = false; // ok to indent next comment
- continue;
- }
- // treat indented preprocessor lines as a line comment
- else if (line[0] == '#' && isIndentedPreprocessor(line, i))
- {
- isInLineComment = true;
- }
- if (isInLineComment)
- {
- // bypass rest of the comment up to the comment end
- while (i + 1 < line.length())
- i++;
- continue;
- }
- if (isInComment)
- {
- // if there is a 'case' statement after these comments unindent by 1
- if (!lineOpensWithComment && isCaseHeaderCommentIndent)
- --indentCount;
- // isElseHeaderIndent is set by ASFormatter if shouldBreakElseIfs is requested
- // if there is an 'else' after these comments a tempStacks indent is required
- if (!lineOpensWithComment && isElseHeaderIndent && !tempStacks->empty())
- indentCount += adjustIndentCountForBreakElseIfComments();
- // bypass rest of the comment up to the comment end
- while (i + 1 < line.length()
- && line.compare(i + 1, 2, "*/") != 0)
- i++;
- continue;
- }
- // if we have reached this far then we are NOT in a comment or string of special character...
- if (probationHeader != nullptr)
- {
- if ((probationHeader == &AS_STATIC && ch == '{')
- || (probationHeader == &AS_SYNCHRONIZED && ch == '('))
- {
- // insert the probation header as a new header
- isInHeader = true;
- headerStack->emplace_back(probationHeader);
- // handle the specific probation header
- isInConditional = (probationHeader == &AS_SYNCHRONIZED);
- isContinuation = false;
- // if the probation comes from the previous line, then indent by 1 tab count.
- if (previousLineProbation
- && ch == '{'
- && !(blockIndent && probationHeader == &AS_STATIC))
- {
- ++indentCount;
- previousLineProbationTab = true;
- }
- previousLineProbation = false;
- }
- // dismiss the probation header
- probationHeader = nullptr;
- }
- prevNonSpaceCh = currentNonSpaceCh;
- currentNonSpaceCh = ch;
- if (!isLegalNameChar(ch) && ch != ',' && ch != ';')
- {
- prevNonLegalCh = currentNonLegalCh;
- currentNonLegalCh = ch;
- }
- if (isInHeader)
- {
- isInHeader = false;
- currentHeader = headerStack->back();
- }
- else
- currentHeader = nullptr;
- if (isCStyle() && isInTemplate
- && (ch == '<' || ch == '>')
- && !(line.length() > i + 1 && line.compare(i, 2, ">=") == 0))
- {
- if (ch == '<')
- {
- ++templateDepth;
- continuationIndentStackSizeStack->push_back(continuationIndentStack->size());
- registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true);
- }
- else if (ch == '>')
- {
- popLastContinuationIndent();
- if (--templateDepth <= 0)
- {
- ch = ';';
- isInTemplate = false;
- templateDepth = 0;
- }
- }
- }
- // handle parentheses
- if (ch == '(' || ch == '[' || ch == ')' || ch == ']')
- {
- if (ch == '(' || ch == '[')
- {
- isInOperator = false;
- // if have a struct header, this is a declaration not a definition
- if (ch == '('
- && !headerStack->empty()
- && headerStack->back() == &AS_STRUCT)
- {
- headerStack->pop_back();
- isInClassHeader = false;
- if (line.find(AS_STRUCT, 0) > i) // if not on this line
- indentCount -= classInitializerIndents;
- if (indentCount < 0)
- indentCount = 0;
- }
- if (parenDepth == 0)
- {
- parenStatementStack->push_back(isContinuation);
- isContinuation = true;
- }
- parenDepth++;
- if (ch == '[')
- {
- ++squareBracketCount;
- if (squareBracketCount == 1 && isCStyle())
- {
- isInObjCMethodCall = true;
- isInObjCMethodCallFirst = true;
- }
- }
- continuationIndentStackSizeStack->push_back(continuationIndentStack->size());
- if (currentHeader != nullptr)
- registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, minConditionalIndent, true);
- else
- registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true);
- }
- else if (ch == ')' || ch == ']')
- {
- if (ch == ']')
- --squareBracketCount;
- if (squareBracketCount <= 0)
- {
- squareBracketCount = 0;
- if (isInObjCMethodCall)
- isImmediatelyPostObjCMethodCall = true;
- }
- foundPreCommandHeader = false;
- parenDepth--;
- if (parenDepth == 0)
- {
- if (!parenStatementStack->empty()) // in case of unmatched closing parens
- {
- isContinuation = parenStatementStack->back();
- parenStatementStack->pop_back();
- }
- isInAsm = false;
- isInConditional = false;
- }
- if (!continuationIndentStackSizeStack->empty())
- {
- popLastContinuationIndent();
- if (!parenIndentStack->empty())
- {
- int poppedIndent = parenIndentStack->back();
- parenIndentStack->pop_back();
- if (i == 0)
- spaceIndentCount = poppedIndent;
- }
- }
- }
- continue;
- }
- if (ch == '{')
- {
- // first, check if '{' is a block-opener or a static-array opener
- bool isBlockOpener = ((prevNonSpaceCh == '{' && braceBlockStateStack->back())
- || prevNonSpaceCh == '}'
- || prevNonSpaceCh == ')'
- || prevNonSpaceCh == ';'
- || peekNextChar(line, i) == '{'
- || foundPreCommandHeader
- || foundPreCommandMacro
- || isInClassHeader
- || (isInClassInitializer && !isLegalNameChar(prevNonSpaceCh))
- || isNonInStatementArray
- || isInObjCMethodDefinition
- || isInObjCInterface
- || isSharpAccessor
- || isSharpDelegate
- || isInExternC
- || isInAsmBlock
- || getNextWord(line, i) == AS_NEW
- || (isInDefine
- && (prevNonSpaceCh == '('
- || isLegalNameChar(prevNonSpaceCh))));
- if (isInObjCMethodDefinition)
- {
- objCColonAlignSubsequent = 0;
- isImmediatelyPostObjCMethodDefinition = true;
- if (lineBeginsWithOpenBrace) // for run-in braces
- clearObjCMethodDefinitionAlignment();
- }
- if (!isBlockOpener && !isContinuation && !isInClassInitializer && !isInEnum)
- {
- if (headerStack->empty())
- isBlockOpener = true;
- else if (headerStack->back() == &AS_OPEN_BRACE
- && headerStack->size() >= 2)
- {
- if ((*headerStack)[headerStack->size() - 2] == &AS_NAMESPACE
- || (*headerStack)[headerStack->size() - 2] == &AS_MODULE
- || (*headerStack)[headerStack->size() - 2] == &AS_CLASS
- || (*headerStack)[headerStack->size() - 2] == &AS_INTERFACE
- || (*headerStack)[headerStack->size() - 2] == &AS_STRUCT
- || (*headerStack)[headerStack->size() - 2] == &AS_UNION)
- isBlockOpener = true;
- }
- else if (headerStack->back() == &AS_NAMESPACE
- || headerStack->back() == &AS_MODULE
- || headerStack->back() == &AS_CLASS
- || headerStack->back() == &AS_INTERFACE
- || headerStack->back() == &AS_STRUCT
- || headerStack->back() == &AS_UNION)
- isBlockOpener = true;
- }
- if (!isBlockOpener && currentHeader != nullptr)
- {
- for (size_t n = 0; n < nonParenHeaders->size(); n++)
- if (currentHeader == (*nonParenHeaders)[n])
- {
- isBlockOpener = true;
- break;
- }
- }
- braceBlockStateStack->push_back(isBlockOpener);
- if (!isBlockOpener)
- {
- continuationIndentStackSizeStack->push_back(continuationIndentStack->size());
- registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, true);
- parenDepth++;
- if (i == 0)
- shouldIndentBracedLine = false;
- isInEnumTypeID = false;
- continue;
- }
- // this brace is a block opener...
- ++lineOpeningBlocksNum;
- if (isInClassInitializer || isInEnumTypeID)
- {
- // decrease tab count if brace is broken
- if (lineBeginsWithOpenBrace)
- {
- indentCount -= classInitializerIndents;
- // decrease one more if an empty class
- if (!headerStack->empty()
- && (*headerStack).back() == &AS_CLASS)
- {
- int nextChar = getNextProgramCharDistance(line, i);
- if ((int) line.length() > nextChar && line[nextChar] == '}')
- --indentCount;
- }
- }
- }
- if (isInObjCInterface)
- {
- isInObjCInterface = false;
- if (lineBeginsWithOpenBrace)
- --indentCount;
- }
- if (braceIndent && !namespaceIndent && !headerStack->empty()
- && ((*headerStack).back() == &AS_NAMESPACE
- || (*headerStack).back() == &AS_MODULE))
- {
- shouldIndentBracedLine = false;
- --indentCount;
- }
- // an indentable struct is treated like a class in the header stack
- if (!headerStack->empty()
- && (*headerStack).back() == &AS_STRUCT
- && isInIndentableStruct)
- (*headerStack).back() = &AS_CLASS;
- squareBracketDepthStack->emplace_back(parenDepth);
- blockStatementStack->push_back(isContinuation);
- if (!continuationIndentStack->empty())
- {
- // completely purge the inStatementIndentStack
- while (!continuationIndentStack->empty())
- popLastContinuationIndent();
- if (isInClassInitializer || isInClassHeaderTab)
- {
- if (lineBeginsWithOpenBrace || lineBeginsWithComma)
- spaceIndentCount = 0;
- }
- else
- spaceIndentCount = 0;
- }
- blockTabCount += (isContinuation ? 1 : 0);
- if (g_preprocessorCppExternCBrace == 3)
- ++g_preprocessorCppExternCBrace;
- parenDepth = 0;
- isInClassHeader = false;
- isInClassHeaderTab = false;
- isInClassInitializer = false;
- isInEnumTypeID = false;
- isContinuation = false;
- isInQuestion = false;
- isInLet = false;
- foundPreCommandHeader = false;
- foundPreCommandMacro = false;
- isInExternC = false;
- tempStacks->emplace_back(new vector<const string*>);
- headerStack->emplace_back(&AS_OPEN_BRACE);
- lastLineHeader = &AS_OPEN_BRACE;
- continue;
- } // end '{'
- //check if a header has been reached
- bool isPotentialHeader = isCharPotentialHeader(line, i);
- if (isPotentialHeader && squareBracketCount == 0)
- {
- const string* newHeader = findHeader(line, i, headers);
- // Qt headers may be variables in C++
- if (isCStyle()
- && (newHeader == &AS_FOREVER || newHeader == &AS_FOREACH))
- {
- if (line.find_first_of("=;", i) != string::npos)
- newHeader = nullptr;
- }
- else if (newHeader == &AS_USING
- && ASBeautifier::peekNextChar(line, i + (*newHeader).length() - 1) != '(')
- newHeader = nullptr;
- if (newHeader != nullptr)
- {
- // if we reached here, then this is a header...
- bool isIndentableHeader = true;
- isInHeader = true;
- vector<const string*>* lastTempStack = nullptr;;
- if (!tempStacks->empty())
- lastTempStack = tempStacks->back();
- // if a new block is opened, push a new stack into tempStacks to hold the
- // future list of headers in the new block.
- // take care of the special case: 'else if (...)'
- if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE)
- {
- headerStack->pop_back();
- }
- // take care of 'else'
- else if (newHeader == &AS_ELSE)
- {
- if (lastTempStack != nullptr)
- {
- int indexOfIf = indexOf(*lastTempStack, &AS_IF);
- if (indexOfIf != -1)
- {
- // recreate the header list in headerStack up to the previous 'if'
- // from the temporary snapshot stored in lastTempStack.
- int restackSize = lastTempStack->size() - indexOfIf - 1;
- for (int r = 0; r < restackSize; r++)
- {
- headerStack->emplace_back(lastTempStack->back());
- lastTempStack->pop_back();
- }
- if (!closingBraceReached)
- indentCount += restackSize;
- }
- /*
- * If the above if is not true, i.e. no 'if' before the 'else',
- * then nothing beautiful will come out of this...
- * I should think about inserting an Exception here to notify the caller of this...
- */
- }
- }
- // check if 'while' closes a previous 'do'
- else if (newHeader == &AS_WHILE)
- {
- if (lastTempStack != nullptr)
- {
- int indexOfDo = indexOf(*lastTempStack, &AS_DO);
- if (indexOfDo != -1)
- {
- // recreate the header list in headerStack up to the previous 'do'
- // from the temporary snapshot stored in lastTempStack.
- int restackSize = lastTempStack->size() - indexOfDo - 1;
- for (int r = 0; r < restackSize; r++)
- {
- headerStack->emplace_back(lastTempStack->back());
- lastTempStack->pop_back();
- }
- if (!closingBraceReached)
- indentCount += restackSize;
- }
- }
- }
- // check if 'catch' closes a previous 'try' or 'catch'
- else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY)
- {
- if (lastTempStack != nullptr)
- {
- int indexOfTry = indexOf(*lastTempStack, &AS_TRY);
- if (indexOfTry == -1)
- indexOfTry = indexOf(*lastTempStack, &AS_CATCH);
- if (indexOfTry != -1)
- {
- // recreate the header list in headerStack up to the previous 'try'
- // from the temporary snapshot stored in lastTempStack.
- int restackSize = lastTempStack->size() - indexOfTry - 1;
- for (int r = 0; r < restackSize; r++)
- {
- headerStack->emplace_back(lastTempStack->back());
- lastTempStack->pop_back();
- }
- if (!closingBraceReached)
- indentCount += restackSize;
- }
- }
- }
- else if (newHeader == &AS_CASE)
- {
- isInCase = true;
- if (!haveCaseIndent)
- {
- haveCaseIndent = true;
- if (!lineBeginsWithOpenBrace)
- --indentCount;
- }
- }
- else if (newHeader == &AS_DEFAULT)
- {
- isInCase = true;
- --indentCount;
- }
- else if (newHeader == &AS_STATIC
- || newHeader == &AS_SYNCHRONIZED)
- {
- if (!headerStack->empty()
- && (headerStack->back() == &AS_STATIC
- || headerStack->back() == &AS_SYNCHRONIZED))
- {
- isIndentableHeader = false;
- }
- else
- {
- isIndentableHeader = false;
- probationHeader = newHeader;
- }
- }
- else if (newHeader == &AS_TEMPLATE)
- {
- isInTemplate = true;
- isIndentableHeader = false;
- }
- if (isIndentableHeader)
- {
- headerStack->emplace_back(newHeader);
- isContinuation = false;
- if (indexOf(*nonParenHeaders, newHeader) == -1)
- {
- isInConditional = true;
- }
- lastLineHeader = newHeader;
- }
- else
- isInHeader = false;
- i += newHeader->length() - 1;
- continue;
- } // newHeader != nullptr
- if (findHeader(line, i, preCommandHeaders) != nullptr)
- foundPreCommandHeader = true;
- // Objective-C NSException macros are preCommandHeaders
- if (isCStyle() && findKeyword(line, i, AS_NS_DURING))
- foundPreCommandMacro = true;
- if (isCStyle() && findKeyword(line, i, AS_NS_HANDLER))
- foundPreCommandMacro = true;
- if (parenDepth == 0 && findKeyword(line, i, AS_ENUM))
- isInEnum = true;
- if (isSharpStyle() && findKeyword(line, i, AS_LET))
- isInLet = true;
- } // isPotentialHeader
- if (ch == '?')
- isInQuestion = true;
- // special handling of colons
- if (ch == ':')
- {
- if (line.length() > i + 1 && line[i + 1] == ':') // look for ::
- {
- ++i;
- continue;
- }
- else if (isInQuestion)
- {
- // do nothing special
- }
- else if (parenDepth > 0)
- {
- // found a 'for' loop or an objective-C statement
- // so do nothing special
- }
- else if (isInEnum)
- {
- // found an enum with a base-type
- isInEnumTypeID = true;
- if (i == 0)
- indentCount += classInitializerIndents;
- }
- else if (isCStyle()
- && !isInCase
- && (prevNonSpaceCh == ')' || foundPreCommandHeader))
- {
- // found a 'class' c'tor initializer
- isInClassInitializer = true;
- registerContinuationIndentColon(line, i, tabIncrementIn);
- if (i == 0)
- indentCount += classInitializerIndents;
- }
- else if (isInClassHeader || isInObjCInterface)
- {
- // is in a 'class A : public B' definition
- isInClassHeaderTab = true;
- registerContinuationIndentColon(line, i, tabIncrementIn);
- }
- else if (isInAsm || isInAsmOneLine || isInAsmBlock)
- {
- // do nothing special
- }
- else if (isDigit(peekNextChar(line, i)))
- {
- // found a bit field - do nothing special
- }
- else if (isCStyle() && isInClass && prevNonSpaceCh != ')')
- {
- // found a 'private:' or 'public:' inside a class definition
- --indentCount;
- if (modifierIndent)
- spaceIndentCount += (indentLength / 2);
- }
- else if (isCStyle() && !isInClass
- && headerStack->size() >= 2
- && (*headerStack)[headerStack->size() - 2] == &AS_CLASS
- && (*headerStack)[headerStack->size() - 1] == &AS_OPEN_BRACE)
- {
- // found a 'private:' or 'public:' inside a class definition
- // and on the same line as the class opening brace
- // do nothing
- }
- else if (isJavaStyle() && lastLineHeader == &AS_FOR)
- {
- // found a java for-each statement
- // so do nothing special
- }
- else
- {
- currentNonSpaceCh = ';'; // so that braces after the ':' will appear as block-openers
- char peekedChar = peekNextChar(line, i);
- if (isInCase)
- {
- isInCase = false;
- ch = ';'; // from here on, treat char as ';'
- }
- else if (isCStyle() || (isSharpStyle() && peekedChar == ';'))
- {
- // is in a label (e.g. 'label1:')
- if (labelIndent)
- --indentCount; // unindent label by one indent
- else if (!lineBeginsWithOpenBrace)
- indentCount = 0; // completely flush indent to left
- }
- }
- }
- if ((ch == ';' || (parenDepth > 0 && ch == ',')) && !continuationIndentStackSizeStack->empty())
- while ((int) continuationIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0)
- < (int) continuationIndentStack->size())
- continuationIndentStack->pop_back();
- else if (ch == ',' && isInEnum && isNonInStatementArray && !continuationIndentStack->empty())
- continuationIndentStack->pop_back();
- // handle commas
- // previous "isInStatement" will be from an assignment operator or class initializer
- if (ch == ',' && parenDepth == 0 && !isContinuation && !isNonInStatementArray)
- {
- // is comma at end of line
- size_t nextChar = line.find_first_not_of(" \t", i + 1);
- if (nextChar != string::npos)
- {
- if (line.compare(nextChar, 2, "//") == 0
- || line.compare(nextChar, 2, "/*") == 0)
- nextChar = string::npos;
- }
- // register indent
- if (nextChar == string::npos)
- {
- // register indent at previous word
- if (isJavaStyle() && isInClassHeader)
- {
- // do nothing for now
- }
- // register indent at second word on the line
- else if (!isInTemplate && !isInClassHeaderTab && !isInClassInitializer)
- {
- int prevWord = getContinuationIndentComma(line, i);
- int continuationIndentCount = prevWord + spaceIndentCount + tabIncrementIn;
- continuationIndentStack->emplace_back(continuationIndentCount);
- isContinuation = true;
- }
- }
- }
- // handle comma first initializers
- if (ch == ',' && parenDepth == 0 && lineBeginsWithComma
- && (isInClassInitializer || isInClassHeaderTab))
- spaceIndentCount = 0;
- // handle ends of statements
- if ((ch == ';' && parenDepth == 0) || ch == '}')
- {
- if (ch == '}')
- {
- // first check if this '}' closes a previous block, or a static array...
- if (braceBlockStateStack->size() > 1)
- {
- bool braceBlockState = braceBlockStateStack->back();
- braceBlockStateStack->pop_back();
- if (!braceBlockState)
- {
- if (!continuationIndentStackSizeStack->empty())
- {
- // this brace is a static array
- popLastContinuationIndent();
- parenDepth--;
- if (i == 0)
- shouldIndentBracedLine = false;
- if (!parenIndentStack->empty())
- {
- int poppedIndent = parenIndentStack->back();
- parenIndentStack->pop_back();
- if (i == 0)
- spaceIndentCount = poppedIndent;
- }
- }
- continue;
- }
- }
- // this brace is block closer...
- ++lineClosingBlocksNum;
- if (!continuationIndentStackSizeStack->empty())
- popLastContinuationIndent();
- if (!squareBracketDepthStack->empty())
- {
- parenDepth = squareBracketDepthStack->back();
- squareBracketDepthStack->pop_back();
- isContinuation = blockStatementStack->back();
- blockStatementStack->pop_back();
- if (isContinuation)
- blockTabCount--;
- }
- closingBraceReached = true;
- if (i == 0)
- spaceIndentCount = 0;
- isInAsmBlock = false;
- isInAsm = isInAsmOneLine = isInQuote = false; // close these just in case
- int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACE);
- if (headerPlace != -1)
- {
- const string* popped = headerStack->back();
- while (popped != &AS_OPEN_BRACE)
- {
- headerStack->pop_back();
- popped = headerStack->back();
- }
- headerStack->pop_back();
- if (headerStack->empty())
- g_preprocessorCppExternCBrace = 0;
- // do not indent namespace brace unless namespaces are indented
- if (!namespaceIndent && !headerStack->empty()
- && ((*headerStack).back() == &AS_NAMESPACE
- || (*headerStack).back() == &AS_MODULE)
- && i == 0) // must be the first brace on the line
- shouldIndentBracedLine = false;
- if (!tempStacks->empty())
- {
- vector<const string*>* temp = tempStacks->back();
- tempStacks->pop_back();
- delete temp;
- }
- }
- ch = ' '; // needed due to cases such as '}else{', so that headers ('else' in this case) will be identified...
- } // ch == '}'
- /*
- * Create a temporary snapshot of the current block's header-list in the
- * uppermost inner stack in tempStacks, and clear the headerStack up to
- * the beginning of the block.
- * Thus, the next future statement will think it comes one indent past
- * the block's '{' unless it specifically checks for a companion-header
- * (such as a previous 'if' for an 'else' header) within the tempStacks,
- * and recreates the temporary snapshot by manipulating the tempStacks.
- */
- if (!tempStacks->back()->empty())
- while (!tempStacks->back()->empty())
- tempStacks->back()->pop_back();
- while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACE)
- {
- tempStacks->back()->emplace_back(headerStack->back());
- headerStack->pop_back();
- }
- if (parenDepth == 0 && ch == ';')
- isContinuation = false;
- if (isInObjCMethodDefinition)
- {
- objCColonAlignSubsequent = 0;
- isImmediatelyPostObjCMethodDefinition = true;
- }
- previousLastLineHeader = nullptr;
- isInClassHeader = false; // for 'friend' class
- isInEnum = false;
- isInEnumTypeID = false;
- isInQuestion = false;
- isInTemplate = false;
- isInObjCInterface = false;
- foundPreCommandHeader = false;
- foundPreCommandMacro = false;
- squareBracketCount = 0;
- continue;
- }
- if (isPotentialHeader)
- {
- // check for preBlockStatements in C/C++ ONLY if not within parentheses
- // (otherwise 'struct XXX' statements would be wrongly interpreted...)
- if (!isInTemplate && !(isCStyle() && parenDepth > 0))
- {
- const string* newHeader = findHeader(line, i, preBlockStatements);
- // handle CORBA IDL module
- if (newHeader == &AS_MODULE)
- {
- char nextChar = peekNextChar(line, i + newHeader->length() - 1);
- if (prevNonSpaceCh == ')' || !isalpha(nextChar))
- newHeader = nullptr;
- }
- if (newHeader != nullptr
- && !(isCStyle() && newHeader == &AS_CLASS && isInEnum)) // is not 'enum class'
- {
- if (!isSharpStyle())
- headerStack->emplace_back(newHeader);
- // do not need 'where' in the headerStack
- // do not need second 'class' statement in a row
- else if (!(newHeader == &AS_WHERE
- || ((newHeader == &AS_CLASS || newHeader == &AS_STRUCT)
- && !headerStack->empty()
- && (headerStack->back() == &AS_CLASS
- || headerStack->back() == &AS_STRUCT))))
- headerStack->emplace_back(newHeader);
- if (!headerStack->empty())
- {
- if ((*headerStack).back() == &AS_CLASS
- || (*headerStack).back() == &AS_STRUCT
- || (*headerStack).back() == &AS_INTERFACE)
- {
- isInClassHeader = true;
- }
- else if ((*headerStack).back() == &AS_NAMESPACE
- || (*headerStack).back() == &AS_MODULE)
- {
- // remove continuationIndent from namespace
- if (!continuationIndentStack->empty())
- continuationIndentStack->pop_back();
- isContinuation = false;
- }
- }
- i += newHeader->length() - 1;
- continue;
- }
- }
- const string* foundIndentableHeader = findHeader(line, i, indentableHeaders);
- if (foundIndentableHeader != nullptr)
- {
- // must bypass the header before registering the in statement
- i += foundIndentableHeader->length() - 1;
- if (!isInOperator && !isInTemplate && !isNonInStatementArray)
- {
- registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, false);
- isContinuation = true;
- }
- continue;
- }
- if (isCStyle() && findKeyword(line, i, AS_OPERATOR))
- isInOperator = true;
- if (g_preprocessorCppExternCBrace == 1 && findKeyword(line, i, AS_EXTERN))
- ++g_preprocessorCppExternCBrace;
- if (g_preprocessorCppExternCBrace == 3) // extern "C" is not followed by a '{'
- g_preprocessorCppExternCBrace = 0;
- // "new" operator is a pointer, not a calculation
- if (findKeyword(line, i, AS_NEW))
- {
- if (isContinuation && !continuationIndentStack->empty() && prevNonSpaceCh == '=')
- continuationIndentStack->back() = 0;
- }
- if (isCStyle())
- {
- if (findKeyword(line, i, AS_ASM)
- || findKeyword(line, i, AS__ASM__))
- {
- isInAsm = true;
- }
- else if (findKeyword(line, i, AS_MS_ASM) // microsoft specific
- || findKeyword(line, i, AS_MS__ASM))
- {
- int index = 4;
- if (peekNextChar(line, i) == '_') // check for __asm
- index = 5;
- char peekedChar = peekNextChar(line, i + index);
- if (peekedChar == '{' || peekedChar == ' ')
- isInAsmBlock = true;
- else
- isInAsmOneLine = true;
- }
- }
- // bypass the entire name for all others
- string name = getCurrentWord(line, i);
- i += name.length() - 1;
- continue;
- }
- // Handle Objective-C statements
- if (ch == '@' && !isWhiteSpace(line[i + 1])
- && isCharPotentialHeader(line, i + 1))
- {
- string curWord = getCurrentWord(line, i + 1);
- if (curWord == AS_INTERFACE && headerStack->empty())
- {
- isInObjCInterface = true;
- string name = '@' + curWord;
- i += name.length() - 1;
- continue;
- }
- else if (isInObjCInterface)
- {
- --indentCount;
- isInObjCInterface = false;
- }
- if (curWord == AS_PUBLIC
- || curWord == AS_PRIVATE
- || curWord == AS_PROTECTED)
- {
- --indentCount;
- if (modifierIndent)
- spaceIndentCount += (indentLength / 2);
- string name = '@' + curWord;
- i += name.length() - 1;
- continue;
- }
- else if (curWord == AS_END)
- {
- popLastContinuationIndent();
- spaceIndentCount = 0;
- isInObjCMethodDefinition = false;
- string name = '@' + curWord;
- i += name.length() - 1;
- continue;
- }
- }
- else if ((ch == '-' || ch == '+')
- && peekNextChar(line, i) == '('
- && headerStack->empty()
- && line.find_first_not_of(" \t") == i)
- {
- if (isInObjCInterface)
- --indentCount;
- isInObjCInterface = false;
- isInObjCMethodDefinition = true;
- continue;
- }
- // Handle operators
- bool isPotentialOperator = isCharPotentialOperator(ch);
- if (isPotentialOperator)
- {
- // Check if an operator has been reached.
- const string* foundAssignmentOp = findOperator(line, i, assignmentOperators);
- const string* foundNonAssignmentOp = findOperator(line, i, nonAssignmentOperators);
- if (foundNonAssignmentOp != nullptr)
- {
- if (foundNonAssignmentOp == &AS_LAMBDA)
- foundPreCommandHeader = true;
- if (isInTemplate && foundNonAssignmentOp == &AS_GR_GR)
- foundNonAssignmentOp = nullptr;
- }
- // Since findHeader's boundary checking was not used above, it is possible
- // that both an assignment op and a non-assignment op where found,
- // e.g. '>>' and '>>='. If this is the case, treat the LONGER one as the
- // found operator.
- if (foundAssignmentOp != nullptr && foundNonAssignmentOp != nullptr)
- {
- if (foundAssignmentOp->length() < foundNonAssignmentOp->length())
- foundAssignmentOp = nullptr;
- else
- foundNonAssignmentOp = nullptr;
- }
- if (foundNonAssignmentOp != nullptr)
- {
- if (foundNonAssignmentOp->length() > 1)
- i += foundNonAssignmentOp->length() - 1;
- // For C++ input/output, operator<< and >> should be
- // aligned, if we are not in a statement already and
- // also not in the "operator<<(...)" header line
- if (!isInOperator
- && continuationIndentStack->empty()
- && isCStyle()
- && (foundNonAssignmentOp == &AS_GR_GR
- || foundNonAssignmentOp == &AS_LS_LS))
- {
- // this will be true if the line begins with the operator
- if (i < 2 && spaceIndentCount == 0)
- spaceIndentCount += 2 * indentLength;
- // align to the beginning column of the operator
- registerContinuationIndent(line, i - foundNonAssignmentOp->length(), spaceIndentCount, tabIncrementIn, 0, false);
- }
- }
- else if (foundAssignmentOp != nullptr)
- {
- foundPreCommandHeader = false; // clears this for array assignments
- foundPreCommandMacro = false;
- if (foundAssignmentOp->length() > 1)
- i += foundAssignmentOp->length() - 1;
- if (!isInOperator && !isInTemplate && (!isNonInStatementArray || isInEnum))
- {
- // if multiple assignments, align on the previous word
- if (foundAssignmentOp == &AS_ASSIGN
- && prevNonSpaceCh != ']' // an array
- && statementEndsWithComma(line, i))
- {
- if (!haveAssignmentThisLine) // only one assignment indent per line
- {
- // register indent at previous word
- haveAssignmentThisLine = true;
- int prevWordIndex = getContinuationIndentAssign(line, i);
- int continuationIndentCount = prevWordIndex + spaceIndentCount + tabIncrementIn;
- continuationIndentStack->emplace_back(continuationIndentCount);
- isContinuation = true;
- }
- }
- // don't indent an assignment if 'let'
- else if (isInLet)
- {
- isInLet = false;
- }
- else if (!lineBeginsWithComma)
- {
- if (i == 0 && spaceIndentCount == 0)
- spaceIndentCount += indentLength;
- registerContinuationIndent(line, i, spaceIndentCount, tabIncrementIn, 0, false);
- isContinuation = true;
- }
- }
- }
- }
- } // end of for loop * end of for loop * end of for loop * end of for loop * end of for loop *
- }
- } // end namespace astyle
|