1 // astyle_main.h 2 // Copyright (c) 2017 by Jim Pattee <jimp03@email.com>. 3 // This code is licensed under the MIT License. 4 // License.md describes the conditions under which this software may be distributed. 5 6 #ifndef ASTYLE_MAIN_H 7 #define ASTYLE_MAIN_H 8 9 //---------------------------------------------------------------------------- 10 // headers 11 //---------------------------------------------------------------------------- 12 13 #include "astyle.h" 14 15 #include <sstream> 16 #include <ctime> 17 18 #if defined(__BORLANDC__) && __BORLANDC__ < 0x0650 19 // Embarcadero needs this for the following utime.h 20 // otherwise "struct utimbuf" gets an error on time_t 21 // 0x0650 for C++Builder XE3 22 using std::time_t; 23 #endif 24 25 #if defined(_MSC_VER) 26 #include <sys/utime.h> 27 #include <sys/stat.h> 28 #else 29 #include <utime.h> 30 #include <sys/stat.h> 31 #endif // end compiler checks 32 33 #ifdef ASTYLE_JNI 34 #include <jni.h> 35 #ifndef ASTYLE_LIB // ASTYLE_LIB must be defined for ASTYLE_JNI 36 #define ASTYLE_LIB 37 #endif 38 #endif // ASTYLE_JNI 39 40 #ifndef ASTYLE_LIB 41 // for console build only 42 #include "ASLocalizer.h" 43 #define _(a) localizer.settext(a) 44 #endif // ASTYLE_LIB 45 46 //----------------------------------------------------------------------------- 47 // declarations 48 //----------------------------------------------------------------------------- 49 50 // for G++ implementation of string.compare: 51 #if defined(__GNUC__) && __GNUC__ < 3 52 #error - Use GNU C compiler release 3 or higher 53 #endif 54 55 // for getenv and localtime 56 #if defined(_MSC_VER) 57 #pragma warning(disable: 4996) // secure version deprecation warnings 58 #endif 59 60 // for namespace problem in version 5.0 61 #if defined(_MSC_VER) && _MSC_VER < 1200 // check for V6.0 62 #error - Use Microsoft compiler version 6 or higher 63 #endif 64 65 #ifdef __clang__ 66 #pragma clang diagnostic ignored "-Wdeprecated-declarations" // getenv, localtime 67 #pragma clang diagnostic ignored "-Wmissing-braces" 68 #endif 69 70 // for mingw BOM, UTF-16, and Unicode functions 71 #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) 72 #if (__MINGW32_MAJOR_VERSION > 3) || \ 73 ((__MINGW32_MAJOR_VERSION == 3) && (__MINGW32_MINOR_VERSION < 16)) 74 #error - Use MinGW compiler version 4 or higher 75 #endif 76 #endif 77 78 #ifdef ASTYLE_LIB 79 80 // define STDCALL and EXPORT for Windows 81 // MINGW defines STDCALL in Windows.h (actually windef.h) 82 // EXPORT has no value if ASTYLE_NO_EXPORT is defined 83 #ifdef _WIN32 84 #ifndef STDCALL 85 #define STDCALL __stdcall 86 #endif 87 // define this to prevent compiler warning and error messages 88 #ifdef ASTYLE_NO_EXPORT 89 #define EXPORT 90 #else 91 #define EXPORT __declspec(dllexport) 92 #endif 93 // define STDCALL and EXPORT for non-Windows 94 // visibility attribute allows "-fvisibility=hidden" compiler option 95 #else 96 #define STDCALL 97 #if __GNUC__ >= 4 98 #define EXPORT __attribute__ ((visibility ("default"))) 99 #else 100 #define EXPORT 101 #endif 102 #endif // #ifdef _WIN32 103 104 // define utf-16 bit text for the platform 105 typedef unsigned short utf16_t; 106 // define pointers to callback error handler and memory allocation 107 typedef void (STDCALL* fpError)(int errorNumber, const char* errorMessage); 108 typedef char* (STDCALL* fpAlloc)(unsigned long memoryNeeded); 109 110 #endif // #ifdef ASTYLE_LIB 111 112 //---------------------------------------------------------------------------- 113 // astyle namespace 114 //---------------------------------------------------------------------------- 115 116 namespace astyle { 117 // 118 //---------------------------------------------------------------------------- 119 // ASStreamIterator class 120 // typename will be istringstream for GUI and istream otherwise 121 // ASSourceIterator is an abstract class defined in astyle.h 122 //---------------------------------------------------------------------------- 123 124 template<typename T> 125 class ASStreamIterator : public ASSourceIterator 126 { 127 public: 128 bool checkForEmptyLine; 129 130 // function declarations 131 explicit ASStreamIterator(T* in); 132 virtual ~ASStreamIterator(); 133 bool getLineEndChange(int lineEndFormat) const; 134 int getStreamLength() const; 135 string nextLine(bool emptyLineWasDeleted); 136 string peekNextLine(); 137 void peekReset(); 138 void saveLastInputLine(); 139 streamoff tellg(); 140 141 private: 142 ASStreamIterator(const ASStreamIterator& copy); // copy constructor not to be implemented 143 ASStreamIterator& operator=(ASStreamIterator&); // assignment operator not to be implemented 144 T* inStream; // pointer to the input stream 145 string buffer; // current input line 146 string prevBuffer; // previous input line 147 string outputEOL; // next output end of line char 148 int eolWindows; // number of Windows line endings, CRLF 149 int eolLinux; // number of Linux line endings, LF 150 int eolMacOld; // number of old Mac line endings. CR 151 streamoff streamLength; // length of the input file stream 152 streamoff peekStart; // starting position for peekNextLine 153 bool prevLineDeleted; // the previous input line was deleted 154 155 public: // inline functions compareToInputBuffer(const string & nextLine_)156 bool compareToInputBuffer(const string& nextLine_) const 157 { return (nextLine_ == prevBuffer); } getOutputEOL()158 const string& getOutputEOL() const { return outputEOL; } hasMoreLines()159 bool hasMoreLines() const { return !inStream->eof(); } 160 }; 161 162 //---------------------------------------------------------------------------- 163 // ASEncoding class for utf8/16 conversions 164 // used by both console and library builds 165 //---------------------------------------------------------------------------- 166 167 class ASEncoding 168 { 169 private: 170 typedef unsigned short utf16; // 16 bits 171 typedef unsigned char utf8; // 8 bits 172 typedef unsigned char ubyte; // 8 bits 173 enum { SURROGATE_LEAD_FIRST = 0xD800 }; 174 enum { SURROGATE_LEAD_LAST = 0xDBFF }; 175 enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; 176 enum { SURROGATE_TRAIL_LAST = 0xDFFF }; 177 enum { SURROGATE_FIRST_VALUE = 0x10000 }; 178 enum eState { eStart, eSecondOf4Bytes, ePenultimate, eFinal }; 179 180 public: 181 bool getBigEndian() const; 182 int swap16bit(int value) const; 183 size_t utf16len(const utf16* utf16In) const; 184 size_t utf8LengthFromUtf16(const char* utf16In, size_t inLen, bool isBigEndian) const; 185 size_t utf8ToUtf16(char* utf8In, size_t inLen, bool isBigEndian, char* utf16Out) const; 186 size_t utf16LengthFromUtf8(const char* utf8In, size_t len) const; 187 size_t utf16ToUtf8(char* utf16In, size_t inLen, bool isBigEndian, 188 bool firstBlock, char* utf8Out) const; 189 }; 190 191 //---------------------------------------------------------------------------- 192 // ASOptions class for options processing 193 // used by both console and library builds 194 //---------------------------------------------------------------------------- 195 class ASConsole; 196 197 class ASOptions 198 { 199 public: 200 #ifdef ASTYLE_LIB 201 ASOptions(ASFormatter& formatterArg); 202 #else 203 ASOptions(ASFormatter& formatterArg, ASConsole& consoleArg); 204 #endif 205 string getOptionErrors() const; 206 void importOptions(istream& in, vector<string>& optionsVector); 207 bool parseOptions(vector<string>& optionsVector, const string& errorInfo); 208 209 private: 210 // variables 211 ASFormatter& formatter; 212 stringstream optionErrors; // option error messages 213 #ifndef ASTYLE_LIB 214 ASConsole& console; // DO NOT USE for ASTYLE_LIB 215 #endif 216 217 // functions 218 ASOptions(const ASOptions&); // copy constructor not to be implemented 219 ASOptions& operator=(ASOptions&); // assignment operator not to be implemented 220 string getParam(const string& arg, const char* op); 221 string getParam(const string& arg, const char* op1, const char* op2); 222 bool isOption(const string& arg, const char* op); 223 bool isOption(const string& arg, const char* op1, const char* op2); 224 void isOptionError(const string& arg, const string& errorInfo); 225 bool isParamOption(const string& arg, const char* option); 226 bool isParamOption(const string& arg, const char* option1, const char* option2); 227 void parseOption(const string& arg, const string& errorInfo); 228 }; 229 230 #ifndef ASTYLE_LIB 231 232 //---------------------------------------------------------------------------- 233 // ASConsole class for console build 234 //---------------------------------------------------------------------------- 235 236 class ASConsole 237 { 238 private: // variables 239 ASFormatter& formatter; // reference to the ASFormatter object 240 ASLocalizer localizer; // ASLocalizer object 241 ostream* errorStream; // direct error messages to cerr or cout 242 // command line options 243 bool isRecursive; // recursive option 244 bool isDryRun; // dry-run option 245 bool noBackup; // suffix=none option 246 bool preserveDate; // preserve-date option 247 bool isVerbose; // verbose option 248 bool isQuiet; // quiet option 249 bool isFormattedOnly; // formatted lines only option 250 bool ignoreExcludeErrors; // don't abort on unmatched excludes 251 bool ignoreExcludeErrorsDisplay; // don't display unmatched excludes 252 bool optionsFileRequired; // options= option 253 bool useAscii; // ascii option 254 // other variables 255 bool bypassBrowserOpen; // don't open the browser on html options 256 bool hasWildcard; // file name includes a wildcard 257 size_t mainDirectoryLength; // directory length to be excluded in displays 258 bool filesAreIdentical; // input and output files are identical 259 int filesFormatted; // number of files formatted 260 int filesUnchanged; // number of files unchanged 261 bool lineEndsMixed; // output has mixed line ends 262 int linesOut; // number of output lines 263 264 ASEncoding utf8_16; // utf8/16 conversion methods 265 266 string outputEOL; // current line end 267 string prevEOL; // previous line end 268 string optionsFileName; // file path and name of the options file to use 269 string origSuffix; // suffix= option 270 string stdPathIn; // path to input from stdin= 271 string stdPathOut; // path to output from stdout= 272 string targetDirectory; // path to the directory being processed 273 string targetFilename; // file name being processed 274 275 vector<string> excludeVector; // exclude from wildcard hits 276 vector<bool> excludeHitsVector; // exclude flags for error reporting 277 vector<string> fileNameVector; // file paths and names from the command line 278 vector<string> optionsVector; // options from the command line 279 vector<string> fileOptionsVector; // options from the options file 280 vector<string> fileName; // files to be processed including path 281 282 public: // functions 283 explicit ASConsole(ASFormatter& formatterArg); 284 ~ASConsole(); 285 void convertLineEnds(ostringstream& out, int lineEnd); 286 FileEncoding detectEncoding(const char* data, size_t dataSize) const; 287 void error() const; 288 void error(const char* why, const char* what) const; 289 void formatCinToCout(); 290 vector<string> getArgvOptions(int argc, char** argv) const; 291 bool fileNameVectorIsEmpty() const; 292 ostream* getErrorStream() const; 293 bool getFilesAreIdentical() const; 294 int getFilesFormatted() const; 295 bool getIgnoreExcludeErrors() const; 296 bool getIgnoreExcludeErrorsDisplay() const; 297 bool getIsDryRun() const; 298 bool getIsFormattedOnly() const; 299 bool getIsQuiet() const; 300 bool getIsRecursive() const; 301 bool getIsVerbose() const; 302 bool getLineEndsMixed() const; 303 bool getNoBackup() const; 304 bool getPreserveDate() const; 305 string getLanguageID() const; 306 string getNumberFormat(int num, size_t lcid = 0) const; 307 string getNumberFormat(int num, const char* groupingArg, const char* separator) const; 308 string getOptionsFileName() const; 309 string getOrigSuffix() const; 310 string getStdPathIn() const; 311 string getStdPathOut() const; 312 void processFiles(); 313 void processOptions(const vector<string>& argvOptions); 314 void setBypassBrowserOpen(bool state); 315 void setErrorStream(ostream* errStreamPtr); 316 void setIgnoreExcludeErrors(bool state); 317 void setIgnoreExcludeErrorsAndDisplay(bool state); 318 void setIsDryRun(bool state); 319 void setIsFormattedOnly(bool state); 320 void setIsQuiet(bool state); 321 void setIsRecursive(bool state); 322 void setIsVerbose(bool state); 323 void setNoBackup(bool state); 324 void setOptionsFileName(const string& name); 325 void setOrigSuffix(const string& suffix); 326 void setPreserveDate(bool state); 327 void setStdPathIn(const string& path); 328 void setStdPathOut(const string& path); 329 void standardizePath(string& path, bool removeBeginningSeparator = false) const; 330 bool stringEndsWith(const string& str, const string& suffix) const; 331 void updateExcludeVector(const string& suffixParam); 332 vector<string> getExcludeVector() const; 333 vector<bool> getExcludeHitsVector() const; 334 vector<string> getFileNameVector() const; 335 vector<string> getOptionsVector() const; 336 vector<string> getFileOptionsVector() const; 337 vector<string> getFileName() const; 338 339 private: // functions 340 ASConsole(const ASConsole&); // copy constructor not to be implemented 341 ASConsole& operator=(ASConsole&); // assignment operator not to be implemented 342 void correctMixedLineEnds(ostringstream& out); 343 void formatFile(const string& fileName_); 344 string getCurrentDirectory(const string& fileName_) const; 345 void getFileNames(const string& directory, const string& wildcard); 346 void getFilePaths(const string& filePath); 347 string getParam(const string& arg, const char* op); 348 void initializeOutputEOL(LineEndFormat lineEndFormat); 349 bool isOption(const string& arg, const char* op); 350 bool isOption(const string& arg, const char* a, const char* b); 351 bool isParamOption(const string& arg, const char* option); 352 bool isPathExclued(const string& subPath); 353 void launchDefaultBrowser(const char* filePathIn = nullptr) const; 354 void printHelp() const; 355 void printMsg(const char* msg, const string& data) const; 356 void printSeparatingLine() const; 357 void printVerboseHeader() const; 358 void printVerboseStats(clock_t startTime) const; 359 FileEncoding readFile(const string& fileName_, stringstream& in) const; 360 void removeFile(const char* fileName_, const char* errMsg) const; 361 void renameFile(const char* oldFileName, const char* newFileName, const char* errMsg) const; 362 void setOutputEOL(LineEndFormat lineEndFormat, const string& currentEOL); 363 void sleep(int seconds) const; 364 int waitForRemove(const char* newFileName) const; 365 int wildcmp(const char* wild, const char* data) const; 366 void writeFile(const string& fileName_, FileEncoding encoding, ostringstream& out) const; 367 #ifdef _WIN32 368 void displayLastError(); 369 #endif 370 }; 371 #else // ASTYLE_LIB 372 373 //---------------------------------------------------------------------------- 374 // ASLibrary class for library build 375 //---------------------------------------------------------------------------- 376 377 class ASLibrary 378 { 379 public: ASLibrary()380 ASLibrary() {} ~ASLibrary()381 virtual ~ASLibrary() {} 382 // virtual functions are mocked in testing 383 utf16_t* formatUtf16(const utf16_t*, const utf16_t*, fpError, fpAlloc) const; 384 virtual utf16_t* convertUtf8ToUtf16(const char* utf8In, fpAlloc fpMemoryAlloc) const; 385 virtual char* convertUtf16ToUtf8(const utf16_t* utf16In) const; 386 387 private: 388 static char* STDCALL tempMemoryAllocation(unsigned long memoryNeeded); 389 390 private: 391 ASEncoding utf8_16; // utf8/16 conversion methods 392 }; 393 394 #endif // ASTYLE_LIB 395 396 //---------------------------------------------------------------------------- 397 398 } // end of namespace astyle 399 400 //---------------------------------------------------------------------------- 401 // declarations for java native interface (JNI) build 402 // they are called externally and are NOT part of the namespace 403 //---------------------------------------------------------------------------- 404 #ifdef ASTYLE_JNI 405 void STDCALL javaErrorHandler(int errorNumber, const char* errorMessage); 406 char* STDCALL javaMemoryAlloc(unsigned long memoryNeeded); 407 // the following function names are constructed from method names in the calling java program 408 extern "C" EXPORT 409 jstring STDCALL Java_cc_arduino_packages_formatter_AStyleInterface_AStyleGetVersion(JNIEnv* env, jclass); 410 extern "C" EXPORT 411 jstring STDCALL Java_cc_arduino_packages_formatter_AStyleInterface_AStyleMain(JNIEnv* env, 412 jobject obj, 413 jstring textInJava, 414 jstring optionsJava); 415 #endif // ASTYLE_JNI 416 417 //---------------------------------------------------------------------------- 418 // declarations for UTF-16 interface 419 // they are called externally and are NOT part of the namespace 420 //---------------------------------------------------------------------------- 421 #ifdef ASTYLE_LIB 422 extern "C" EXPORT 423 utf16_t* STDCALL AStyleMainUtf16(const utf16_t* pSourceIn, 424 const utf16_t* pOptions, 425 fpError fpErrorHandler, 426 fpAlloc fpMemoryAlloc); 427 #endif // ASTYLE_LIB 428 429 //----------------------------------------------------------------------------- 430 // declarations for standard DLL interface 431 // they are called externally and are NOT part of the namespace 432 //----------------------------------------------------------------------------- 433 #ifdef ASTYLE_LIB 434 extern "C" EXPORT char* STDCALL AStyleMain(const char* pSourceIn, 435 const char* pOptions, 436 fpError fpErrorHandler, 437 fpAlloc fpMemoryAlloc); 438 extern "C" EXPORT const char* STDCALL AStyleGetVersion(void); 439 #endif // ASTYLE_LIB 440 441 //----------------------------------------------------------------------------- 442 443 #endif // closes ASTYLE_MAIN_H 444