Pages: [1]   Go Down
Author Topic: How can I see expanded macros?  (Read 909 times)
0 Members and 1 Guest are viewing this topic.
Santa Cruz California
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
"When I hear of Schrödinger's cat, I reach for my gun " (Stephen Hawking)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm fooling around with some macros to implement  a select operator similar to the one in VB. I'd like to be able to see what the actual output is rather than just a pass/fail test.

Here's what I'm trying to do...

#define selection switch(0){ if(false);
#define condition(str) else if(str)
#define conditionFail else
#define endSelection }

void doGET(String parameter, EthernetClient client){  // must be a file request
    parameter.toLowerCase();
    if (parameter=="/") parameter = "/index.htm";
    int ptr = parameter.lastIndexOf(".");
    String ext = parameter.substring(ptr+1);
    DEBUG_PRINT("ext:" << ext );
  selection
      condition (ext == "htm") doHTML(parameter,  client);
      condition (ext == "jpg") doJPG( parameter,  client);
      condition (ext == "txt") doTXT( parameter,  client);
      conditionFail crash(4002, "unknown file extension");
    endSelection
}

Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not sure if this is the easiest way, but this is how I did it.

Get verbose output (checkbox in Preferences, or hold down Shift while hitting Verify under version 0022).

The first line shown (it might wrap) should be your main sketch, in my case I saw this:

/Applications/Arduino_v0022.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino_v0022.app/Contents/Resources/Java/hardware/arduino/cores/arduino /var/folders/1l/43x8v10s1v36trvjz3v92m900000gn/T/build7232351857332367125.tmp/sketch_mar30a.cpp  -o/var/folders/1l/43x8v10s1v36trvjz3v92m900000gn/T/build7232351857332367125.tmp/sketch_mar30a.cpp.o

Now, replace the -o ... stuff with -E.

In other words, the output file, in my case:

-o/var/folders/1l/43x8v10s1v36trvjz3v92m900000gn/T/build7232351857332367125.tmp/sketch_mar30a.cpp.o

is replaced by -E.

This outputs the preprocessor output to stdout.  You might want to send that to a file, eg.

/Applications/Arduino_v0022.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=22 -I/Applications/Arduino_v0022.app/Contents/Resources/Java/hardware/arduino/cores/arduino /var/folders/1l/43x8v10s1v36trvjz3v92m900000gn/T/build7232351857332367125.tmp/sketch_mar30a.cpp  -E > ~/nick.txt

Opening that file, near the bottom, I see this:

Code:
void doGET(String parameter, EthernetClient client);
void doGET(String parameter, EthernetClient client){
    parameter.toLowerCase();
    if (parameter=="/") parameter = "/index.htm";
    int ptr = parameter.lastIndexOf(".");
    String ext = parameter.substring(ptr+1);
    DEBUG_PRINT("ext:" << ext );
  switch(0){ if(0x0);
      else if(ext == "htm") doHTML(parameter, client);
      else if(ext == "jpg") doJPG( parameter, client);
      else if(ext == "txt") doTXT( parameter, client);
      else crash(4002, "unknown file extension");
    }
}

Having answered your question, I don't know if I would do that personally. I think it just obscures things somewhat. But sometimes it is handy to know what the preprocessor is doing.
Logged

Santa Cruz California
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
"When I hear of Schrödinger's cat, I reach for my gun " (Stephen Hawking)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Nick.
I haven't managed to get DOS to accept that string yet, I tried putting it in a bat file but still no joy. I'm running Arduino 1.0 and the output looks a little different. However your copy of the output should be very helpful.
Norm
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know what the switch is doing, you don't have any case statements there:

Code:
switch(0){ if(0x0);
      else if(ext == "htm") doHTML(parameter, client);
      else if(ext == "jpg") doJPG( parameter, client);
      else if(ext == "txt") doTXT( parameter, client);
      else crash(4002, "unknown file extension");
    }

Also I advise against using the String class, it can be a memory hog.
Logged

Santa Cruz California
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
"When I hear of Schrödinger's cat, I reach for my gun " (Stephen Hawking)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The "switch(0){ if(0x0)" was an attempt to get "break" to work for me without having a list of cases. Coming back fresh has shown me that I'm not getting what I want out of this anyway. What I want is a switch/case operator that isn't limited to testing for equality of integers.


"Also I advise against using the String class, it can be a memory hog."
The code needs to be re-entrant and trying to keep track of char *s  and their scope was making me crazy.
« Last Edit: March 30, 2012, 05:13:46 pm by TheNorm » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can set up a one-shot loop and break out of it like below, but I'm not convinced this is a fantastic idea:

Code:
void setup ()
  {
  int a = 42;
 
  do
    {
    if (a == 1)
       {
       // blah blah
       break;
       }
    else if (a == 2)
       {
         
       }
     // and so on ... 
    } while (false);
 
  } // end of setup
void loop () {}
Logged

Santa Cruz California
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
"When I hear of Schrödinger's cat, I reach for my gun " (Stephen Hawking)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mmm. If I just use "if"s instead of "else if"s I can get the fall-through effect of a "case" as well as having a "break". I don't quite see how to do "default" at the moment but...

I'd rather use a macro with it's own syntax than an apparently infinite do loop though. Rather than head scratching and figuring out what's going on I'd know right away that I have a specific operator to look up. At least I'm hoping that's how my mind will work after I forget how the code works, in about two days.

Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

for strings something like this works

Code:

#define STRSWITCH(STR)      { char _x[16]; strcpy(_x, STR); if (false) {
#define STRCASE(STR)        } else if (strcmp(_x, STR)==0){
#define STRBREAK            ;
#define STRDEFAULT          } else {
#define STRENDSWITCH        }}

void setup()
{
  Serial.begin(9600);
  char x[10];
  strcpy(x, "BEER");

  STRSWITCH(x)
    STRCASE ("NOT")
      Serial.println(1,DEC);
  STRCASE ("APE")
    Serial.println(2,DEC);
  STRCASE ("BEER")
    Serial.println(3,DEC);
  STRCASE ("WINE")
    Serial.println(4,DEC);
  STRDEFAULT
    Serial.println("not in the list");
  STRENDSWITCH
}

void loop()
{
};
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


can even be smaller, and yes it uses an hidded variable ...

Code:

#define STRSWITCH(STR)      char _x[16]; strcpy(_x, STR); if (false)
#define STRCASE(STR)        } else if (strcmp(_x, STR)==0){
#define STRDEFAULT          } else {


void setup()
{
  Serial.begin(9600);
  char x[10];
  strcpy(x, "BEER");

  STRSWITCH(x)
  {
    STRCASE ("NOT")
      Serial.println(1,DEC);
      Serial.println(1,DEC);
    STRCASE ("APE")
      Serial.println(2,DEC);
      Serial.println(2,DEC);
    STRCASE ("BEER")
      Serial.println(3,DEC);
    STRCASE ("WINE")
      Serial.println(4,DEC);
    STRDEFAULT
      Serial.println("not in the list");
  }
}
void loop(){
};
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Santa Cruz California
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
"When I hear of Schrödinger's cat, I reach for my gun " (Stephen Hawking)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, that's nice. I was shooting for a more generic solution not limited to string equalities but that should take care of my current needs very well.

Thanks
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

if you want a switch that works for all datatypes (including structs etc) than you must rebuild a compiler I guess.

But with the trick above you can (re)make a switch like layout for every datatype, you need a element, a copyfunction and a compare function

#define T_SWITCH(X)     element _x; elementCopy(_x, X); if (false)
#define T_CASE(X)         } else if (elementCmp(_x, X)==0) {
#define T_DEFAULT       } else {

Even making  switch for structs like  {x,y} is possible this way.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Santa Cruz California
Offline Offline
Jr. Member
**
Karma: 0
Posts: 53
"When I hear of Schrödinger's cat, I reach for my gun " (Stephen Hawking)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for all the responses.
Logged

Pages: [1]   Go Up
Jump to: