1 /** 2 * @file uncrustify_types.h 3 * 4 * Defines some types for the uncrustify program 5 * 6 * @author Ben Gardner 7 * @license GPL v2+ 8 */ 9 10 #ifndef UNCRUSTIFY_TYPES_H_INCLUDED 11 #define UNCRUSTIFY_TYPES_H_INCLUDED 12 13 #include "options.h" 14 #include "pcf_flags.h" 15 #include "token_enum.h" // c_token_t 16 #include "unc_text.h" 17 #include "uncrustify_limits.h" 18 19 #include <assert.h> 20 21 #ifdef HAVE_UTIME_H 22 #include <utime.h> 23 #endif 24 25 26 class ParseFrame; 27 28 29 /** 30 * abbreviations used: 31 * SS = star style 32 */ 33 34 /** 35 * special strings to mark a part of the input file where 36 * uncrustify shall not change anything 37 */ 38 #define UNCRUSTIFY_OFF_TEXT " *INDENT-OFF*" 39 #define UNCRUSTIFY_ON_TEXT " *INDENT-ON*" 40 41 //! returns type (with removed reference) of a variable 42 #define noref_decl_t(X) std::remove_reference<decltype((X))>::type 43 44 //! returns type (with removed const and reference) of a variable 45 #define nocref_decl_t(X) std::remove_const<noref_decl_t((X))>::type 46 47 //! static casts Y to the type (with removed reference) of X 48 #define s_cast_noref_decl_t(X, Y) static_cast<nocref_decl_t(X)>(Y) 49 50 //! performs abs on Y after static casting it to the type (with removed reference) of X 51 #define cast_abs(X, Y) s_cast_noref_decl_t(X, abs(Y)) 52 53 /** 54 * @brief Macro to inform the compiler that a variable is intentionally 55 * not in use. 56 * 57 * @param [in] variableName: The unused variable. 58 */ 59 #define UNUSED(variableName) ((void)variableName) 60 61 62 //! Brace stage enum used in brace_cleanup 63 enum class brace_stage_e : unsigned int 64 { 65 NONE, 66 PAREN1, //! expected paren after if/catch (C++)/for/switch/synchronized/while 67 OP_PAREN1, //! optional paren after catch (C#) 68 WOD_PAREN, //! while of do parens 69 WOD_SEMI, //! semicolon after while of do 70 BRACE_DO, //! do 71 BRACE2, //! if/catch/else/finally/for/switch/synchronized/while 72 ELSE, //! expecting 'else' after 'if' 73 ELSEIF, //! expecting 'if' after 'else' 74 WHILE, //! expecting 'while' after 'do' 75 CATCH, //! expecting 'catch' or 'finally' after 'try' 76 CATCH_WHEN, //! optional 'when' after 'catch' 77 }; 78 79 80 enum class char_encoding_e : unsigned int 81 { 82 e_ASCII, //! 0-127 83 e_BYTE, //! 0-255, not UTF-8 84 e_UTF8, //! utf 8 bit wide 85 e_UTF16_LE, //! utf 16 bit wide, little endian 86 e_UTF16_BE //! utf 16 bit wide, big endian 87 }; 88 89 90 struct chunk_t; //forward declaration 91 92 93 /** 94 * Sort of like the aligning stuff, but the token indent is relative to the 95 * indent of another chunk. This is needed, as that chunk may be aligned and 96 * so the indent cannot be determined in the indent code. 97 */ 98 struct indent_ptr_t 99 { 100 chunk_t *ref; 101 int delta; 102 }; 103 104 105 struct align_ptr_t 106 { 107 chunk_t *next; //! nullptr or the chunk that should be under this one 108 bool right_align; //! AlignStack.m_right_align 109 size_t star_style; //! AlignStack.m_star_style 110 size_t amp_style; //! AlignStack.m_amp_style 111 int gap; //! AlignStack.m_gap 112 113 /* 114 * col_adj is the amount to alter the column for the token. 115 * For example, a dangling '*' would be set to -1. 116 * A right-aligned word would be a positive value. 117 */ 118 int col_adj; 119 chunk_t *ref; 120 chunk_t *start; 121 }; 122 123 124 // for debugging purpose only 125 typedef std::pair<size_t, char *> Track_nr; // track for "trackNumber" and "rule" 126 typedef std::vector<Track_nr> track_list; // liste for many tracks 127 128 // This is the main type of this program 129 struct chunk_t 130 { chunk_tchunk_t131 chunk_t() 132 { 133 reset(); 134 } 135 136 137 //! sets all elements of the struct to their default value resetchunk_t138 void reset() 139 { 140 memset(&align, 0, sizeof(align)); 141 memset(&indent, 0, sizeof(indent)); 142 next = nullptr; 143 prev = nullptr; 144 parent = nullptr; 145 type = CT_NONE; 146 parent_type = CT_NONE; 147 orig_line = 0; 148 orig_col = 0; 149 orig_col_end = 0; 150 orig_prev_sp = 0; 151 flags = PCF_NONE; 152 column = 0; 153 column_indent = 0; 154 nl_count = 0; 155 nl_column = 0; 156 level = 0; 157 brace_level = 0; 158 pp_level = 999; // use a big value to find some errors 159 after_tab = false; 160 // for debugging purpose only 161 tracking = nullptr; 162 str.clear(); 163 } 164 165 166 //! provides the number of characters of string lenchunk_t167 size_t len() const 168 { 169 return(str.size()); 170 } 171 172 173 //! provides the content of a string a zero terminated character pointer textchunk_t174 const char *text() const 175 { 176 return(str.c_str()); 177 } 178 179 180 // Issue #2984, fill up, if necessary, a copie of the first chars of the text() string elided_textchunk_t181 const char *elided_text(char *for_the_copy) 182 { 183 const char *test_it = text(); 184 size_t test_it_length = strlen(test_it); 185 186 size_t truncate_value = uncrustify::options::debug_truncate(); 187 188 if (truncate_value != 0) 189 { 190 if (test_it_length > truncate_value) 191 { 192 memset(for_the_copy, 0, 1000); 193 194 if (test_it_length < truncate_value + 30) 195 { 196 strncpy(for_the_copy, test_it, truncate_value - 30); 197 for_the_copy[truncate_value - 30] = 0; 198 } 199 else 200 { 201 strncpy(for_the_copy, test_it, truncate_value); 202 for_the_copy[truncate_value] = 0; 203 } 204 char *message = strcat(for_the_copy, " ... <The string is truncated>"); 205 206 return(message); 207 } 208 else 209 { 210 return(test_it); 211 } 212 } 213 return(test_it); 214 } 215 216 chunk_t *next; //! pointer to next chunk in list 217 chunk_t *prev; //! pointer to previous chunk in list 218 chunk_t *parent; //! pointer to parent chunk(not always set) 219 align_ptr_t align; 220 indent_ptr_t indent; 221 c_token_t type; //! type of the chunk itself 222 c_token_t parent_type; //! type of the parent chunk usually CT_NONE 223 //! might be different from parent->parent_type (above) 224 size_t orig_line; //! line number of chunk in input file 225 size_t orig_col; //! column where chunk started in the input file, is always > 0 226 size_t orig_col_end; //! column where chunk ended in the input file, is always > 1 227 UINT32 orig_prev_sp; //! whitespace before this token 228 pcf_flags_t flags; //! see PCF_xxx 229 size_t column; //! column of chunk 230 size_t column_indent; /** if 1st on a line, set to the 'indent' 231 * column, which may be less than the real 232 * column used to indent with tabs */ 233 size_t nl_count; //! number of newlines in CT_NEWLINE 234 size_t nl_column; //! column of the subsequent newline entries(all of them should have the same column) 235 size_t level; /** nest level in {, (, or [ 236 * only to help vim command } */ 237 size_t brace_level; //! nest level in braces only 238 size_t pp_level; //! nest level in preprocessor 239 bool after_tab; //! whether this token was after a tab 240 unc_text str; //! the token text 241 242 // for debugging purpose only 243 track_list *tracking; 244 }; 245 246 247 //! list of all programming languages Uncrustify supports 248 enum lang_flag_e 249 { 250 LANG_C = 0x0001, 251 LANG_CPP = 0x0002, 252 LANG_D = 0x0004, 253 LANG_CS = 0x0008, //! C# (C-Sharp) 254 LANG_JAVA = 0x0010, 255 LANG_OC = 0x0020, //! Objective-C 256 LANG_VALA = 0x0040, 257 LANG_PAWN = 0x0080, 258 LANG_ECMA = 0x0100, //! ECMA Script (JavaScript) 259 260 LANG_ALLC = 0x017f, /** LANG_C | LANG_CPP | LANG_D | LANG_CS | 261 * LANG_JAVA | LANG_OC | LANG_VALA | LANG_ECMA */ 262 LANG_ALL = 0x0fff, //! applies to all languages 263 264 FLAG_HDR = 0x2000, /*<< Header file for C family languages */ 265 FLAG_DIG = 0x4000, //! digraph/trigraph 266 FLAG_PP = 0x8000, //! only appears in a preprocessor 267 }; 268 269 //! Pattern classes for special keywords 270 enum class pattern_class_e : unsigned int 271 { 272 NONE, 273 BRACED, /** keyword + braced statement: 274 * do, try, finally, body, unittest, unsafe, volatile 275 * add, get, remove, set */ 276 PBRACED, /** keyword + parens + braced statement: 277 * if, elseif, switch, for, while, synchronized, 278 * using, lock, with, version, CT_D_SCOPE_IF */ 279 OPBRACED, /** keyword + optional parens + braced statement: 280 * catch, version, debug */ 281 VBRACED, /** keyword + value + braced statement: 282 * namespace */ 283 PAREN, /** keyword + parens: 284 * while-of-do */ 285 OPPAREN, /** keyword + optional parens: 286 * invariant (D lang) */ 287 ELSE, /** Special case of pattern_class_e::BRACED for handling CT_IF 288 * else */ 289 }; 290 291 //! used to link language keywords with some addition information 292 struct chunk_tag_t 293 { 294 const char *tag; //! name of the keyword e.g. "bool" 295 c_token_t type; //! uncrustify type assigned to that keyword 296 size_t lang_flags; //! programming language that uses this keyword 297 }; 298 299 300 struct align_t 301 { 302 size_t col; 303 c_token_t type; 304 size_t len; //! length of the token + space 305 }; 306 307 //! holds information and data of a file 308 struct file_mem 309 { 310 std::vector<UINT8> raw; //! raw content of file 311 std::deque<int> data; //! processed content of file 312 bool bom; 313 char_encoding_e enc; //! character encoding of file ASCII, utf, etc. 314 #ifdef HAVE_UTIME_H 315 struct utimbuf utb; 316 #endif 317 }; 318 319 enum class unc_stage_e : unsigned int 320 { 321 TOKENIZE, 322 HEADER, 323 TOKENIZE_CLEANUP, 324 BRACE_CLEANUP, 325 FIX_SYMBOLS, 326 MARK_COMMENTS, 327 COMBINE_LABELS, 328 OTHER, 329 CLEANUP 330 }; 331 332 struct cp_data_t 333 { 334 std::deque<UINT8> *bout; 335 FILE *fout; 336 int last_char; 337 bool do_check; 338 unc_stage_e unc_stage; 339 int check_fail_cnt; //! total failure count 340 bool if_changed; 341 342 UINT32 error_count; //! counts how many errors occurred so far 343 std::string filename; 344 345 file_mem file_hdr; // for cmt_insert_file_header 346 file_mem file_ftr; // for cmt_insert_file_footer 347 file_mem func_hdr; // for cmt_insert_func_header 348 file_mem oc_msg_hdr; // for cmt_insert_oc_msg_header 349 file_mem class_hdr; // for cmt_insert_class_header 350 file_mem reflow_fold_regex; // for cmt_reflow_fold_regex_file 351 352 size_t lang_flags; //! defines the language of the source input 353 bool lang_forced; //! overwrites automatic language detection 354 355 bool unc_off; 356 bool unc_off_used; //! true if the `disable_processing_cmt` option was actively used in the processed file 357 UINT32 line_number; 358 size_t column; //! column for parsing 359 UINT16 spaces; //! space count on output 360 361 int ifdef_over_whole_file; 362 363 bool frag; //! activates code fragment option 364 UINT32 frag_cols; 365 366 // stuff to auto-detect line endings 367 UINT32 le_counts[uncrustify::line_end_styles]; 368 unc_text newline; 369 370 int did_newline; //! flag indicates if a newline was added or converted 371 c_token_t in_preproc; 372 int preproc_ncnl_count; 373 bool output_trailspace; 374 bool output_tab_as_space; 375 376 bool bom; 377 char_encoding_e enc; 378 379 // bumped up when a line is split or indented 380 int changes; 381 int pass_count; //! indicates how often the chunk list shall be processed 382 383 align_t al[uncrustify::limits::AL_SIZE]; 384 size_t al_cnt; 385 bool al_c99_array; 386 387 bool warned_unable_string_replace_tab_chars; 388 389 int pp_level; // TODO: can this ever be -1? 390 391 const char *phase_name; 392 const char *dumped_file; 393 const char *html_file = nullptr; // for debugging purpose only 394 }; 395 396 extern cp_data_t cpd; // TODO: can we avoid this external variable? 397 398 const char *get_brace_stage_name(brace_stage_e brace_stage); 399 400 const char *get_unc_stage_name(unc_stage_e unc_stage); 401 402 #endif /* UNCRUSTIFY_TYPES_H_INCLUDED */ 403