title: Advanced Preprocesor Tokenization in C
body: <p>I'm having problem building <strong>C</strong> macro for my PIC. It's the same for other C-based system's, so non-PIC <strong>C</strong> experts are also more than welcome.</p>
  
  <p>Lets assume that I have defined my LED_1 pin :</p>
  
  <pre><code>#define LED_1 A1    //A1 as output for LED_1
  </code></pre>
  
  <p>So if I want to light a LED I would write:</p>
  
  <pre><code>PORTAbits.RA1 = 1;
  </code></pre>
  
  <p>And if I would like to do it using my LED_1 definition I have to add two more macros:</p>
  
  <pre><code>#define change_PORT_(var) PORTAbits.R##var
  #define change_PORT(var) change_PORT_(var
  </code></pre>
  
  <p>And to use it:</p>
  
  <pre><code>change_PORT(LED_1) = 1;
  </code></pre>
  
  <p>And it works like a charm. But the problem is that in definitions above I have  </p>
  
  <blockquote>
    <p>PORT <strong>A</strong> bits.##var</p>
  </blockquote>
  
  <p>So what if I want to change PORTB values? I would have to build separate macros for PORTs A and B. But it's not even close to be a robust solution.
  And I came up with an idea which, I don't know why, doesnt work.</p>
  
  <pre><code>#define LED_1 A1
  #define LED_2 B1
  
  #define __A1 A   //This would be defined for all PORTA's pins such as A2,A3,A4 etc
  #define __B1 B
  
  #define ___change_PORT(var,var2)    PORT##var2 bits.R##var
  #define __change_PORT(var,var2)   ___change_PORT(var,var2)
  #define _change_PORT(var)    __change_PORT(var,__##var) // creating e.g. __A1
  #define change_PORT(var)   _change_PORT(var)
  </code></pre>
  
  <p>And when I try to run this:</p>
  
  <pre><code>change_PORT(LED_1);
  </code></pre>
  
  <p>The compiler changes <strong>__##var</strong> to <strong>___A1</strong> but it never changes <strong>__A1</strong> to <strong>A</strong> so this MACRO doesn't work as it supposed to.</p>
  
  <p>I spent a lot of time trying to fix it so I'd appreciate any help :)  </p>
  
  <blockquote>
    <hr>
    
    <p><strong>EDIT::</strong></p>
    
    <hr>
  </blockquote>
  
  <p>I might have found a solution to my problem:<br>
  (LAT is just another register name, but it works same as PORT, so this name-change is irrelevant)</p>
  
  <pre><code>#define ___PORTchange(var,var2) PORT##var2##bits.R##var
  #define __PORTchange(var,var2)  ___PORTchange(var,var2)
  #define CHANGE_TO_PORT_NAME(var) ___##var
  #define _PORTchange(var)    __PORTchange(var,CHANGE_TO_PORT_NAME(var))
  #define PORTchange(var) _PORTchange(var)
  </code></pre>
  
  <p>but I get a compiler error:</p>
  
  <blockquote>
    <p>100:   PORTAbits.RA0 = 1;<br>
                     ^ (374) missing basic type; int assumed (warning)<br>
                 ^ (983) storage class redeclared<br>
                 ^ (984) type redeclared<br>
                 ^ (239) identifier "PORTAbits" redefined (from line 3900)<br>
                 ^ (314) ";" expected  </p>
  </blockquote>
  
  <p>So no it does substitute it correctly but I get a compiler warning telling me that I redefine PORTAbits which I cannot understand. I just wanted preprocessor to change <strong>PORTchange(var)</strong> to <strong>PORTxbits.Rvar</strong> where x is A or B. But instead it seems that I'm redeclaring something.</p>
  
  <p>I don't get it.</p>