summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.74.0/src/uncrustify_types.h
blob: 1aeb43c337ce4356a73b7dd86b31f2dcc7302b3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
/**
 * @file uncrustify_types.h
 *
 * Defines some types for the uncrustify program
 *
 * @author  Ben Gardner
 * @license GPL v2+
 */

#ifndef UNCRUSTIFY_TYPES_H_INCLUDED
#define UNCRUSTIFY_TYPES_H_INCLUDED

#include "options.h"
#include "pcf_flags.h"
#include "token_enum.h"    // c_token_t
#include "unc_text.h"
#include "uncrustify_limits.h"

#include <assert.h>

#ifdef HAVE_UTIME_H
#include <utime.h>
#endif


class ParseFrame;


/**
 * abbreviations used:
 *   SS = star style
 */

/**
 * special strings to mark a part of the input file where
 * uncrustify shall not change anything
 */
#define UNCRUSTIFY_OFF_TEXT    " *INDENT-OFF*"
#define UNCRUSTIFY_ON_TEXT     " *INDENT-ON*"

//! returns type (with removed reference) of a variable
#define noref_decl_t(X)              std::remove_reference<decltype((X))>::type

//! returns type (with removed const and reference) of a variable
#define nocref_decl_t(X)             std::remove_const<noref_decl_t((X))>::type

//! static casts Y to the type (with removed reference) of X
#define s_cast_noref_decl_t(X, Y)    static_cast<nocref_decl_t(X)>(Y)

//! performs abs on Y after static casting it to the type (with removed reference) of X
#define cast_abs(X, Y)               s_cast_noref_decl_t(X, abs(Y))

/**
 * @brief Macro to inform the compiler that a variable is intentionally
 * not in use.
 *
 * @param [in] variableName: The unused variable.
 */
#define UNUSED(variableName)         ((void)variableName)


//! Brace stage enum used in brace_cleanup
enum class brace_stage_e : unsigned int
{
   NONE,
   PAREN1,      //! expected paren after if/catch (C++)/for/switch/synchronized/while
   OP_PAREN1,   //! optional paren after catch (C#)
   WOD_PAREN,   //! while of do parens
   WOD_SEMI,    //! semicolon after while of do
   BRACE_DO,    //! do
   BRACE2,      //! if/catch/else/finally/for/switch/synchronized/while
   ELSE,        //! expecting 'else' after 'if'
   ELSEIF,      //! expecting 'if' after 'else'
   WHILE,       //! expecting 'while' after 'do'
   CATCH,       //! expecting 'catch' or 'finally' after 'try'
   CATCH_WHEN,  //! optional 'when' after 'catch'
};


enum class char_encoding_e : unsigned int
{
   e_ASCII,     //! 0-127
   e_BYTE,      //! 0-255, not UTF-8
   e_UTF8,      //! utf 8 bit wide
   e_UTF16_LE,  //! utf 16 bit wide, little endian
   e_UTF16_BE   //! utf 16 bit wide, big endian
};


struct chunk_t; //forward declaration


/**
 * Sort of like the aligning stuff, but the token indent is relative to the
 * indent of another chunk. This is needed, as that chunk may be aligned and
 * so the indent cannot be determined in the indent code.
 */
struct indent_ptr_t
{
   chunk_t *ref;
   int     delta;
};


struct align_ptr_t
{
   chunk_t *next;       //! nullptr or the chunk that should be under this one
   bool    right_align; //! AlignStack.m_right_align
   size_t  star_style;  //! AlignStack.m_star_style
   size_t  amp_style;   //! AlignStack.m_amp_style
   int     gap;         //! AlignStack.m_gap

   /*
    * col_adj is the amount to alter the column for the token.
    * For example, a dangling '*' would be set to -1.
    * A right-aligned word would be a positive value.
    */
   int     col_adj;
   chunk_t *ref;
   chunk_t *start;
};


// for debugging purpose only
typedef std::pair<size_t, char *>   Track_nr;         // track for "trackNumber" and "rule"
typedef std::vector<Track_nr>       track_list;       // liste for many tracks

// This is the main type of this program
struct chunk_t
{
   chunk_t()
   {
      reset();
   }


   //! sets all elements of the struct to their default value
   void reset()
   {
      memset(&align, 0, sizeof(align));
      memset(&indent, 0, sizeof(indent));
      next          = nullptr;
      prev          = nullptr;
      parent        = nullptr;
      type          = CT_NONE;
      parent_type   = CT_NONE;
      orig_line     = 0;
      orig_col      = 0;
      orig_col_end  = 0;
      orig_prev_sp  = 0;
      flags         = PCF_NONE;
      column        = 0;
      column_indent = 0;
      nl_count      = 0;
      nl_column     = 0;
      level         = 0;
      brace_level   = 0;
      pp_level      = 999;                           // use a big value to find some errors
      after_tab     = false;
      // for debugging purpose only
      tracking = nullptr;
      str.clear();
   }


   //! provides the number of characters of string
   size_t len() const
   {
      return(str.size());
   }


   //! provides the content of a string a zero terminated character pointer
   const char *text() const
   {
      return(str.c_str());
   }


   // Issue #2984, fill up, if necessary, a copie of the first chars of the text() string
   const char *elided_text(char *for_the_copy)
   {
      const char *test_it       = text();
      size_t     test_it_length = strlen(test_it);

      size_t     truncate_value = uncrustify::options::debug_truncate();

      if (truncate_value != 0)
      {
         if (test_it_length > truncate_value)
         {
            memset(for_the_copy, 0, 1000);

            if (test_it_length < truncate_value + 30)
            {
               strncpy(for_the_copy, test_it, truncate_value - 30);
               for_the_copy[truncate_value - 30] = 0;
            }
            else
            {
               strncpy(for_the_copy, test_it, truncate_value);
               for_the_copy[truncate_value] = 0;
            }
            char *message = strcat(for_the_copy, " ... <The string is truncated>");

            return(message);
         }
         else
         {
            return(test_it);
         }
      }
      return(test_it);
   }

   chunk_t      *next;            //! pointer to next chunk in list
   chunk_t      *prev;            //! pointer to previous chunk in list
   chunk_t      *parent;          //! pointer to parent chunk(not always set)
   align_ptr_t  align;
   indent_ptr_t indent;
   c_token_t    type;             //! type of the chunk itself
   c_token_t    parent_type;      //! type of the parent chunk usually CT_NONE
                                  //! might be different from parent->parent_type (above)
   size_t       orig_line;        //! line number of chunk in input file
   size_t       orig_col;         //! column where chunk started in the input file, is always > 0
   size_t       orig_col_end;     //! column where chunk ended in the input file, is always > 1
   UINT32       orig_prev_sp;     //! whitespace before this token
   pcf_flags_t  flags;            //! see PCF_xxx
   size_t       column;           //! column of chunk
   size_t       column_indent;    /** if 1st on a line, set to the 'indent'
                                   * column, which may be less than the real
                                   * column used to indent with tabs          */
   size_t       nl_count;         //! number of newlines in CT_NEWLINE
   size_t       nl_column;        //! column of the subsequent newline entries(all of them should have the same column)
   size_t       level;            /** nest level in {, (, or [
                                   * only to help vim command } */
   size_t       brace_level;      //! nest level in braces only
   size_t       pp_level;         //! nest level in preprocessor
   bool         after_tab;        //! whether this token was after a tab
   unc_text     str;              //! the token text

   // for debugging purpose only
   track_list   *tracking;
};


//! list of all programming languages Uncrustify supports
enum lang_flag_e
{
   LANG_C    = 0x0001,
   LANG_CPP  = 0x0002,
   LANG_D    = 0x0004,
   LANG_CS   = 0x0008,     //! C# (C-Sharp)
   LANG_JAVA = 0x0010,
   LANG_OC   = 0x0020,     //! Objective-C
   LANG_VALA = 0x0040,
   LANG_PAWN = 0x0080,
   LANG_ECMA = 0x0100,     //! ECMA Script (JavaScript)

   LANG_ALLC = 0x017f,     /** LANG_C    | LANG_CPP | LANG_D    | LANG_CS   |
                            *  LANG_JAVA | LANG_OC  | LANG_VALA | LANG_ECMA   */
   LANG_ALL  = 0x0fff,     //! applies to all languages

   FLAG_HDR  = 0x2000,     /*<< Header file for C family languages */
   FLAG_DIG  = 0x4000,     //! digraph/trigraph
   FLAG_PP   = 0x8000,     //! only appears in a preprocessor
};

//! Pattern classes for special keywords
enum class pattern_class_e : unsigned int
{
   NONE,
   BRACED,   /** keyword + braced statement:
              *    do, try, finally, body, unittest, unsafe, volatile
              *    add, get, remove, set                                      */
   PBRACED,  /** keyword + parens + braced statement:
              *    if, elseif, switch, for, while, synchronized,
              *    using, lock, with, version, CT_D_SCOPE_IF                  */
   OPBRACED, /** keyword + optional parens + braced statement:
              *    catch, version, debug                                      */
   VBRACED,  /** keyword + value + braced statement:
              *    namespace                                                  */
   PAREN,    /** keyword + parens:
              *    while-of-do                                                */
   OPPAREN,  /** keyword + optional parens:
              *    invariant (D lang)                                         */
   ELSE,     /** Special case of pattern_class_e::BRACED for handling CT_IF
              *    else                                                       */
};

//! used to link language keywords with some addition information
struct chunk_tag_t
{
   const char *tag;        //! name of the keyword e.g. "bool"
   c_token_t  type;        //! uncrustify type assigned to that keyword
   size_t     lang_flags;  //! programming language that uses this keyword
};


struct align_t
{
   size_t    col;
   c_token_t type;
   size_t    len;    //! length of the token + space
};

//! holds information and data of a file
struct file_mem
{
   std::vector<UINT8> raw;  //! raw content of file
   std::deque<int>    data; //! processed content of file
   bool               bom;
   char_encoding_e    enc;  //! character encoding of file ASCII, utf, etc.
#ifdef HAVE_UTIME_H
   struct utimbuf     utb;
#endif
};

enum class unc_stage_e : unsigned int
{
   TOKENIZE,
   HEADER,
   TOKENIZE_CLEANUP,
   BRACE_CLEANUP,
   FIX_SYMBOLS,
   MARK_COMMENTS,
   COMBINE_LABELS,
   OTHER,
   CLEANUP
};

struct cp_data_t
{
   std::deque<UINT8> *bout;
   FILE              *fout;
   int               last_char;
   bool              do_check;
   unc_stage_e       unc_stage;
   int               check_fail_cnt;       //! total failure count
   bool              if_changed;

   UINT32            error_count;       //! counts how many errors occurred so far
   std::string       filename;

   file_mem          file_hdr;          // for cmt_insert_file_header
   file_mem          file_ftr;          // for cmt_insert_file_footer
   file_mem          func_hdr;          // for cmt_insert_func_header
   file_mem          oc_msg_hdr;        // for cmt_insert_oc_msg_header
   file_mem          class_hdr;         // for cmt_insert_class_header
   file_mem          reflow_fold_regex; // for cmt_reflow_fold_regex_file

   size_t            lang_flags;        //! defines the language of the source input
   bool              lang_forced;       //! overwrites automatic language detection

   bool              unc_off;
   bool              unc_off_used;       //! true if the `disable_processing_cmt` option was actively used in the processed file
   UINT32            line_number;
   size_t            column;             //! column for parsing
   UINT16            spaces;             //! space count on output

   int               ifdef_over_whole_file;

   bool              frag;          //! activates code fragment option
   UINT32            frag_cols;

   // stuff to auto-detect line endings
   UINT32            le_counts[uncrustify::line_end_styles];
   unc_text          newline;

   int               did_newline;       //! flag indicates if a newline was added or converted
   c_token_t         in_preproc;
   int               preproc_ncnl_count;
   bool              output_trailspace;
   bool              output_tab_as_space;

   bool              bom;
   char_encoding_e   enc;

   // bumped up when a line is split or indented
   int               changes;
   int               pass_count;       //! indicates how often the chunk list shall be processed

   align_t           al[uncrustify::limits::AL_SIZE];
   size_t            al_cnt;
   bool              al_c99_array;

   bool              warned_unable_string_replace_tab_chars;

   int               pp_level;       // TODO: can this ever be -1?

   const char        *phase_name;
   const char        *dumped_file;
   const char        *html_file = nullptr; // for debugging purpose only
};

extern cp_data_t cpd;  // TODO: can we avoid this external variable?

const char *get_brace_stage_name(brace_stage_e brace_stage);

const char *get_unc_stage_name(unc_stage_e unc_stage);

#endif /* UNCRUSTIFY_TYPES_H_INCLUDED */