/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * astyle_main.cpp * * This file is a part of "Artistic Style" - an indentation and * reformatting tool for C, C++, C# and Java source files. * http://astyle.sourceforge.net * * The "Artistic Style" project, including all files needed to * compile it, is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this project; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "astyle.h" #include #include #include #include #include #ifndef ASTYLE_LIB // for console build only #if defined(_MSC_VER) || defined(__DMC__) #include #include //#define utimbuf _utimbuf //#define utime _utime #else #include #include #endif // end compiler checks #endif // end ASTYLE_LIB // for G++ implementation of string.compare: // compare((str), (place), (length)) instead of compare(place, length, str) #if defined(__GNUC__) && __GNUC__ < 3 #error - Use GNU C compiler release 3 or higher #endif // for namespace problem in version 5.0 #if defined(_MSC_VER) && _MSC_VER < 1200 // check for V6.0 #error - Use Microsoft compiler version 6 or higher #endif #ifdef _WIN32 #define STDCALL __stdcall #define EXPORT __declspec(dllexport) #else #define STDCALL #define EXPORT #endif #define IS_OPTION(arg,op) ((arg).compare(op)==0) #define IS_OPTIONS(arg,a,b) (IS_OPTION((arg),(a)) || IS_OPTION((arg),(b))) #define GET_PARAM(arg,op) ((arg).substr(strlen(op))) #define GET_PARAMS(arg,a,b) (isParamOption((arg),(a)) ? GET_PARAM((arg),(a)) : GET_PARAM((arg),(b))) using namespace astyle; const char* _version = "1.21"; // some compilers want this declared bool parseOption(ASFormatter &formatter, const string &arg, const string &errorInfo); #ifdef ASTYLE_LIB // GUI function pointers typedef void (STDCALL *fpError)(int, char*); // pointer to callback error handler typedef char* (STDCALL *fpAlloc)(unsigned long); // pointer to callback memory allocation // GUI variables stringstream *_err = NULL; #else // console variables ostream *_err = &cerr; bool _purgeOrigIn = false; bool _preserveDate = false; string _suffix = ".orig"; stringstream _msg; // info messages are not printed until a file is read #endif bool _modeManuallySet = false; // typename will be istringstream for GUI and istream otherwise template class ASStreamIterator : public ASSourceIterator { public: ASStreamIterator(T *in); virtual ~ASStreamIterator(); bool hasMoreLines() const; string nextLine(); private: T * inStream; string buffer; bool inStreamEOF; }; template ASStreamIterator::ASStreamIterator(T *in) { inStream = in; buffer.reserve(200); inStreamEOF = false; } template ASStreamIterator::~ASStreamIterator() { } template bool ASStreamIterator::hasMoreLines() const { return !inStreamEOF; } /** * read the input stream, delete any end of line characters, * and build a string that contains the input line. * * @return string containing the next input line minus any end of line characters */ template string ASStreamIterator::nextLine() { char ch; char LF = '\n'; char CR = '\r'; inStream->get(ch); buffer.clear(); while (!inStream->eof() && ch != LF && ch != CR) { buffer.append(1, ch); inStream->get(ch); } if (inStream->eof()) { inStreamEOF = true; return buffer; } int peekch = inStream->peek(); if (ch == CR) // CR+LF is windows otherwise Mac OS 9 { if (peekch == LF) { inStream->get(); eolWindows++; } else eolMacOld++; } else // LF is Linux, allow for improbable LF/CR { if (peekch == CR) { inStream->get(); eolWindows++; } else eolLinux++; } // set output end of line character if (eolWindows >= eolLinux) if (eolWindows >= eolMacOld) strcpy(outputEOL, "\r\n"); // Windows (CR+LF) else strcpy(outputEOL, "\r"); // MacOld (CR) else if (eolLinux >= eolMacOld) strcpy(outputEOL, "\n"); // Linux (LF) else strcpy(outputEOL, "\r"); // MacOld (CR) return buffer; } template bool parseOptions(ASFormatter &formatter, const ITER &optionsBegin, const ITER &optionsEnd, const string &errorInfo) { ITER option; bool ok = true; string arg, subArg; for (option = optionsBegin; option != optionsEnd; ++option) { arg = *option; if (arg.compare(0, 2, "--") == 0) ok &= parseOption(formatter, arg.substr(2), errorInfo); else if (arg[0] == '-') { size_t i; for (i = 1; i < arg.length(); ++i) { if (isalpha(arg[i]) && i > 1) { ok &= parseOption(formatter, subArg, errorInfo); subArg = ""; } subArg.append(1, arg[i]); } ok &= parseOption(formatter, subArg, errorInfo); subArg = ""; } else { ok &= parseOption(formatter, arg, errorInfo); subArg = ""; } } return ok; } void importOptions(istream &in, vector &optionsVector) { char ch; string currentToken; while (in) { currentToken = ""; do { in.get(ch); if (in.eof()) break; // treat '#' as line comments if (ch == '#') while (in) { in.get(ch); if (ch == '\n') break; } // break options on spaces, tabs or new-lines if (in.eof() || ch == ' ' || ch == '\t' || ch == '\n') break; else currentToken.append(1, ch); } while (in); if (currentToken.length() != 0) optionsVector.push_back(currentToken); } } bool isParamOption(const string &arg, const char *option) { bool retVal = arg.compare(0, strlen(option), option) == 0; // if comparing for short option, 2nd char of arg must be numeric if (retVal && strlen(option) == 1 && arg.length() > 1) if (!isdigit(arg[1])) retVal = false; return retVal; } void isOptionError(const string &arg, const string &errorInfo) { #ifdef ASTYLE_LIB if (_err->str().length() == 0) { (*_err) << errorInfo << endl; // need main error message (*_err) << arg; // output the option in error } else (*_err) << endl << arg; // put endl after previous option #else if (errorInfo.length() > 0) // to avoid a compiler warning (*_err) << "Error in param: " << arg << endl; #endif } bool isParamOption(const string &arg, const char *option1, const char *option2) { return isParamOption(arg, option1) || isParamOption(arg, option2); } bool parseOption(ASFormatter &formatter, const string &arg, const string &errorInfo) { if ( IS_OPTION(arg, "style=ansi") ) { formatter.setSpaceIndentation(4); formatter.setBracketFormatMode(BREAK_MODE); formatter.setBracketIndent(false); formatter.setClassIndent(false); formatter.setSwitchIndent(false); formatter.setNamespaceIndent(false); } else if ( IS_OPTION(arg, "style=gnu") ) { formatter.setSpaceIndentation(2); formatter.setBracketFormatMode(BREAK_MODE); formatter.setBlockIndent(true); formatter.setClassIndent(false); formatter.setSwitchIndent(false); formatter.setNamespaceIndent(false); } else if ( IS_OPTION(arg, "style=java") ) { // formatter.setJavaStyle(); // _modeManuallySet = true; formatter.setSpaceIndentation(4); formatter.setBracketFormatMode(ATTACH_MODE); formatter.setBracketIndent(false); formatter.setSwitchIndent(false); } else if ( IS_OPTION(arg, "style=kr") ) { //manuallySetCStyle(formatter); formatter.setSpaceIndentation(4); formatter.setBracketFormatMode(ATTACH_MODE); formatter.setBracketIndent(false); formatter.setClassIndent(false); formatter.setSwitchIndent(false); formatter.setNamespaceIndent(false); } else if ( IS_OPTION(arg, "style=linux") ) { formatter.setSpaceIndentation(8); formatter.setBracketFormatMode(BDAC_MODE); formatter.setBracketIndent(false); formatter.setClassIndent(false); formatter.setSwitchIndent(false); formatter.setNamespaceIndent(false); } // must check for mode=cs before mode=c !!! else if ( IS_OPTION(arg, "mode=cs") ) { formatter.setSharpStyle(); _modeManuallySet = true; } else if ( IS_OPTION(arg, "mode=c") ) { formatter.setCStyle(); _modeManuallySet = true; } else if ( IS_OPTION(arg, "mode=java") ) { formatter.setJavaStyle(); _modeManuallySet = true; } else if ( isParamOption(arg, "t", "indent=tab=") ) { int spaceNum = 4; string spaceNumParam = GET_PARAMS(arg, "t", "indent=tab="); if (spaceNumParam.length() > 0) spaceNum = atoi(spaceNumParam.c_str()); if (spaceNum < 2 || spaceNum > 20) isOptionError(arg, errorInfo); else formatter.setTabIndentation(spaceNum, false); } else if ( isParamOption(arg, "T", "force-indent=tab=") ) { int spaceNum = 4; string spaceNumParam = GET_PARAMS(arg, "T", "force-indent=tab="); if (spaceNumParam.length() > 0) spaceNum = atoi(spaceNumParam.c_str()); if (spaceNum < 2 || spaceNum > 20) isOptionError(arg, errorInfo); else formatter.setTabIndentation(spaceNum, true); } else if ( IS_OPTION(arg, "indent=tab") ) { formatter.setTabIndentation(4); } else if ( isParamOption(arg, "s", "indent=spaces=") ) { int spaceNum = 4; string spaceNumParam = GET_PARAMS(arg, "s", "indent=spaces="); if (spaceNumParam.length() > 0) spaceNum = atoi(spaceNumParam.c_str()); if (spaceNum < 2 || spaceNum > 20) isOptionError(arg, errorInfo); else formatter.setSpaceIndentation(spaceNum); } else if ( IS_OPTION(arg, "indent=spaces") ) { formatter.setSpaceIndentation(4); } else if ( isParamOption(arg, "m", "min-conditional-indent=") ) { int minIndent = 8; string minIndentParam = GET_PARAMS(arg, "m", "min-conditional-indent="); if (minIndentParam.length() > 0) minIndent = atoi(minIndentParam.c_str()); if (minIndent > 40) isOptionError(arg, errorInfo); else formatter.setMinConditionalIndentLength(minIndent); } else if ( isParamOption(arg, "M", "max-instatement-indent=") ) { int maxIndent = 40; string maxIndentParam = GET_PARAMS(arg, "M", "max-instatement-indent="); if (maxIndentParam.length() > 0) maxIndent = atoi(maxIndentParam.c_str()); if (maxIndent > 80) isOptionError(arg, errorInfo); else formatter.setMaxInStatementIndentLength(maxIndent); } else if ( IS_OPTIONS(arg, "B", "indent-brackets") ) { formatter.setBracketIndent(true); } else if ( IS_OPTIONS(arg, "G", "indent-blocks") ) { formatter.setBlockIndent(true); } else if ( IS_OPTIONS(arg, "N", "indent-namespaces") ) { formatter.setNamespaceIndent(true); } else if ( IS_OPTIONS(arg, "C", "indent-classes") ) { formatter.setClassIndent(true); } else if ( IS_OPTIONS(arg, "S", "indent-switches") ) { formatter.setSwitchIndent(true); } else if ( IS_OPTIONS(arg, "K", "indent-cases") ) { formatter.setCaseIndent(true); } else if ( IS_OPTIONS(arg, "L", "indent-labels") ) { formatter.setLabelIndent(true); } else if ( IS_OPTIONS(arg, "y", "brackets=break-closing") ) { formatter.setBreakClosingHeaderBracketsMode(true); } else if ( IS_OPTIONS(arg, "b", "brackets=break") ) { formatter.setBracketFormatMode(BREAK_MODE); } else if ( IS_OPTIONS(arg, "a", "brackets=attach") ) { formatter.setBracketFormatMode(ATTACH_MODE); } else if ( IS_OPTIONS(arg, "l", "brackets=linux") ) { formatter.setBracketFormatMode(BDAC_MODE); } else if ( IS_OPTIONS(arg, "O", "one-line=keep-blocks") ) { formatter.setBreakOneLineBlocksMode(false); } else if ( IS_OPTIONS(arg, "o", "one-line=keep-statements") ) { formatter.setSingleStatementsMode(false); } else if ( IS_OPTIONS(arg, "P", "pad=paren") ) { formatter.setParensOutsidePaddingMode(true); formatter.setParensInsidePaddingMode(true); } else if ( IS_OPTIONS(arg, "d", "pad=paren-out") ) { formatter.setParensOutsidePaddingMode(true); } else if ( IS_OPTIONS(arg, "D", "pad=paren-in") ) { formatter.setParensInsidePaddingMode(true); } else if ( IS_OPTIONS(arg, "U", "unpad=paren") ) { formatter.setParensUnPaddingMode(true); } else if ( IS_OPTIONS(arg, "p", "pad=oper") ) { formatter.setOperatorPaddingMode(true); } else if ( IS_OPTIONS(arg, "E", "fill-empty-lines") ) { formatter.setEmptyLineFill(true); } else if ( IS_OPTIONS(arg, "w", "indent-preprocessor") ) { formatter.setPreprocessorIndent(true); } else if ( IS_OPTIONS(arg, "V", "convert-tabs") ) { formatter.setTabSpaceConversionMode(true); } else if ( IS_OPTIONS(arg, "F", "break-blocks=all") ) { formatter.setBreakBlocksMode(true); formatter.setBreakClosingHeaderBlocksMode(true); } else if ( IS_OPTIONS(arg, "f", "break-blocks") ) { formatter.setBreakBlocksMode(true); } else if ( IS_OPTIONS(arg, "e", "break-elseifs") ) { formatter.setBreakElseIfsMode(true); } #ifdef ASTYLE_LIB // End of options used by GUI else isOptionError(arg, errorInfo); #else // Options used by only console else if ( IS_OPTIONS(arg, "n", "suffix=none") ) { _purgeOrigIn = true; } else if ( isParamOption(arg, "suffix=") ) { string suffixParam = GET_PARAM(arg, "suffix="); if (suffixParam.length() > 0) { _suffix = suffixParam; // if (_suffix[0] != '.') // _suffix = '.' + _suffix; } } else if ( IS_OPTIONS(arg, "Z", "preserve-date") ) { _preserveDate =true; } else if ( IS_OPTIONS(arg, "X", "errors-to-stdout") ) { _err = &cout; } else if ( IS_OPTIONS(arg, "v", "version") ) { (*_err) << "Artistic Style " << _version << endl; exit(0); } else { (*_err) << errorInfo << arg << endl; return false; // unknown option } #endif // End of parseOption function return true; //o.k. } #ifdef ASTYLE_LIB // ************************* GUI functions ***************************************************** /* * IMPORTANT VC DLL linker must have the parameter /EXPORT:AStyleMain=_AStyleMain@16 * /EXPORT:AStyleGetVersion=_AStyleGetVersion@0 * For Dll only - "warning C4702: unreachable code" in the header * is caused by using the Optimization options. * /O2 Maximize speed * /O1 Minimize size * /Ob2 Inline Expansion * This is a bug in the Microsoft compiler. The program runs about twice as fast * with the options set. There haven't been any problems so far. */ extern "C" EXPORT char* STDCALL AStyleMain(const char* pSourceIn, // pointer to the source to be formatted const char* pOptions, // pointer to AStyle options, separated by \n fpError fpErrorHandler, // pointer to error handler function fpAlloc fpMemoryAlloc) // pointer to memory allocation function { if (fpErrorHandler == NULL) // cannot display a message if no error handler return NULL; if (pSourceIn == NULL) { fpErrorHandler(101, "No pointer to source input"); return NULL; } if (pOptions == NULL) { fpErrorHandler(102, "No pointer to AStyle options"); return NULL; } if (fpMemoryAlloc == NULL) { fpErrorHandler(103, "No pointer to memory allocation function"); return NULL; } ASFormatter formatter; string arg; vector optionsVector; istringstream opt(pOptions); _err = new stringstream; _modeManuallySet = false; importOptions(opt, optionsVector); parseOptions(formatter, optionsVector.begin(), optionsVector.end(), "Unknown Artistic Style options\n" "The following options were not processed:"); if (_err->str().length() > 0) fpErrorHandler(210, (char*) _err->str().c_str()); delete _err; _err = NULL; istringstream in(pSourceIn); ASStreamIterator streamIterator(&in); ostringstream out; formatter.init(&streamIterator); while (formatter.hasMoreLines()) { out << formatter.nextLine(); out << streamIterator.outputEOL; } unsigned long textSizeOut = out.str().length(); char* pTextOut = fpMemoryAlloc(textSizeOut + 1); // call memory allocation function // pTextOut = NULL; // for testing if (pTextOut == NULL) { fpErrorHandler(110, "Allocation failure on output"); return NULL; } strcpy(pTextOut, out.str().c_str()); return pTextOut; } extern "C" EXPORT const char* STDCALL AStyleGetVersion (void) { return _version; } #else void preserveFileDate(const char *oldFileName, const char *newFileName) { struct stat stBuf; bool statErr = false; if (stat (oldFileName, &stBuf) == -1) statErr = true; else { struct utimbuf outBuf; outBuf.actime = stBuf.st_atime; // add 1 so RCS will recoginze a change outBuf.modtime = stBuf.st_mtime + 1; if (utime (newFileName, &outBuf) == -1) statErr = true; } if (statErr) (*_err) << " Could not preserve file date" << endl; } bool stringEndsWith(const string &str, const string &suffix) { int strIndex = (int) str.length() - 1; int suffixIndex = (int) suffix.length() - 1; while (strIndex >= 0 && suffixIndex >= 0) { if (tolower(str[strIndex]) != tolower(suffix[suffixIndex])) return false; --strIndex; --suffixIndex; } return true; } void error(const char *why, const char* what) { (*_err) << why << ' ' << what << '\n' << endl; exit(1); } void printHelp() { (*_err) << endl; (*_err) << " Artistic Style " << _version << endl; (*_err) << " Maintained by: Jim Pattee\n"; (*_err) << " Original Author: Tal Davidson\n"; (*_err) << endl; (*_err) << "Usage : astyle [options] Source1.cpp Source2.cpp [...]\n"; (*_err) << " astyle [options] < Original > Beautified\n"; (*_err) << endl; (*_err) << "When indenting a specific file, the resulting indented file RETAINS the\n"; (*_err) << "original file-name. The original pre-indented file is renamed, with a\n"; (*_err) << "suffix of \".orig\" added to the original filename.\n"; (*_err) << endl; (*_err) << "By default, astyle is set up to indent C/C++/C#/Java files, with 4 spaces\n"; (*_err) << "per indent, a maximal indentation of 40 spaces inside continuous statements,\n"; (*_err) << "and NO formatting.\n"; (*_err) << endl; (*_err) << "Option's Format:\n"; (*_err) << "----------------\n"; (*_err) << " Long options (starting with '--') must be written one at a time.\n"; (*_err) << " Short options (starting with '-') may be appended together.\n"; (*_err) << " Thus, -bps4 is the same as -b -p -s4.\n"; (*_err) << endl; (*_err) << "Predefined Style Options:\n"; (*_err) << "-------------------------\n"; (*_err) << " --style=ansi\n"; (*_err) << " ANSI style formatting/indenting.\n"; (*_err) << endl; (*_err) << " --style=gnu\n"; (*_err) << " GNU style formatting/indenting.\n"; (*_err) << endl; (*_err) << " --style=kr\n"; (*_err) << " Kernighan&Ritchie style formatting/indenting.\n"; (*_err) << endl; (*_err) << " --style=linux\n"; (*_err) << " Linux mode (8 spaces per indent, break definition-block\n"; (*_err) << " brackets but attach command-block brackets).\n"; (*_err) << endl; (*_err) << " --style=java\n"; (*_err) << " Java mode, with standard java style formatting/indenting.\n"; (*_err) << endl; (*_err) << "Tab and Bracket Options:\n"; (*_err) << "------------------------\n"; (*_err) << " default indent option\n"; (*_err) << " If no indentation option is set,\n"; (*_err) << " the default option of 4 spaces will be used.\n"; (*_err) << endl; (*_err) << " --indent=spaces=# OR -s#\n"; (*_err) << " Indent using # spaces per indent. Not specifying #\n"; (*_err) << " will result in a default of 4 spaces per indent.\n"; (*_err) << endl; (*_err) << " --indent=tab OR --indent=tab=# OR -t OR -t#\n"; (*_err) << " Indent using tab characters, assuming that each\n"; (*_err) << " tab is # spaces long. Not specifying # will result\n"; (*_err) << " in a default assumption of 4 spaces per tab.\n"; (*_err) << endl; (*_err) << " --force-indent=tab=# OR -T#\n"; (*_err) << " Indent using tab characters, assuming that each\n"; (*_err) << " tab is # spaces long. Force tabs to be used in areas\n"; (*_err) << " Astyle would prefer to use spaces.\n"; (*_err) << endl; (*_err) << " default brackets option\n"; (*_err) << " If no brackets option is set,\n"; (*_err) << " the brackets will not be changed.\n"; (*_err) << endl; (*_err) << " --brackets=break OR -b\n"; (*_err) << " Break brackets from pre-block code (i.e. ANSI C/C++ style).\n"; (*_err) << endl; (*_err) << " --brackets=attach OR -a\n"; (*_err) << " Attach brackets to pre-block code (i.e. Java/K&R style).\n"; (*_err) << endl; (*_err) << " --brackets=linux OR -l\n"; (*_err) << " Break definition-block brackets and attach command-block\n"; (*_err) << " brackets.\n"; (*_err) << endl; (*_err) << " --brackets=break-closing OR -y\n"; (*_err) << " Break brackets before closing headers (e.g. 'else', 'catch', ...).\n"; (*_err) << " Should be appended to --brackets=attach or --brackets=linux.\n"; (*_err) << endl; (*_err) << "Indentation options:\n"; (*_err) << "--------------------\n"; (*_err) << " --indent-classes OR -C\n"; (*_err) << " Indent 'class' blocks, so that the inner 'public:',\n"; (*_err) << " 'protected:' and 'private: headers are indented in\n"; (*_err) << " relation to the class block.\n"; (*_err) << endl; (*_err) << " --indent-switches OR -S\n"; (*_err) << " Indent 'switch' blocks, so that the inner 'case XXX:'\n"; (*_err) << " headers are indented in relation to the switch block.\n"; (*_err) << endl; (*_err) << " --indent-cases OR -K\n"; (*_err) << " Indent case blocks from the 'case XXX:' headers.\n"; (*_err) << " Case statements not enclosed in blocks are NOT indented.\n"; (*_err) << endl; (*_err) << " --indent-brackets OR -B\n"; (*_err) << " Add extra indentation to '{' and '}' block brackets.\n"; (*_err) << endl; (*_err) << " --indent-blocks OR -G\n"; (*_err) << " Add extra indentation entire blocks (including brackets).\n"; (*_err) << endl; (*_err) << " --indent-namespaces OR -N\n"; (*_err) << " Indent the contents of namespace blocks.\n"; (*_err) << endl; (*_err) << " --indent-labels OR -L\n"; (*_err) << " Indent labels so that they appear one indent less than\n"; (*_err) << " the current indentation level, rather than being\n"; (*_err) << " flushed completely to the left (which is the default).\n"; (*_err) << endl; (*_err) << " --indent-preprocessor OR -w\n"; (*_err) << " Indent multi-line #define statements.\n"; (*_err) << endl; (*_err) << " --max-instatement-indent=# OR -M#\n"; (*_err) << " Indent a maximal # spaces in a continuous statement,\n"; (*_err) << " relative to the previous line.\n"; (*_err) << endl; (*_err) << " --min-conditional-indent=# OR -m#\n"; (*_err) << " Indent a minimal # spaces in a continuous conditional\n"; (*_err) << " belonging to a conditional header.\n"; (*_err) << endl; (*_err) << "Formatting options:\n"; (*_err) << "-------------------\n"; (*_err) << " --break-blocks OR -f\n"; (*_err) << " Insert empty lines around unrelated blocks, labels, classes, ...\n"; (*_err) << endl; (*_err) << " --break-blocks=all OR -F\n"; (*_err) << " Like --break-blocks, except also insert empty lines \n"; (*_err) << " around closing headers (e.g. 'else', 'catch', ...).\n"; (*_err) << endl; (*_err) << " --break-elseifs OR -e\n"; (*_err) << " Break 'else if()' statements into two different lines.\n"; (*_err) << endl; (*_err) << " --pad=oper OR -p\n"; (*_err) << " Insert space paddings around operators.\n"; (*_err) << endl; (*_err) << " --pad=paren OR -P\n"; (*_err) << " Insert space padding around parenthesis on both the outside\n"; (*_err) << " and the inside.\n"; (*_err) << endl; (*_err) << " --pad=paren-out OR -d\n"; (*_err) << " Insert space padding around parenthesis on the outside only.\n"; (*_err) << endl; (*_err) << " --pad=paren-in OR -D\n"; (*_err) << " Insert space padding around parenthesis on the inside only.\n"; (*_err) << endl; (*_err) << " --unpad=paren OR -U\n"; (*_err) << " Remove unnecessary space padding around parenthesis. This\n"; (*_err) << " can be used in combination with the 'pad' options above.\n"; (*_err) << endl; (*_err) << " --one-line=keep-statements OR -o\n"; (*_err) << " Don't break lines containing multiple statements into\n"; (*_err) << " multiple single-statement lines.\n"; (*_err) << endl; (*_err) << " --one-line=keep-blocks OR -O\n"; (*_err) << " Don't break blocks residing completely on one line.\n"; (*_err) << endl; (*_err) << " --convert-tabs OR -V\n"; (*_err) << " Convert tabs to spaces.\n"; (*_err) << endl; (*_err) << " --fill-empty-lines OR -E\n"; (*_err) << " Fill empty lines with the white space of their\n"; (*_err) << " previous lines.\n"; (*_err) << endl; (*_err) << " --mode=c OR -c\n"; (*_err) << " Indent a C, C++ or C# source file (this is the default).\n"; (*_err) << endl; (*_err) << " --mode=java OR -j\n"; (*_err) << " Indent a Java(TM) source file.\n"; (*_err) << endl; (*_err) << "Other options:\n"; (*_err) << "--------------\n"; (*_err) << " --suffix=####\n"; (*_err) << " Append the suffix #### instead of '.orig' to original filename.\n"; (*_err) << endl; (*_err) << " --suffix=none OR -n\n"; (*_err) << " Do not retain a backup of the original file.\n"; (*_err) << endl; (*_err) << " --options=####\n"; (*_err) << " Specify an options file #### to read and use.\n"; (*_err) << endl; (*_err) << " --options=none\n"; (*_err) << " Disable the default options file.\n"; (*_err) << " Only the command-line parameters will be used.\n"; (*_err) << endl; (*_err) << " --preserve-date OR -Z\n"; (*_err) << " The date and time modified will not be changed in the formatted file.\n"; (*_err) << endl; (*_err) << " --errors-to-stdout OR -X\n"; (*_err) << " Print errors and help information to standard-output rather than\n"; (*_err) << " to standard-error.\n"; (*_err) << endl; (*_err) << " --version OR -v\n"; (*_err) << " Print version number.\n"; (*_err) << endl; (*_err) << " --help OR -h OR -?\n"; (*_err) << " Print this help message.\n"; (*_err) << endl; (*_err) << "Default options file:\n"; (*_err) << "---------------------\n"; (*_err) << " Artistic Style looks for a default options file in the\n"; (*_err) << " following order:\n"; (*_err) << " 1. The contents of the ARTISTIC_STYLE_OPTIONS environment\n"; (*_err) << " variable if it exists.\n"; (*_err) << " 2. The file called .astylerc in the directory pointed to by the\n"; (*_err) << " HOME environment variable ( i.e. $HOME/.astylerc ).\n"; (*_err) << " 3. The file called astylerc in the directory pointed to by the\n"; (*_err) << " USERPROFILE environment variable ( i.e. %USERPROFILE%\\astylerc ).\n"; (*_err) << " If a default options file is found, the options in this file\n"; (*_err) << " will be parsed BEFORE the command-line options.\n"; (*_err) << " Long options within the default option file may be written without\n"; (*_err) << " the preliminary '--'.\n"; (*_err) << endl; } int main(int argc, char *argv[]) { ASFormatter formatter; vector fileNameVector; vector optionsVector; string optionsFileName = ""; string arg; bool ok = true; bool shouldPrintHelp = false; bool shouldParseOptionsFile = true; _modeManuallySet = false; _msg << "\nArtistic Style " << _version << endl; // manage flags for (int i = 1; i < argc; i++) { arg = string(argv[i]); if ( IS_OPTION(arg, "--options=none") ) { shouldParseOptionsFile = false; } else if ( isParamOption(arg, "--options=") ) { optionsFileName = GET_PARAM(arg, "--options="); } else if ( IS_OPTION(arg, "-h") || IS_OPTION(arg, "--help") || IS_OPTION(arg, "-?") ) { shouldPrintHelp = true; } else if (arg[0] == '-') { optionsVector.push_back(arg); } else // file-name { fileNameVector.push_back(arg); } } // parse options file if (shouldParseOptionsFile) { if (optionsFileName.compare("") == 0) { char* env = getenv("ARTISTIC_STYLE_OPTIONS"); if (env != NULL) optionsFileName = string(env); } if (optionsFileName.compare("") == 0) { char* env = getenv("HOME"); if (env != NULL) optionsFileName = string(env) + string("/.astylerc"); } if (optionsFileName.compare("") == 0) { char* env = getenv("USERPROFILE"); if (env != NULL) optionsFileName = string(env) + string("/astylerc"); } if (optionsFileName.compare("") != 0) { ifstream optionsIn(optionsFileName.c_str()); if (optionsIn) { _msg << "Using default options file " << optionsFileName << endl; vector fileOptionsVector; importOptions(optionsIn, fileOptionsVector); ok = parseOptions(formatter, fileOptionsVector.begin(), fileOptionsVector.end(), string("Unknown option in default options file: ")); } optionsIn.close(); if (!ok) { (*_err) << "For help on options, type 'astyle -h' " << endl; } } } // parse options from command line ok = parseOptions(formatter, optionsVector.begin(), optionsVector.end(), string("Unknown command line option: ")); if (!ok) { (*_err) << "For help on options, type 'astyle -h' \n" << endl; exit(1); } if (shouldPrintHelp) { printHelp(); exit(0); } // if no files have been given, use cin for input and cout for output // this is used to format text for text editors like TextWrangler // do NOT display any console messages when this branch is used if (fileNameVector.empty()) { ASStreamIterator streamIterator(&cin); formatter.init(&streamIterator); while (formatter.hasMoreLines()) { cout << formatter.nextLine(); if (formatter.hasMoreLines()) cout << streamIterator.outputEOL; } cout.flush(); } else { // indent the given files cout << _msg.str().c_str(); clock_t startTime = clock(); for (size_t i = 0; i < fileNameVector.size(); i++) { string originalFileName = fileNameVector[i]; string inFileName = originalFileName + _suffix; remove(inFileName.c_str()); // remove the old .orig if present // check if the file is present before rename ifstream inCheck(originalFileName.c_str()); if (!inCheck) error("Could not open input file", originalFileName.c_str()); inCheck.close(); if (rename(originalFileName.c_str(), inFileName.c_str()) < 0) error("Could not rename ", string(originalFileName + " to " + inFileName).c_str()); ifstream in(inFileName.c_str(), ios::binary); if (!in) error("Could not open input file", inFileName.c_str()); ofstream out(originalFileName.c_str(), ios::binary); if (!out) error("Could not open output file", originalFileName.c_str()); // Unless a specific language mode has been, set the language mode // according to the file's suffix. if (!_modeManuallySet) { if (stringEndsWith(originalFileName, string(".java"))) formatter.setJavaStyle(); else if (stringEndsWith(originalFileName, string(".cs"))) formatter.setSharpStyle(); else formatter.setCStyle(); } // display file formatting message and save the filename cout << "formatting " << originalFileName.c_str() << endl; size_t fname = originalFileName.find_last_of("/\\"); if (fname == string::npos) fname = 0; else fname +=1; formatter.fileName = originalFileName.substr(fname); ASStreamIterator streamIterator(&in); formatter.init(&streamIterator); while (formatter.hasMoreLines()) { out << formatter.nextLine(); // the last line does not get an eol if (formatter.hasMoreLines()) out << streamIterator.outputEOL; } out.flush(); out.close(); in.close(); // change date modified to original file date if (_preserveDate) preserveFileDate(inFileName.c_str(), originalFileName.c_str()); if (_purgeOrigIn) remove(inFileName.c_str()); } // all files formatted clock_t stopTime = clock(); float secs = (float) (stopTime - startTime) / CLOCKS_PER_SEC; // show tenths of a second if time is less than 20 seconds cout.precision(2); if (secs >= 100 || (secs >= 10 && secs < 20)) cout.precision(3); cout << "total time " << secs << " seconds" << endl; cout.precision(0); cout << endl; } return 0; } #endif // ************************* end of console functions *****************************************