summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/align_preprocessor.cpp
blob: b05c0dd9ef901b9655bbe1f840cdfb9aa12a8eca (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
/**
 * @file align_preprocessor.cpp
 *
 * @author  Guy Maurel
 * split from align.cpp
 * @author  Ben Gardner
 * @license GPL v2+
 */

#include "align_preprocessor.h"

#include "align_stack.h"
#include "log_rules.h"

constexpr static auto LCURRENT = LALPP;

using namespace uncrustify;


void align_preprocessor(void)
{
   LOG_FUNC_ENTRY();

   AlignStack as;    // value macros

   log_rule_B("align_pp_define_span");
   as.Start(options::align_pp_define_span());
   log_rule_B("align_pp_define_gap");
   as.m_gap = options::align_pp_define_gap();
   AlignStack *cur_as = &as;

   AlignStack asf;   // function macros

   log_rule_B("align_pp_define_span");
   asf.Start(options::align_pp_define_span());
   log_rule_B("align_pp_define_gap");
   asf.m_gap = options::align_pp_define_gap();

   Chunk *pc = Chunk::GetHead();

   while (  pc != nullptr
         && pc->IsNotNullChunk())
   {
      // Note: not counting back-slash newline combos
      if (chunk_is_token(pc, CT_NEWLINE))   // mind the gap: chunk_is_newline(pc) is NOT the same!
      {
         as.NewLines(pc->nl_count);
         asf.NewLines(pc->nl_count);
      }

      // If we aren't on a 'define', then skip to the next non-comment
      if (chunk_is_not_token(pc, CT_PP_DEFINE))
      {
         pc = pc->GetNextNc();
         continue;
      }
      // step past the 'define'
      pc = pc->GetNextNc();

      if (pc->IsNullChunk())
      {
         // coveralls will complain here. There are no example for that.
         // see https://en.wikipedia.org/wiki/Robustness_principle
         break;
      }
      LOG_FMT(LALPP, "%s(%d): define (%s) on line %zu col %zu\n",
              __func__, __LINE__, pc->Text(), pc->orig_line, pc->orig_col);

      cur_as = &as;

      if (chunk_is_token(pc, CT_MACRO_FUNC))
      {
         log_rule_B("align_pp_define_together");

         if (!options::align_pp_define_together())
         {
            cur_as = &asf;
         }
         // Skip to the close parenthesis
         pc = pc->GetNextNc(); // point to open (
         pc = pc->GetNextType(CT_FPAREN_CLOSE, pc->level);

         LOG_FMT(LALPP, "%s(%d): jumped to (%s) on line %zu col %zu\n",
                 __func__, __LINE__, pc->Text(), pc->orig_line, pc->orig_col);
      }
      // step to the value past the close parenthesis or the macro name
      pc = pc->GetNext();

      if (pc->IsNullChunk())
      {
         // coveralls will complain here. There are no example for that.
         // see https://en.wikipedia.org/wiki/Robustness_principle
         break;
      }

      /*
       * don't align anything if the first line ends with a newline before
       * a value is given
       */
      if (!chunk_is_newline(pc))
      {
         LOG_FMT(LALPP, "%s(%d): align on '%s', line %zu col %zu\n",
                 __func__, __LINE__, pc->Text(), pc->orig_line, pc->orig_col);

         cur_as->Add(pc);
      }
   }
   as.End();
   asf.End();
} // align_preprocessor