Logo Search packages:      
Sourcecode: codeblocks version File versions  Download package

astyle_main.cpp

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *   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 <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <ctime>

#ifndef ASTYLE_LIB             // for console build only
#if defined(_MSC_VER) || defined(__DMC__)
#include <sys/utime.h>
#include <sys/stat.h>
//#define utimbuf  _utimbuf
//#define utime    _utime
#else
#include <utime.h>
#include <sys/stat.h>
#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<typename T>
class ASStreamIterator :
                  public ASSourceIterator
{
      public:
            ASStreamIterator(T *in);
            virtual ~ASStreamIterator();
            bool hasMoreLines() const;
            string nextLine();

      private:
            T * inStream;
            string buffer;
            bool inStreamEOF;
};

template<typename T>
ASStreamIterator<T>::ASStreamIterator(T *in)
{
      inStream = in;
      buffer.reserve(200);
      inStreamEOF = false;
}


template<typename T>
ASStreamIterator<T>::~ASStreamIterator()
{
}


template<typename T>
bool ASStreamIterator<T>::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<typename T>
string ASStreamIterator<T>::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<typename ITER>
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<string> &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 <vector> 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<string> 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<istringstream> 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<string> fileNameVector;
      vector<string> 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<string> 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<istream> 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<istream> 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   *****************************************

Generated by  Doxygen 1.6.0   Back to index