| 1 | // ASResource.cpp |
| 2 | // Copyright (c) 2018 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 | //----------------------------------------------------------------------------- |
| 7 | // headers |
| 8 | //----------------------------------------------------------------------------- |
| 9 | |
| 10 | #include "astyle.h" |
| 11 | #include <algorithm> |
| 12 | |
| 13 | //----------------------------------------------------------------------------- |
| 14 | // astyle namespace |
| 15 | //----------------------------------------------------------------------------- |
| 16 | |
| 17 | namespace astyle { |
| 18 | // |
| 19 | const string ASResource::_AS_EXCEPT = string("__except" ); |
| 20 | const string ASResource::_AS_FINALLY = string("__finally" ); |
| 21 | const string ASResource::_AS_TRY = string("__try" ); |
| 22 | const string ASResource::AS_ADD = string("add" ); |
| 23 | const string ASResource::AS_AUTO = string("auto" ); |
| 24 | const string ASResource::AS_AUTORELEASEPOOL = string("autoreleasepool" ); |
| 25 | const string ASResource::AS_CASE = string("case" ); |
| 26 | const string ASResource::AS_CATCH = string("catch" ); |
| 27 | const string ASResource::AS_CLASS = string("class" ); |
| 28 | const string ASResource::AS_CONST = string("const" ); |
| 29 | const string ASResource::AS_CONST_CAST = string("const_cast" ); |
| 30 | const string ASResource::AS_DEFAULT = string("default" ); |
| 31 | const string ASResource::AS_DELEGATE = string("delegate" ); |
| 32 | const string ASResource::AS_DELETE = string("delete" ); |
| 33 | const string ASResource::AS_DO = string("do" ); |
| 34 | const string ASResource::AS_DYNAMIC_CAST = string("dynamic_cast" ); |
| 35 | const string ASResource::AS_ELSE = string("else" ); |
| 36 | const string ASResource::AS_END = string("end" ); |
| 37 | const string ASResource::AS_ENUM = string("enum" ); |
| 38 | const string ASResource::AS_EXTERN = string("extern" ); |
| 39 | const string ASResource::AS_FINAL = string("final" ); |
| 40 | const string ASResource::AS_FINALLY = string("finally" ); |
| 41 | const string ASResource::AS_FIXED = string("fixed" ); |
| 42 | const string ASResource::AS_FOR = string("for" ); |
| 43 | const string ASResource::AS_FOREACH = string("foreach" ); |
| 44 | const string ASResource::AS_FOREVER = string("forever" ); |
| 45 | const string ASResource::AS_GET = string("get" ); |
| 46 | const string ASResource::AS_IF = string("if" ); |
| 47 | const string ASResource::AS_INTERFACE = string("interface" ); |
| 48 | const string ASResource::AS_INTERRUPT = string("interrupt" ); |
| 49 | const string ASResource::AS_LET = string("let" ); |
| 50 | const string ASResource::AS_LOCK = string("lock" ); |
| 51 | const string ASResource::AS_MODULE = string("module" ); // CORBA IDL module definition |
| 52 | const string ASResource::AS_NAMESPACE = string("namespace" ); |
| 53 | const string ASResource::AS_NEW = string("new" ); |
| 54 | const string ASResource::AS_NOEXCEPT = string("noexcept" ); |
| 55 | const string ASResource::AS_NS_DURING = string("NS_DURING" ); |
| 56 | const string ASResource::AS_NS_HANDLER = string("NS_HANDLER" ); |
| 57 | const string ASResource::AS_OPERATOR = string("operator" ); |
| 58 | const string ASResource::AS_OVERRIDE = string("override" ); |
| 59 | const string ASResource::AS_PRIVATE = string("private" ); |
| 60 | const string ASResource::AS_PROTECTED = string("protected" ); |
| 61 | const string ASResource::AS_PUBLIC = string("public" ); |
| 62 | const string ASResource::AS_QFOREACH = string("Q_FOREACH" ); |
| 63 | const string ASResource::AS_QFOREVER = string("Q_FOREVER" ); |
| 64 | const string ASResource::AS_REINTERPRET_CAST = string("reinterpret_cast" ); |
| 65 | const string ASResource::AS_REMOVE = string("remove" ); |
| 66 | const string ASResource::AS_SEALED = string("sealed" ); |
| 67 | const string ASResource::AS_SELECTOR = string("selector" ); |
| 68 | const string ASResource::AS_SET = string("set" ); |
| 69 | const string ASResource::AS_STATIC = string("static" ); |
| 70 | const string ASResource::AS_STATIC_CAST = string("static_cast" ); |
| 71 | const string ASResource::AS_STRUCT = string("struct" ); |
| 72 | const string ASResource::AS_SWITCH = string("switch" ); |
| 73 | const string ASResource::AS_SYNCHRONIZED = string("synchronized" ); |
| 74 | const string ASResource::AS_TEMPLATE = string("template" ); |
| 75 | const string ASResource::AS_THROW = string("throw" ); |
| 76 | const string ASResource::AS_THROWS = string("throws" ); |
| 77 | const string ASResource::AS_TRY = string("try" ); |
| 78 | const string ASResource::AS_UNCHECKED = string("unchecked" ); |
| 79 | const string ASResource::AS_UNION = string("union" ); |
| 80 | const string ASResource::AS_UNSAFE = string("unsafe" ); |
| 81 | const string ASResource::AS_USING = string("using" ); |
| 82 | const string ASResource::AS_VOLATILE = string("volatile" ); |
| 83 | const string ASResource::AS_WHERE = string("where" ); |
| 84 | const string ASResource::AS_WHILE = string("while" ); |
| 85 | |
| 86 | const string ASResource::AS_ASM = string("asm" ); |
| 87 | const string ASResource::AS__ASM__ = string("__asm__" ); |
| 88 | const string ASResource::AS_MS_ASM = string("_asm" ); |
| 89 | const string ASResource::AS_MS__ASM = string("__asm" ); |
| 90 | |
| 91 | const string ASResource::AS_BAR_DEFINE = string("#define" ); |
| 92 | const string ASResource::AS_BAR_INCLUDE = string("#include" ); |
| 93 | const string ASResource::AS_BAR_IF = string("#if" ); |
| 94 | const string ASResource::AS_BAR_EL = string("#el" ); |
| 95 | const string ASResource::AS_BAR_ENDIF = string("#endif" ); |
| 96 | |
| 97 | const string ASResource::AS_OPEN_BRACE = string("{" ); |
| 98 | const string ASResource::AS_CLOSE_BRACE = string("}" ); |
| 99 | const string ASResource:: = string("//" ); |
| 100 | const string ASResource:: = string("/*" ); |
| 101 | const string ASResource:: = string("*/" ); |
| 102 | |
| 103 | const string ASResource::AS_ASSIGN = string("=" ); |
| 104 | const string ASResource::AS_PLUS_ASSIGN = string("+=" ); |
| 105 | const string ASResource::AS_MINUS_ASSIGN = string("-=" ); |
| 106 | const string ASResource::AS_MULT_ASSIGN = string("*=" ); |
| 107 | const string ASResource::AS_DIV_ASSIGN = string("/=" ); |
| 108 | const string ASResource::AS_MOD_ASSIGN = string("%=" ); |
| 109 | const string ASResource::AS_OR_ASSIGN = string("|=" ); |
| 110 | const string ASResource::AS_AND_ASSIGN = string("&=" ); |
| 111 | const string ASResource::AS_XOR_ASSIGN = string("^=" ); |
| 112 | const string ASResource::AS_GR_GR_ASSIGN = string(">>=" ); |
| 113 | const string ASResource::AS_LS_LS_ASSIGN = string("<<=" ); |
| 114 | const string ASResource::AS_GR_GR_GR_ASSIGN = string(">>>=" ); |
| 115 | const string ASResource::AS_LS_LS_LS_ASSIGN = string("<<<=" ); |
| 116 | const string ASResource::AS_GCC_MIN_ASSIGN = string("<?" ); |
| 117 | const string ASResource::AS_GCC_MAX_ASSIGN = string(">?" ); |
| 118 | |
| 119 | const string ASResource::AS_RETURN = string("return" ); |
| 120 | const string ASResource::AS_CIN = string("cin" ); |
| 121 | const string ASResource::AS_COUT = string("cout" ); |
| 122 | const string ASResource::AS_CERR = string("cerr" ); |
| 123 | |
| 124 | const string ASResource::AS_EQUAL = string("==" ); |
| 125 | const string ASResource::AS_PLUS_PLUS = string("++" ); |
| 126 | const string ASResource::AS_MINUS_MINUS = string("--" ); |
| 127 | const string ASResource::AS_NOT_EQUAL = string("!=" ); |
| 128 | const string ASResource::AS_GR_EQUAL = string(">=" ); |
| 129 | const string ASResource::AS_GR_GR = string(">>" ); |
| 130 | const string ASResource::AS_GR_GR_GR = string(">>>" ); |
| 131 | const string ASResource::AS_LS_EQUAL = string("<=" ); |
| 132 | const string ASResource::AS_LS_LS = string("<<" ); |
| 133 | const string ASResource::AS_LS_LS_LS = string("<<<" ); |
| 134 | const string ASResource::AS_QUESTION_QUESTION = string("??" ); |
| 135 | const string ASResource::AS_LAMBDA = string("=>" ); // C# lambda expression arrow |
| 136 | const string ASResource::AS_ARROW = string("->" ); |
| 137 | const string ASResource::AS_AND = string("&&" ); |
| 138 | const string ASResource::AS_OR = string("||" ); |
| 139 | const string ASResource::AS_SCOPE_RESOLUTION = string("::" ); |
| 140 | |
| 141 | const string ASResource::AS_PLUS = string("+" ); |
| 142 | const string ASResource::AS_MINUS = string("-" ); |
| 143 | const string ASResource::AS_MULT = string("*" ); |
| 144 | const string ASResource::AS_DIV = string("/" ); |
| 145 | const string ASResource::AS_MOD = string("%" ); |
| 146 | const string ASResource::AS_GR = string(">" ); |
| 147 | const string ASResource::AS_LS = string("<" ); |
| 148 | const string ASResource::AS_NOT = string("!" ); |
| 149 | const string ASResource::AS_BIT_OR = string("|" ); |
| 150 | const string ASResource::AS_BIT_AND = string("&" ); |
| 151 | const string ASResource::AS_BIT_NOT = string("~" ); |
| 152 | const string ASResource::AS_BIT_XOR = string("^" ); |
| 153 | const string ASResource::AS_QUESTION = string("?" ); |
| 154 | const string ASResource::AS_COLON = string(":" ); |
| 155 | const string ASResource::AS_COMMA = string("," ); |
| 156 | const string ASResource::AS_SEMICOLON = string(";" ); |
| 157 | |
| 158 | /** |
| 159 | * Sort comparison function. |
| 160 | * Compares the length of the value of pointers in the vectors. |
| 161 | * The LONGEST strings will be first in the vector. |
| 162 | * |
| 163 | * @param a and b, the string pointers to be compared. |
| 164 | */ |
| 165 | bool sortOnLength(const string* a, const string* b) |
| 166 | { |
| 167 | return (*a).length() > (*b).length(); |
| 168 | } |
| 169 | |
| 170 | /** |
| 171 | * Sort comparison function. |
| 172 | * Compares the value of pointers in the vectors. |
| 173 | * |
| 174 | * @param a and b, the string pointers to be compared. |
| 175 | */ |
| 176 | bool sortOnName(const string* a, const string* b) |
| 177 | { |
| 178 | return *a < *b; |
| 179 | } |
| 180 | |
| 181 | /** |
| 182 | * Build the vector of assignment operators. |
| 183 | * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp |
| 184 | * |
| 185 | * @param assignmentOperators a reference to the vector to be built. |
| 186 | */ |
| 187 | void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOperators) |
| 188 | { |
| 189 | const size_t elements = 15; |
| 190 | assignmentOperators->reserve(elements); |
| 191 | |
| 192 | assignmentOperators->emplace_back(&AS_ASSIGN); |
| 193 | assignmentOperators->emplace_back(&AS_PLUS_ASSIGN); |
| 194 | assignmentOperators->emplace_back(&AS_MINUS_ASSIGN); |
| 195 | assignmentOperators->emplace_back(&AS_MULT_ASSIGN); |
| 196 | assignmentOperators->emplace_back(&AS_DIV_ASSIGN); |
| 197 | assignmentOperators->emplace_back(&AS_MOD_ASSIGN); |
| 198 | assignmentOperators->emplace_back(&AS_OR_ASSIGN); |
| 199 | assignmentOperators->emplace_back(&AS_AND_ASSIGN); |
| 200 | assignmentOperators->emplace_back(&AS_XOR_ASSIGN); |
| 201 | |
| 202 | // Java |
| 203 | assignmentOperators->emplace_back(&AS_GR_GR_GR_ASSIGN); |
| 204 | assignmentOperators->emplace_back(&AS_GR_GR_ASSIGN); |
| 205 | assignmentOperators->emplace_back(&AS_LS_LS_ASSIGN); |
| 206 | |
| 207 | // Unknown |
| 208 | assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN); |
| 209 | |
| 210 | assert(assignmentOperators->size() < elements); |
| 211 | sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength); |
| 212 | } |
| 213 | |
| 214 | /** |
| 215 | * Build the vector of C++ cast operators. |
| 216 | * Used by ONLY ASFormatter.cpp |
| 217 | * |
| 218 | * @param castOperators a reference to the vector to be built. |
| 219 | */ |
| 220 | void ASResource::buildCastOperators(vector<const string*>* castOperators) |
| 221 | { |
| 222 | const size_t elements = 5; |
| 223 | castOperators->reserve(elements); |
| 224 | |
| 225 | castOperators->emplace_back(&AS_CONST_CAST); |
| 226 | castOperators->emplace_back(&AS_DYNAMIC_CAST); |
| 227 | castOperators->emplace_back(&AS_REINTERPRET_CAST); |
| 228 | castOperators->emplace_back(&AS_STATIC_CAST); |
| 229 | |
| 230 | assert(castOperators->size() < elements); |
| 231 | sort(castOperators->begin(), castOperators->end(), sortOnName); |
| 232 | } |
| 233 | |
| 234 | /** |
| 235 | * Build the vector of header words. |
| 236 | * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp |
| 237 | * |
| 238 | * @param headers a reference to the vector to be built. |
| 239 | */ |
| 240 | void ASResource::(vector<const string*>* , int fileType, bool beautifier) |
| 241 | { |
| 242 | const size_t elements = 25; |
| 243 | headers->reserve(elements); |
| 244 | |
| 245 | headers->emplace_back(&AS_IF); |
| 246 | headers->emplace_back(&AS_ELSE); |
| 247 | headers->emplace_back(&AS_FOR); |
| 248 | headers->emplace_back(&AS_WHILE); |
| 249 | headers->emplace_back(&AS_DO); |
| 250 | headers->emplace_back(&AS_SWITCH); |
| 251 | headers->emplace_back(&AS_CASE); |
| 252 | headers->emplace_back(&AS_DEFAULT); |
| 253 | headers->emplace_back(&AS_TRY); |
| 254 | headers->emplace_back(&AS_CATCH); |
| 255 | headers->emplace_back(&AS_QFOREACH); // QT |
| 256 | headers->emplace_back(&AS_QFOREVER); // QT |
| 257 | headers->emplace_back(&AS_FOREACH); // QT & C# |
| 258 | headers->emplace_back(&AS_FOREVER); // Qt & Boost |
| 259 | |
| 260 | if (fileType == C_TYPE) |
| 261 | { |
| 262 | headers->emplace_back(&_AS_TRY); // __try |
| 263 | headers->emplace_back(&_AS_FINALLY); // __finally |
| 264 | headers->emplace_back(&_AS_EXCEPT); // __except |
| 265 | } |
| 266 | if (fileType == JAVA_TYPE) |
| 267 | { |
| 268 | headers->emplace_back(&AS_FINALLY); |
| 269 | headers->emplace_back(&AS_SYNCHRONIZED); |
| 270 | } |
| 271 | |
| 272 | if (fileType == SHARP_TYPE) |
| 273 | { |
| 274 | headers->emplace_back(&AS_FINALLY); |
| 275 | headers->emplace_back(&AS_LOCK); |
| 276 | headers->emplace_back(&AS_FIXED); |
| 277 | headers->emplace_back(&AS_GET); |
| 278 | headers->emplace_back(&AS_SET); |
| 279 | headers->emplace_back(&AS_ADD); |
| 280 | headers->emplace_back(&AS_REMOVE); |
| 281 | headers->emplace_back(&AS_USING); |
| 282 | } |
| 283 | |
| 284 | if (beautifier) |
| 285 | { |
| 286 | if (fileType == C_TYPE) |
| 287 | { |
| 288 | headers->emplace_back(&AS_TEMPLATE); |
| 289 | } |
| 290 | |
| 291 | if (fileType == JAVA_TYPE) |
| 292 | { |
| 293 | headers->emplace_back(&AS_STATIC); // for static constructor |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | assert(headers->size() < elements); |
| 298 | sort(headers->begin(), headers->end(), sortOnName); |
| 299 | } |
| 300 | |
| 301 | /** |
| 302 | * Build the vector of indentable headers. |
| 303 | * Used by ONLY ASBeautifier.cpp |
| 304 | * |
| 305 | * @param indentableHeaders a reference to the vector to be built. |
| 306 | */ |
| 307 | void ASResource::(vector<const string*>* ) |
| 308 | { |
| 309 | indentableHeaders->emplace_back(&AS_RETURN); |
| 310 | |
| 311 | // sort(indentableHeaders->begin(), indentableHeaders->end(), sortOnName); |
| 312 | } |
| 313 | |
| 314 | /** |
| 315 | * Build the vector of indentable macros pairs. |
| 316 | * Initialized by ASFormatter, used by ONLY ASEnhancer.cpp |
| 317 | * |
| 318 | * @param indentableMacros a reference to the vector to be built. |
| 319 | */ |
| 320 | void ASResource::buildIndentableMacros(vector<const pair<const string, const string>* >* indentableMacros) |
| 321 | { |
| 322 | const size_t elements = 10; |
| 323 | indentableMacros->reserve(elements); |
| 324 | |
| 325 | // the pairs must be retained in memory because of pair pointers |
| 326 | using macro_pair = pair<const string, const string>; |
| 327 | static const macro_pair macros[] = |
| 328 | { |
| 329 | // wxWidgets |
| 330 | macro_pair("BEGIN_EVENT_TABLE" , "END_EVENT_TABLE" ), |
| 331 | macro_pair("wxBEGIN_EVENT_TABLE" , "wxEND_EVENT_TABLE" ), |
| 332 | // MFC |
| 333 | macro_pair("BEGIN_DISPATCH_MAP" , "END_DISPATCH_MAP" ), |
| 334 | macro_pair("BEGIN_EVENT_MAP" , "END_EVENT_MAP" ), |
| 335 | macro_pair("BEGIN_MESSAGE_MAP" , "END_MESSAGE_MAP" ), |
| 336 | macro_pair("BEGIN_PROPPAGEIDS" , "END_PROPPAGEIDS" ), |
| 337 | }; |
| 338 | |
| 339 | for (const macro_pair& macro : macros) |
| 340 | indentableMacros->emplace_back(¯o); |
| 341 | |
| 342 | assert(indentableMacros->size() < elements); |
| 343 | } |
| 344 | |
| 345 | /** |
| 346 | * Build the vector of non-assignment operators. |
| 347 | * Used by ONLY ASBeautifier.cpp |
| 348 | * |
| 349 | * @param nonAssignmentOperators a reference to the vector to be built. |
| 350 | */ |
| 351 | void ASResource::buildNonAssignmentOperators(vector<const string*>* nonAssignmentOperators) |
| 352 | { |
| 353 | const size_t elements = 15; |
| 354 | nonAssignmentOperators->reserve(elements); |
| 355 | |
| 356 | nonAssignmentOperators->emplace_back(&AS_EQUAL); |
| 357 | nonAssignmentOperators->emplace_back(&AS_PLUS_PLUS); |
| 358 | nonAssignmentOperators->emplace_back(&AS_MINUS_MINUS); |
| 359 | nonAssignmentOperators->emplace_back(&AS_NOT_EQUAL); |
| 360 | nonAssignmentOperators->emplace_back(&AS_GR_EQUAL); |
| 361 | nonAssignmentOperators->emplace_back(&AS_GR_GR_GR); |
| 362 | nonAssignmentOperators->emplace_back(&AS_GR_GR); |
| 363 | nonAssignmentOperators->emplace_back(&AS_LS_EQUAL); |
| 364 | nonAssignmentOperators->emplace_back(&AS_LS_LS_LS); |
| 365 | nonAssignmentOperators->emplace_back(&AS_LS_LS); |
| 366 | nonAssignmentOperators->emplace_back(&AS_ARROW); |
| 367 | nonAssignmentOperators->emplace_back(&AS_AND); |
| 368 | nonAssignmentOperators->emplace_back(&AS_OR); |
| 369 | nonAssignmentOperators->emplace_back(&AS_LAMBDA); |
| 370 | |
| 371 | assert(nonAssignmentOperators->size() < elements); |
| 372 | sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength); |
| 373 | } |
| 374 | |
| 375 | /** |
| 376 | * Build the vector of header non-paren headers. |
| 377 | * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp. |
| 378 | * NOTE: Non-paren headers should also be included in the headers vector. |
| 379 | * |
| 380 | * @param nonParenHeaders a reference to the vector to be built. |
| 381 | */ |
| 382 | void ASResource::(vector<const string*>* , int fileType, bool beautifier) |
| 383 | { |
| 384 | const size_t elements = 20; |
| 385 | nonParenHeaders->reserve(elements); |
| 386 | |
| 387 | nonParenHeaders->emplace_back(&AS_ELSE); |
| 388 | nonParenHeaders->emplace_back(&AS_DO); |
| 389 | nonParenHeaders->emplace_back(&AS_TRY); |
| 390 | nonParenHeaders->emplace_back(&AS_CATCH); // can be paren or non-paren |
| 391 | nonParenHeaders->emplace_back(&AS_CASE); // can be paren or non-paren |
| 392 | nonParenHeaders->emplace_back(&AS_DEFAULT); |
| 393 | nonParenHeaders->emplace_back(&AS_QFOREVER); // QT |
| 394 | nonParenHeaders->emplace_back(&AS_FOREVER); // Boost |
| 395 | |
| 396 | if (fileType == C_TYPE) |
| 397 | { |
| 398 | nonParenHeaders->emplace_back(&_AS_TRY); // __try |
| 399 | nonParenHeaders->emplace_back(&_AS_FINALLY); // __finally |
| 400 | } |
| 401 | if (fileType == JAVA_TYPE) |
| 402 | { |
| 403 | nonParenHeaders->emplace_back(&AS_FINALLY); |
| 404 | } |
| 405 | |
| 406 | if (fileType == SHARP_TYPE) |
| 407 | { |
| 408 | nonParenHeaders->emplace_back(&AS_FINALLY); |
| 409 | nonParenHeaders->emplace_back(&AS_GET); |
| 410 | nonParenHeaders->emplace_back(&AS_SET); |
| 411 | nonParenHeaders->emplace_back(&AS_ADD); |
| 412 | nonParenHeaders->emplace_back(&AS_REMOVE); |
| 413 | } |
| 414 | |
| 415 | if (beautifier) |
| 416 | { |
| 417 | if (fileType == C_TYPE) |
| 418 | { |
| 419 | nonParenHeaders->emplace_back(&AS_TEMPLATE); |
| 420 | } |
| 421 | if (fileType == JAVA_TYPE) |
| 422 | { |
| 423 | nonParenHeaders->emplace_back(&AS_STATIC); |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | assert(nonParenHeaders->size() < elements); |
| 428 | sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName); |
| 429 | } |
| 430 | |
| 431 | /** |
| 432 | * Build the vector of operators. |
| 433 | * Used by ONLY ASFormatter.cpp |
| 434 | * |
| 435 | * @param operators a reference to the vector to be built. |
| 436 | */ |
| 437 | void ASResource::buildOperators(vector<const string*>* operators, int fileType) |
| 438 | { |
| 439 | const size_t elements = 50; |
| 440 | operators->reserve(elements); |
| 441 | |
| 442 | operators->emplace_back(&AS_PLUS_ASSIGN); |
| 443 | operators->emplace_back(&AS_MINUS_ASSIGN); |
| 444 | operators->emplace_back(&AS_MULT_ASSIGN); |
| 445 | operators->emplace_back(&AS_DIV_ASSIGN); |
| 446 | operators->emplace_back(&AS_MOD_ASSIGN); |
| 447 | operators->emplace_back(&AS_OR_ASSIGN); |
| 448 | operators->emplace_back(&AS_AND_ASSIGN); |
| 449 | operators->emplace_back(&AS_XOR_ASSIGN); |
| 450 | operators->emplace_back(&AS_EQUAL); |
| 451 | operators->emplace_back(&AS_PLUS_PLUS); |
| 452 | operators->emplace_back(&AS_MINUS_MINUS); |
| 453 | operators->emplace_back(&AS_NOT_EQUAL); |
| 454 | operators->emplace_back(&AS_GR_EQUAL); |
| 455 | operators->emplace_back(&AS_GR_GR_GR_ASSIGN); |
| 456 | operators->emplace_back(&AS_GR_GR_ASSIGN); |
| 457 | operators->emplace_back(&AS_GR_GR_GR); |
| 458 | operators->emplace_back(&AS_GR_GR); |
| 459 | operators->emplace_back(&AS_LS_EQUAL); |
| 460 | operators->emplace_back(&AS_LS_LS_LS_ASSIGN); |
| 461 | operators->emplace_back(&AS_LS_LS_ASSIGN); |
| 462 | operators->emplace_back(&AS_LS_LS_LS); |
| 463 | operators->emplace_back(&AS_LS_LS); |
| 464 | operators->emplace_back(&AS_QUESTION_QUESTION); |
| 465 | operators->emplace_back(&AS_LAMBDA); |
| 466 | operators->emplace_back(&AS_ARROW); |
| 467 | operators->emplace_back(&AS_AND); |
| 468 | operators->emplace_back(&AS_OR); |
| 469 | operators->emplace_back(&AS_SCOPE_RESOLUTION); |
| 470 | operators->emplace_back(&AS_PLUS); |
| 471 | operators->emplace_back(&AS_MINUS); |
| 472 | operators->emplace_back(&AS_MULT); |
| 473 | operators->emplace_back(&AS_DIV); |
| 474 | operators->emplace_back(&AS_MOD); |
| 475 | operators->emplace_back(&AS_QUESTION); |
| 476 | operators->emplace_back(&AS_COLON); |
| 477 | operators->emplace_back(&AS_ASSIGN); |
| 478 | operators->emplace_back(&AS_LS); |
| 479 | operators->emplace_back(&AS_GR); |
| 480 | operators->emplace_back(&AS_NOT); |
| 481 | operators->emplace_back(&AS_BIT_OR); |
| 482 | operators->emplace_back(&AS_BIT_AND); |
| 483 | operators->emplace_back(&AS_BIT_NOT); |
| 484 | operators->emplace_back(&AS_BIT_XOR); |
| 485 | if (fileType == C_TYPE) |
| 486 | { |
| 487 | operators->emplace_back(&AS_GCC_MIN_ASSIGN); |
| 488 | operators->emplace_back(&AS_GCC_MAX_ASSIGN); |
| 489 | } |
| 490 | |
| 491 | assert(operators->size() < elements); |
| 492 | sort(operators->begin(), operators->end(), sortOnLength); |
| 493 | } |
| 494 | |
| 495 | /** |
| 496 | * Build the vector of pre-block statements. |
| 497 | * Used by ONLY ASBeautifier.cpp |
| 498 | * NOTE: Cannot be both a header and a preBlockStatement. |
| 499 | * |
| 500 | * @param preBlockStatements a reference to the vector to be built. |
| 501 | */ |
| 502 | void ASResource::buildPreBlockStatements(vector<const string*>* preBlockStatements, int fileType) |
| 503 | { |
| 504 | const size_t elements = 10; |
| 505 | preBlockStatements->reserve(elements); |
| 506 | |
| 507 | preBlockStatements->emplace_back(&AS_CLASS); |
| 508 | if (fileType == C_TYPE) |
| 509 | { |
| 510 | preBlockStatements->emplace_back(&AS_STRUCT); |
| 511 | preBlockStatements->emplace_back(&AS_UNION); |
| 512 | preBlockStatements->emplace_back(&AS_NAMESPACE); |
| 513 | preBlockStatements->emplace_back(&AS_MODULE); // for CORBA IDL |
| 514 | preBlockStatements->emplace_back(&AS_INTERFACE); // for CORBA IDL |
| 515 | } |
| 516 | if (fileType == JAVA_TYPE) |
| 517 | { |
| 518 | preBlockStatements->emplace_back(&AS_INTERFACE); |
| 519 | preBlockStatements->emplace_back(&AS_THROWS); |
| 520 | } |
| 521 | if (fileType == SHARP_TYPE) |
| 522 | { |
| 523 | preBlockStatements->emplace_back(&AS_INTERFACE); |
| 524 | preBlockStatements->emplace_back(&AS_NAMESPACE); |
| 525 | preBlockStatements->emplace_back(&AS_WHERE); |
| 526 | preBlockStatements->emplace_back(&AS_STRUCT); |
| 527 | } |
| 528 | |
| 529 | assert(preBlockStatements->size() < elements); |
| 530 | sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName); |
| 531 | } |
| 532 | |
| 533 | /** |
| 534 | * Build the vector of pre-command headers. |
| 535 | * Used by BOTH ASFormatter.cpp and ASBeautifier.cpp. |
| 536 | * NOTE: Cannot be both a header and a preCommandHeader. |
| 537 | * |
| 538 | * A preCommandHeader is in a function definition between |
| 539 | * the closing paren and the opening brace. |
| 540 | * e.g. in "void foo() const {}", "const" is a preCommandHeader. |
| 541 | */ |
| 542 | void ASResource::buildPreCommandHeaders(vector<const string*>* preCommandHeaders, int fileType) |
| 543 | { |
| 544 | const size_t elements = 10; |
| 545 | preCommandHeaders->reserve(elements); |
| 546 | |
| 547 | if (fileType == C_TYPE) |
| 548 | { |
| 549 | preCommandHeaders->emplace_back(&AS_CONST); |
| 550 | preCommandHeaders->emplace_back(&AS_FINAL); |
| 551 | preCommandHeaders->emplace_back(&AS_INTERRUPT); |
| 552 | preCommandHeaders->emplace_back(&AS_NOEXCEPT); |
| 553 | preCommandHeaders->emplace_back(&AS_OVERRIDE); |
| 554 | preCommandHeaders->emplace_back(&AS_VOLATILE); |
| 555 | preCommandHeaders->emplace_back(&AS_SEALED); // Visual C only |
| 556 | preCommandHeaders->emplace_back(&AS_AUTORELEASEPOOL); // Obj-C only |
| 557 | } |
| 558 | |
| 559 | if (fileType == JAVA_TYPE) |
| 560 | { |
| 561 | preCommandHeaders->emplace_back(&AS_THROWS); |
| 562 | } |
| 563 | |
| 564 | if (fileType == SHARP_TYPE) |
| 565 | { |
| 566 | preCommandHeaders->emplace_back(&AS_WHERE); |
| 567 | } |
| 568 | |
| 569 | assert(preCommandHeaders->size() < elements); |
| 570 | sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName); |
| 571 | } |
| 572 | |
| 573 | /** |
| 574 | * Build the vector of pre-definition headers. |
| 575 | * Used by ONLY ASFormatter.cpp |
| 576 | * NOTE: Do NOT add 'enum' here. It is an array type brace. |
| 577 | * NOTE: Do NOT add 'extern' here. Do not want an extra indent. |
| 578 | * |
| 579 | * @param preDefinitionHeaders a reference to the vector to be built. |
| 580 | */ |
| 581 | void ASResource::(vector<const string*>* , int fileType) |
| 582 | { |
| 583 | const size_t elements = 10; |
| 584 | preDefinitionHeaders->reserve(elements); |
| 585 | |
| 586 | preDefinitionHeaders->emplace_back(&AS_CLASS); |
| 587 | if (fileType == C_TYPE) |
| 588 | { |
| 589 | preDefinitionHeaders->emplace_back(&AS_STRUCT); |
| 590 | preDefinitionHeaders->emplace_back(&AS_UNION); |
| 591 | preDefinitionHeaders->emplace_back(&AS_NAMESPACE); |
| 592 | preDefinitionHeaders->emplace_back(&AS_MODULE); // for CORBA IDL |
| 593 | preDefinitionHeaders->emplace_back(&AS_INTERFACE); // for CORBA IDL |
| 594 | } |
| 595 | if (fileType == JAVA_TYPE) |
| 596 | { |
| 597 | preDefinitionHeaders->emplace_back(&AS_INTERFACE); |
| 598 | } |
| 599 | if (fileType == SHARP_TYPE) |
| 600 | { |
| 601 | preDefinitionHeaders->emplace_back(&AS_STRUCT); |
| 602 | preDefinitionHeaders->emplace_back(&AS_INTERFACE); |
| 603 | preDefinitionHeaders->emplace_back(&AS_NAMESPACE); |
| 604 | } |
| 605 | |
| 606 | assert(preDefinitionHeaders->size() < elements); |
| 607 | sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName); |
| 608 | } |
| 609 | |
| 610 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| 611 | * ASBase Functions |
| 612 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
| 613 | |
| 614 | // check if a specific line position contains a header. |
| 615 | const string* ASBase::(const string& line, int i, |
| 616 | const vector<const string*>* ) const |
| 617 | { |
| 618 | assert(isCharPotentialHeader(line, i)); |
| 619 | // check the word |
| 620 | size_t = possibleHeaders->size(); |
| 621 | for (size_t p = 0; p < maxHeaders; p++) |
| 622 | { |
| 623 | const string* = (*possibleHeaders)[p]; |
| 624 | const size_t wordEnd = i + header->length(); |
| 625 | if (wordEnd > line.length()) |
| 626 | continue; |
| 627 | int result = (line.compare(i, header->length(), *header)); |
| 628 | if (result > 0) |
| 629 | continue; |
| 630 | if (result < 0) |
| 631 | break; |
| 632 | // check that this is not part of a longer word |
| 633 | if (wordEnd == line.length()) |
| 634 | return header; |
| 635 | if (isLegalNameChar(line[wordEnd])) |
| 636 | continue; |
| 637 | const char peekChar = peekNextChar(line, wordEnd - 1); |
| 638 | // is not a header if part of a definition |
| 639 | if (peekChar == ',' || peekChar == ')') |
| 640 | break; |
| 641 | // the following accessor definitions are NOT headers |
| 642 | // goto default; is NOT a header |
| 643 | // default(int) keyword in C# is NOT a header |
| 644 | if ((header == &AS_GET |
| 645 | || header == &AS_SET |
| 646 | || header == &AS_DEFAULT) |
| 647 | && (peekChar == ';' || peekChar == '(' || peekChar == '=')) |
| 648 | break; |
| 649 | return header; |
| 650 | } |
| 651 | return nullptr; |
| 652 | } |
| 653 | |
| 654 | // check if a specific line position contains a keyword. |
| 655 | bool ASBase::findKeyword(const string& line, int i, const string& keyword) const |
| 656 | { |
| 657 | assert(isCharPotentialHeader(line, i)); |
| 658 | // check the word |
| 659 | const size_t keywordLength = keyword.length(); |
| 660 | const size_t wordEnd = i + keywordLength; |
| 661 | if (wordEnd > line.length()) |
| 662 | return false; |
| 663 | if (line.compare(i, keywordLength, keyword) != 0) |
| 664 | return false; |
| 665 | // check that this is not part of a longer word |
| 666 | if (wordEnd == line.length()) |
| 667 | return true; |
| 668 | if (isLegalNameChar(line[wordEnd])) |
| 669 | return false; |
| 670 | // is not a keyword if part of a definition |
| 671 | const char peekChar = peekNextChar(line, (int) wordEnd - 1); |
| 672 | if (peekChar == ',' || peekChar == ')') |
| 673 | return false; |
| 674 | return true; |
| 675 | } |
| 676 | |
| 677 | // check if a specific line position contains an operator. |
| 678 | const string* ASBase::findOperator(const string& line, int i, |
| 679 | const vector<const string*>* possibleOperators) const |
| 680 | { |
| 681 | assert(isCharPotentialOperator(line[i])); |
| 682 | // find the operator in the vector |
| 683 | // the vector contains the LONGEST operators first |
| 684 | // must loop thru the entire vector |
| 685 | size_t maxOperators = possibleOperators->size(); |
| 686 | for (size_t p = 0; p < maxOperators; p++) |
| 687 | { |
| 688 | const size_t wordEnd = i + (*(*possibleOperators)[p]).length(); |
| 689 | if (wordEnd > line.length()) |
| 690 | continue; |
| 691 | if (line.compare(i, (*(*possibleOperators)[p]).length(), *(*possibleOperators)[p]) == 0) |
| 692 | return (*possibleOperators)[p]; |
| 693 | } |
| 694 | return nullptr; |
| 695 | } |
| 696 | |
| 697 | // get the current word on a line |
| 698 | // index must point to the beginning of the word |
| 699 | string ASBase::getCurrentWord(const string& line, size_t index) const |
| 700 | { |
| 701 | assert(isCharPotentialHeader(line, index)); |
| 702 | size_t lineLength = line.length(); |
| 703 | size_t i; |
| 704 | for (i = index; i < lineLength; i++) |
| 705 | { |
| 706 | if (!isLegalNameChar(line[i])) |
| 707 | break; |
| 708 | } |
| 709 | return line.substr(index, i - index); |
| 710 | } |
| 711 | |
| 712 | // check if a specific character can be used in a legal variable/method/class name |
| 713 | bool ASBase::isLegalNameChar(char ch) const |
| 714 | { |
| 715 | if (isWhiteSpace(ch)) |
| 716 | return false; |
| 717 | // if ((unsigned char) ch > 127) |
| 718 | // return false; |
| 719 | if ((unsigned char) ch > 127) |
| 720 | return true; |
| 721 | return (isalnum((unsigned char) ch) |
| 722 | || ch == '.' || ch == '_' |
| 723 | || (isJavaStyle() && ch == '$') |
| 724 | || (isSharpStyle() && ch == '@')); // may be used as a prefix |
| 725 | } |
| 726 | |
| 727 | // check if a specific character can be part of a header |
| 728 | bool ASBase::(const string& line, size_t i) const |
| 729 | { |
| 730 | assert(!isWhiteSpace(line[i])); |
| 731 | char prevCh = ' '; |
| 732 | if (i > 0) |
| 733 | prevCh = line[i - 1]; |
| 734 | if (i > 1 && line[i - 2] == '\\') |
| 735 | prevCh = ' '; |
| 736 | if (!isLegalNameChar(prevCh) && isLegalNameChar(line[i])) |
| 737 | return true; |
| 738 | return false; |
| 739 | } |
| 740 | |
| 741 | // check if a specific character can be part of an operator |
| 742 | bool ASBase::isCharPotentialOperator(char ch) const |
| 743 | { |
| 744 | assert(!isWhiteSpace(ch)); |
| 745 | if ((unsigned) ch > 127) |
| 746 | return false; |
| 747 | return (ispunct((unsigned char) ch) |
| 748 | && ch != '{' && ch != '}' |
| 749 | && ch != '(' && ch != ')' |
| 750 | && ch != '[' && ch != ']' |
| 751 | && ch != ';' && ch != ',' |
| 752 | && ch != '#' && ch != '\\' |
| 753 | && ch != '\'' && ch != '\"'); |
| 754 | } |
| 755 | |
| 756 | // check if a specific character is a digit |
| 757 | // NOTE: Visual C isdigit() gives assert error if char > 256 |
| 758 | bool ASBase::isDigit(char ch) const |
| 759 | { |
| 760 | return (ch >= '0' && ch <= '9'); |
| 761 | } |
| 762 | |
| 763 | // check if a specific character is a digit separator |
| 764 | bool ASBase::isDigitSeparator(const string& line, int i) const |
| 765 | { |
| 766 | assert(line[i] == '\''); |
| 767 | // casting to (unsigned char) eliminates negative characters |
| 768 | // will get a "Debug Assertion Failed" if not cast |
| 769 | bool foundDigitSeparator = i > 0 |
| 770 | && isxdigit((unsigned char) line[i - 1]) |
| 771 | && i < (int) line.length() - 1 |
| 772 | && isxdigit((unsigned char) line[i + 1]); |
| 773 | return foundDigitSeparator; |
| 774 | } |
| 775 | |
| 776 | // peek at the next unread character. |
| 777 | char ASBase::peekNextChar(const string& line, int i) const |
| 778 | { |
| 779 | char ch = ' '; |
| 780 | size_t peekNum = line.find_first_not_of(" \t" , i + 1); |
| 781 | if (peekNum == string::npos) |
| 782 | return ch; |
| 783 | ch = line[peekNum]; |
| 784 | return ch; |
| 785 | } |
| 786 | |
| 787 | } // end namespace astyle |
| 788 | |