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.
9 //----------------------------------------------------------------------------
11 //----------------------------------------------------------------------------
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
26 #include <sys/utime.h>
31 #endif // end compiler checks
35 #ifndef ASTYLE_LIB // ASTYLE_LIB must be defined for ASTYLE_JNI
41 // for console build only
42 #include "ASLocalizer.h"
43 #define _(a) localizer.settext(a)
46 //-----------------------------------------------------------------------------
48 //-----------------------------------------------------------------------------
50 // for G++ implementation of string.compare:
51 #if defined(__GNUC__) && __GNUC__ < 3
52 #error - Use GNU C compiler release 3 or higher
55 // for getenv and localtime
57 #pragma warning(disable: 4996) // secure version deprecation warnings
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
66 #pragma clang diagnostic ignored "-Wdeprecated-declarations" // getenv, localtime
67 #pragma clang diagnostic ignored "-Wmissing-braces"
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
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
85 #define STDCALL __stdcall
87 // define this to prevent compiler warning and error messages
88 #ifdef ASTYLE_NO_EXPORT
91 #define EXPORT __declspec(dllexport)
93 // define STDCALL and EXPORT for non-Windows
94 // visibility attribute allows "-fvisibility=hidden" compiler option
98 #define EXPORT __attribute__ ((visibility ("default")))
102 #endif // #ifdef _WIN32
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);
110 #endif // #ifdef ASTYLE_LIB
112 //----------------------------------------------------------------------------
114 //----------------------------------------------------------------------------
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 //----------------------------------------------------------------------------
125 class ASStreamIterator : public ASSourceIterator
128 bool checkForEmptyLine;
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();
138 void saveLastInputLine();
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
155 public: // inline functions
156 bool compareToInputBuffer(const string& nextLine_) const
157 { return (nextLine_ == prevBuffer); }
158 const string& getOutputEOL() const { return outputEOL; }
159 bool hasMoreLines() const { return !inStream->eof(); }
162 //----------------------------------------------------------------------------
163 // ASEncoding class for utf8/16 conversions
164 // used by both console and library builds
165 //----------------------------------------------------------------------------
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 };
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;
191 //----------------------------------------------------------------------------
192 // ASOptions class for options processing
193 // used by both console and library builds
194 //----------------------------------------------------------------------------
201 ASOptions(ASFormatter& formatterArg);
203 ASOptions(ASFormatter& formatterArg, ASConsole& consoleArg);
205 string getOptionErrors() const;
206 void importOptions(istream& in, vector<string>& optionsVector);
207 bool parseOptions(vector<string>& optionsVector, const string& errorInfo);
211 ASFormatter& formatter;
212 stringstream optionErrors; // option error messages
214 ASConsole& console; // DO NOT USE for ASTYLE_LIB
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);
232 //----------------------------------------------------------------------------
233 // ASConsole class for console build
234 //----------------------------------------------------------------------------
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
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
264 ASEncoding utf8_16; // utf8/16 conversion methods
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
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
283 explicit ASConsole(ASFormatter& formatterArg);
285 void convertLineEnds(ostringstream& out, int lineEnd);
286 FileEncoding detectEncoding(const char* data, size_t dataSize) 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;
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;
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;
368 void displayLastError();
373 //----------------------------------------------------------------------------
374 // ASLibrary class for library build
375 //----------------------------------------------------------------------------
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;
388 static char* STDCALL tempMemoryAllocation(unsigned long memoryNeeded);
391 ASEncoding utf8_16; // utf8/16 conversion methods
396 //----------------------------------------------------------------------------
398 } // end of namespace astyle
400 //----------------------------------------------------------------------------
401 // declarations for java native interface (JNI) build
402 // they are called externally and are NOT part of the namespace
403 //----------------------------------------------------------------------------
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
409 jstring STDCALL Java_AStyleInterface_AStyleGetVersion(JNIEnv* env, jclass);
411 jstring STDCALL Java_AStyleInterface_AStyleMain(JNIEnv* env,
414 jstring optionsJava);
417 //----------------------------------------------------------------------------
418 // declarations for UTF-16 interface
419 // they are called externally and are NOT part of the namespace
420 //----------------------------------------------------------------------------
423 utf16_t* STDCALL AStyleMainUtf16(const utf16_t* pSourceIn,
424 const utf16_t* pOptions,
425 fpError fpErrorHandler,
426 fpAlloc fpMemoryAlloc);
429 //-----------------------------------------------------------------------------
430 // declarations for standard DLL interface
431 // they are called externally and are NOT part of the namespace
432 //-----------------------------------------------------------------------------
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);
441 //-----------------------------------------------------------------------------
443 #endif // closes ASTYLE_MAIN_H