[aspectc-user] Preprocessor bug? Macros with spaces.

Guilherme . guibufolo at gmail.com
Thu Apr 14 15:46:25 CEST 2011


Hi!

I have been working with AspectC and the ecos-OS and have found that
the weaver has some difficultios with some macros.

I have compile a small test sample and would like to know if there as
a fix for it or if i have to wait for the next release.

The macros are found exactly like this in the ecos source except where marked.

Sample:
#define CYG_MACRO_START do {
#define CYG_MACRO_END      } while(0)

#define HAL_WRITE_UINT8( _register_, _value_ )   \
CYG_MACRO_START                                 \
{                                               \
               asm volatile ( "xor %%eax,%%eax ;"          \
                                                                  "inb
%%dx, %%al"             \
                              : "=a" (_value_)             \
                                    :  "d"(_register_)           \
                         );                                      \
}                                               \
CYG_MACRO_END

//added for sample
//these are defined within ecos to point to the registers
int address = 10;
int data = 12;
#define DS_ADDR address
#define DS_DATA data
//end added for sample

# define DS_WRITE_UINT8(x,y) HAL_WRITE_UINT8(x,y)

# define DS_WRITE(offset, data)                \
 CYG_MACRO_START                              \
 DS_WRITE_UINT8(DS_ADDR, (offset));           \
 DS_WRITE_UINT8(DS_DATA, (data));             \
 CYG_MACRO_END

int main(int, char**){
//added for sample
       int add = 0xa;

//these are defined within ecos to point to the registers
#define DS_REG_B add
#define DS_REG_B_24H add
//end added for sample

       DS_WRITE(DS_REG_B, DS_REG_B_24H);

       return 0;
}

Command

ag++ -v9 test.cpp --keep_woven -o test

outputs:

*
*
* AG++ Configuration:
*   Aspect C++ weaver:  ac++
*   C++ compiler:       g++
*   Files:               test.cpp
*   Options (G++):       -v -I "."  -o "test"
*   Options (AC++):      -v9 -p.
*   Options (total):     -v9 -v test.cpp -I "."  -o "test"  -p.
*   PumaConfig: 1 Weave: 1 Compile: 1 Link: 1
*
*
* Generating Puma configuration file
 - Parsing output of g++ compiler
 - Executing: "g++"  -E -dM -v -x c++ "/dev/null"
2>/tmp/agxx_stderrDhYyjR 1>/tmp/agxx_stdoutKby7VC
 - Exit: Success
 - removing temporary file: /tmp/agxx_stdoutKby7VC
 - removing temporary file: /tmp/agxx_stderrDhYyjR
 - Writing puma configuration file '/tmp/agxx_pcfg5Uwzyo'
* Weaving
 - Executing: "ac++" --config "/tmp/agxx_pcfg5Uwzyo"  -v9 -p. -c
"test.cpp" -o "test.acc"
* Running ac++ 1.0pre4 svn
* Handling Translation Unit `test.cpp'.
 - Path "test.cpp"
 - Inserting namespace AC
 - Parsing ...
test.cpp:38: error: tokens after end of program (too many closing brackets?)
test.cpp:38: error: invalid declaration near token `while'
test.cpp:38: located in the following non-file unit:
} while(0)
 - Aborting
error: Execution failed: "ac++" --config "/tmp/agxx_pcfg5Uwzyo"  -v9
-p. -c "test.cpp" -o "test.acc"
 - Exitcode: 256 (should be 0 )

And the preprocessed version is:
# 1 "test.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.cpp"
# 16 "test.cpp"
int address = 10;
int data = 12;
# 30 "test.cpp"
int main(int, char**){
 int add = 0xa;

 do {
        do {
                {
                        asm volatile ( "xor %%eax,%%eax ;"
                                        "inb %%dx, %%al"
                                        : "=a" ((add))
                                        : "d"(address) );
                }
        } while(0);

        do {
                {
                        asm volatile ( "xor %%eax,%%eax ;"
                                        "inb %%dx, %%al"
                                        : "=a" ((add))
                                        : "d"(data) );
                }
        } while(0);
 } while(0);

 return 0;
}

which is legal c++.

Am I doing something wrong or is this a real bug with the aspect
weaver preprocessor?

(I did sent this mail when i wasn't subscribed. AFAIK i fixed the bug
in Puma/src/cpp/Preprocessor.cc)

Here is my patch:

Index: Puma/src/cpp/PreprocessorParser.cc
===================================================================
--- Puma/src/cpp/PreprocessorParser.cc	(revision 590)
+++ Puma/src/cpp/PreprocessorParser.cc	(working copy)
@@ -167,7 +167,23 @@
   }
 }

+void trim(std::string& str){
+	// trim trailing spaces
+		size_t endpos = str.find_last_not_of(" \t");
+	if( string::npos != endpos )
+	{
+		    str = str.substr( 0, endpos+1 );
+	}

+	// trim leading spaces
+	size_t startpos = str.find_first_not_of(" \t");
+	if( string::npos != startpos )
+	{
+		str = str.substr( startpos );
+	}
+
+}
+
 // Parse a macro and return the name and the list of arguments
 bool parseMacro (const char *name,
                  string &macro_name, list<string> &args) {
@@ -175,19 +191,28 @@

   string work = name;
   string::size_type arg_pos = work.find_first_of ("(");
+	string::size_type closing_pos = work.find_first_of(")");
+	//closing bracket after opening bracket?
+	if(closing_pos < arg_pos){
+		return false;
+	}
   // arguments found?
   if (arg_pos != string::npos) {
     // check if there are characters in front of '('
     if (arg_pos == 0) return false; // syntax error
     macro_name = work.substr (0, arg_pos);
-    work = work.substr (arg_pos + 1); // the argument list
-    while ((arg_pos = work.find_first_of (",)")) != string::npos) {
+		work = work.substr(arg_pos + 1, closing_pos - arg_pos - 1);// the
argument list
+		//get everything within commas until we get the last closing parenthesis
+		while ((arg_pos = work.find_first_of(",")) != string::npos) {
       string arg = work.substr (0, arg_pos);
-      if (arg[0] == ' ' || arg[arg.length () - 1] == ' ')
-        return false;
+			trim(arg);
       args.push_back (arg);
       work = work.substr (arg_pos + 1); // the argument list
     }
+		if(work.length() == 0){
+			return false;
+		}
+		args.push_back(work);
   }
   else {
     // no arguments


This basically searches for the first opening and closing parenthesis
and takes all that as the arguments to the MACRO separated by ',' and
trimmed from beginning and ending whitespaces and tabs. I have run the
tests that come with the AspectC++ compiler and all of them passed.
(Btw it would be nice if there was a notice that the tests need
PUMA_CONFIG set to be able to compile, took me a while to figure that
out...)

Thx for your time.
Guilherme



More information about the aspectc-user mailing list