Browse Source

* fix for cplusplus skipping by JPMugaas.

git-svn-id: trunk@5012 -
marco 19 years ago
parent
commit
97a740d602
1 changed files with 368 additions and 162 deletions
  1. 368 162
      utils/h2pas/scan.l

+ 368 - 162
utils/h2pas/scan.l

@@ -208,6 +208,16 @@ type
        in_space_define : byte = 0;
        arglevel : longint = 0;
 
+       {> 1 = ifdef level in a ifdef C++ block
+          1 = first level in an ifdef block
+          0 = not in an ifdef block
+         -1 = in else part of ifdef block, process like we weren't in the block
+              but skip the incoming end.
+        > -1 = ifdef sublevel in an else block.
+       }
+       cplusblocklevel : LongInt = 0;
+       
+       
     function yylex : integer;
     function act_token : string;
     procedure internalerror(i : integer);
@@ -314,7 +324,11 @@ type
          strpnew:=p;
       end;
 
-
+    function NotInCPlusBlock : Boolean; inline;
+    begin
+      NotInCPlusBlock := cplusblocklevel < 1;
+    end;
+    
     constructor tresobject.init_preop(const s : string;_p1 : presobject);
       begin
          typ:=t_preop;
@@ -475,7 +489,8 @@ type
 D [0-9]
 %%
 
-"/*"                    begin
+"/*"                    if NotInCPlusBlock then 
+                        begin
                           if not stripcomment then
                             write(outfile,aktspace,'{');
                           repeat
@@ -526,8 +541,11 @@ D [0-9]
                             end;
                           until false;
                           flush(outfile);
-                        end;
-"//"                    begin
+                        end
+                        else 
+                          skip_until_eol;
+"//"                    if NotInCPlusBlock then 
+                        begin
                           commentstr:='';
                           if (in_define) and not (stripcomment) then
                           begin
@@ -579,23 +597,37 @@ D [0-9]
                             end;
                           until false;
                           flush(outfile);
-                        end;
-\"[^\"]*\"              return(CSTRING);
-\'[^\']*\'              return(CSTRING);
-"L"\"[^\"]*\"           if win32headers then
-                          return(CSTRING)
-                        else
-                          return(256);
-"L"\'[^\']*\'           if win32headers then
-                          return(CSTRING)
+                        end
+                        else 
+                          skip_until_eol;
+\"[^\"]*\"              if NotInCPlusBlock then return(CSTRING) else skip_until_eol;
+\'[^\']*\'              if NotInCPlusBlock then return(CSTRING) else skip_until_eol;
+"L"\"[^\"]*\"           if NotInCPlusBlock then 
+                        begin
+                          if win32headers then
+                            return(CSTRING)
+                          else
+                            return(256);
+                        end
+                        else skip_until_eol;
+"L"\'[^\']*\'           if NotInCPlusBlock then 
+                        begin
+                          if win32headers then
+                            return(CSTRING)
+                          else
+                            return(256);
+                        end
                         else
-                          return(256);
-{D}+[Uu]?[Ll]?          begin
+                          skip_until_eol;
+{D}+[Uu]?[Ll]?          if NotInCPlusBlock then 
+                        begin
                            while yytext[length(yytext)] in ['L','U','l','u'] do
                              Delete(yytext,length(yytext),1);
                            return(NUMBER);
-                        end;
+                        end
+                         else skip_until_eol;
 "0x"[0-9A-Fa-f]*[Uu]?[Ll]?
+                        if NotInCPlusBlock then                  
                         begin
                            (* handle pre- and postfixes *)
                            if copy(yytext,1,2)='0x' then
@@ -606,90 +638,170 @@ D [0-9]
                            while yytext[length(yytext)] in ['L','U','l','u'] do
                              Delete(yytext,length(yytext),1);
                            return(NUMBER);
-                        end;
+                        end
+                        else
+                         skip_until_eol;
 {D}+(\.{D}+)?([Ee][+-]?{D}+)?
+                        if NotInCPlusBlock then 
                         begin
                           return(NUMBER);
-                        end;
-"->"                    if in_define then
-                          return(DEREF)
-                        else
-                          return(256);
-"-"                     return(MINUS);
-"=="                    return(EQUAL);
-"!="                    return(UNEQUAL);
-">="                    return(GTE);
-"<="                    return(LTE);
-">>"                    return(_SHR);
-"##"                    return(STICK);
-"<<"                    return(_SHL);
-">"                     return(GT);
-"<"                     return(LT);
-"|"                     return(_OR);
-"&"                     return(_AND);
-"~"                     return(_NOT); (* inverse, but handled as not operation *)
-"!"                     return(_NOT);
-"/"                     return(_SLASH);
-"+"                     return(_PLUS);
-"?"                     return(QUESTIONMARK);
-":"                     return(COLON);
-","                     return(COMMA);
-"["                     return(LECKKLAMMER);
-"]"                     return(RECKKLAMMER);
-"("                     begin
-                           inc(arglevel);
-                           return(LKLAMMER);
-                        end;
-")"                     begin
-                           dec(arglevel);
-                           return(RKLAMMER);
-                        end;
-"*"                     return(STAR);
-"..."                   return(ELLIPSIS);
-"."                     if in_define then
-                          return(POINT)
+                        end
+                        else 
+                          skip_until_eol;
+"->"                    if NotInCPlusBlock then 
+                        begin
+                          if in_define then
+                            return(DEREF)
+                          else
+                            return(256);
+                        end
+                        else 
+                          skip_until_eol;
+"-"                     if NotInCPlusBlock then return(MINUS) else skip_until_eol;
+"=="                    if NotInCPlusBlock then return(EQUAL) else skip_until_eol;
+"!="                    if NotInCPlusBlock then return(UNEQUAL) else skip_until_eol;
+">="                    if NotInCPlusBlock then return(GTE) else skip_until_eol;
+"<="                    if NotInCPlusBlock then return(LTE) else skip_until_eol;
+">>"                    if NotInCPlusBlock then return(_SHR) else skip_until_eol;
+"##"                    if NotInCPlusBlock then return(STICK) else skip_until_eol;
+"<<"                    if NotInCPlusBlock then return(_SHL) else skip_until_eol;
+">"                     if NotInCPlusBlock then return(GT) else skip_until_eol;
+"<"                     if NotInCPlusBlock then return(LT) else skip_until_eol;
+"|"                     if NotInCPlusBlock then return(_OR) else skip_until_eol;
+"&"                     if NotInCPlusBlock then return(_AND) else skip_until_eol;
+"~"                     if NotInCPlusBlock then return(_NOT) else skip_until_eol; (* inverse, but handled as not operation *)
+"!"                     if NotInCPlusBlock then return(_NOT) else skip_until_eol;
+"/"                     if NotInCPlusBlock then return(_SLASH) else skip_until_eol;
+"+"                     if NotInCPlusBlock then return(_PLUS) else skip_until_eol;
+"?"                     if NotInCPlusBlock then return(QUESTIONMARK) else skip_until_eol;
+":"                     if NotInCPlusBlock then return(COLON) else skip_until_eol;
+","                     if NotInCPlusBlock then return(COMMA) else skip_until_eol;
+"["                     if NotInCPlusBlock then return(LECKKLAMMER) else skip_until_eol;
+"]"                     if NotInCPlusBlock then return(RECKKLAMMER) else skip_until_eol;
+"("                     if NotInCPlusBlock then 
+                           begin 
+                             inc(arglevel);
+                             return(LKLAMMER);
+                           end
                         else
-                          return(256);
-"="                     return(_ASSIGN);
-"extern"                return(EXTERN);
-"STDCALL"               if Win32headers then
-                          return(STDCALL)
+                           skip_until_eol;
+")"                     if NotInCPlusBlock then 
+                           begin
+                             dec(arglevel);
+                             return(RKLAMMER);
+                           end
+                         else 
+                           skip_until_eol;
+"*"                     if NotInCPlusBlock then return(STAR) else skip_until_eol;
+"..."                   if NotInCPlusBlock then return(ELLIPSIS) else skip_until_eol;
+"."                     if NotInCPlusBlock then 
+                          if in_define then
+                            return(POINT)
+                          else
+                            return(256);
+"="                     if NotInCPlusBlock then return(_ASSIGN) else skip_until_eol;
+"extern"                if NotInCPlusBlock then return(EXTERN) else skip_until_eol;
+"STDCALL"               if NotInCPlusBlock then 
+                        begin
+                          if Win32headers then
+                            return(STDCALL)
+                          else
+                            return(ID);
+                        end
                         else
-                          return(ID);
-"CDECL"                 if not Win32headers then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;                            
+"CDECL"                 if NotInCPlusBlock then
+                        begin 
+                          if not Win32headers then
+                            return(ID)
+                          else
+                            return(CDECL);
+                        end
                         else
-                          return(CDECL);
-"PASCAL"                if not Win32headers then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;                            
+"PASCAL"                if NotInCPlusBlock then 
+                        begin
+                          if not Win32headers then
+                            return(ID)
+                          else
+                            return(PASCAL);
+                        end
                         else
-                          return(PASCAL);
-"PACKED"                if not Win32headers then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;                            
+"PACKED"                if NotInCPlusBlock then 
+                        begin
+                          if not Win32headers then
+                            return(ID)
+                          else
+                            return(_PACKED);
+                        end
                         else
-                          return(_PACKED);
-"WINAPI"                if not Win32headers then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;
+"WINAPI"                if NotInCPlusBlock then 
+                        begin
+                          if not Win32headers then
+                            return(ID)
+                          else
+                            return(WINAPI);
+                        end
                         else
-                          return(WINAPI);
-"SYS_TRAP"              if not palmpilot then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;                            
+"SYS_TRAP"              if NotInCPlusBlock then 
+                        begin
+                          if not palmpilot then
+                            return(ID)
+                          else
+                            return(SYS_TRAP);
+                        end
                         else
-                          return(SYS_TRAP);
-"WINGDIAPI"             if not Win32headers then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;                            
+"WINGDIAPI"             if NotInCPlusBlock then 
+                        begin
+                          if not Win32headers then
+                            return(ID)
+                          else
+                            return(WINGDIAPI);
+                        end
                         else
-                          return(WINGDIAPI);
-"CALLBACK"              if not Win32headers then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;
+"CALLBACK"              if NotInCPlusBlock then 
+                        begin              
+                          if not Win32headers then
+                            return(ID)
+                          else
+                            return(CALLBACK);
+                        end
                         else
-                          return(CALLBACK);
-"EXPENTRY"              if not Win32headers then
-                          return(ID)
+                        begin
+                          skip_until_eol;
+                        end;
+"EXPENTRY"              if NotInCPlusBlock then 
+                        begin
+                          if not Win32headers then
+                            return(ID)
+                          else
+                            return(CALLBACK);
+                        end
                         else
-                          return(CALLBACK);
-"void"                  return(VOID);
-"VOID"                  return(VOID);
+                        begin
+                          skip_until_eol;
+                        end;
+"void"                  if NotInCPlusBlock then return(VOID) else skip_until_eol;
+"VOID"                  if NotInCPlusBlock then return(VOID) else skip_until_eol;
 "#ifdef __cplusplus"[ \t]*\n"extern \"C\" {"\n"#endif"
                         begin
                           if not stripinfo then
@@ -709,25 +821,96 @@ D [0-9]
                         begin
                           if not stripinfo then
                             writeln(outfile,'{ C++ end of extern C conditionnal removed }');
-                        end;                        
+                        end;    
+"#ifdef cplusplus"[ \t]*
+                        begin
+                          Inc(cplusblocklevel);
+                        end;   
+"#ifdef __cplusplus"[ \t]*
+                        begin
+                          Inc(cplusblocklevel);
+                        end; 
+"#ifdef"[ \t]
+                        begin
+                           if cplusblocklevel > 0 then
+                             Inc(cplusblocklevel)
+                           else
+                           begin 
+                             if cplusblocklevel < 0 then
+                               Dec(cplusblocklevel);
+                             write(outfile,'{$ifdef ');
+                             copy_until_eol;
+                             writeln(outfile,'}');
+                             flush(outfile);                           
+                           end;
+                        end;                
 "#"[ \t]*"else"         begin
-                           writeln(outfile,'{$else}');
-                           block_type:=bt_no;
-                           flush(outfile);
+                           if cplusblocklevel < -1 then
+                           begin
+                             writeln(outfile,'{$else}');
+                             block_type:=bt_no;
+                             flush(outfile);
+                           end
+                           else
+                             case cplusblocklevel of
+                             0 :
+                                 begin
+                                   writeln(outfile,'{$else}');
+                                   block_type:=bt_no;
+                                   flush(outfile);                                 
+                                 end;
+                             1 : cplusblocklevel := -1;
+                             -1 : cplusblocklevel := 1;
+                             end;
                         end;
 "#"[ \t]*"endif"        begin
-                           writeln(outfile,'{$endif}');
-                           block_type:=bt_no;
-                           flush(outfile);
+                           if cplusblocklevel > 0 then
+                           begin
+                             Dec(cplusblocklevel);
+                           end
+                           else
+                           begin
+                             case cplusblocklevel of
+                               0 : begin
+                                     writeln(outfile,'{$endif}');
+                                     block_type:=bt_no;
+                                     flush(outfile);                               
+                                   end;
+                               -1 : begin
+                                     cplusblocklevel :=0;
+                                    end
+                              else
+                                inc(cplusblocklevel);
+                              end;
+                           end;
+
                         end;
 "#"[ \t]*"elif"         begin
-                           if not stripinfo then
-                             write(outfile,'(*** was #elif ****)');
-                           write(outfile,'{$else');
-                           copy_until_eol;
-                           writeln(outfile,'}');
-                           block_type:=bt_no;
-                           flush(outfile);
+                           if cplusblocklevel < -1 then
+                           begin
+                             if not stripinfo then
+                               write(outfile,'(*** was #elif ****)');
+                             write(outfile,'{$else');
+                             copy_until_eol;
+                             writeln(outfile,'}');
+                             block_type:=bt_no;
+                             flush(outfile);
+                           end
+                           else
+                             case cplusblocklevel of
+                             0 :
+                                 begin
+                                   if not stripinfo then
+                                     write(outfile,'(*** was #elif ****)');
+                                   write(outfile,'{$else');
+                                   copy_until_eol;
+                                   writeln(outfile,'}');
+                                   block_type:=bt_no;
+                                   flush(outfile);                             
+                                 end;
+                             1 : cplusblocklevel := -1;
+                             -1 : cplusblocklevel := 1;
+                             end;                           
                         end;
 "#"[ \t]*"undef"        begin
                            write(outfile,'{$undef');
@@ -741,21 +924,31 @@ D [0-9]
                            writeln(outfile,'}');
                            flush(outfile);
                         end;
-"#"[ \t]*"include"      begin
-                           write(outfile,'{$include');
-                           copy_until_eol;
-                           writeln(outfile,'}');
-                           flush(outfile);
-                           block_type:=bt_no;
-                        end;
+"#"[ \t]*"include"      if NotInCPlusBlock then
+                           begin
+                             write(outfile,'{$include');
+                             copy_until_eol;
+                             writeln(outfile,'}');
+                             flush(outfile);
+                             block_type:=bt_no;
+                           end
+                        else
+                          skip_until_eol;
 "#"[ \t]*"if"           begin
-                           write(outfile,'{$if');
-                           copy_until_eol;
-                           writeln(outfile,'}');
-                           flush(outfile);
-                           block_type:=bt_no;
-                        end;
-"# "[0-9]+" "           begin
+                           if cplusblocklevel > 0 then
+                             Inc(cplusblocklevel)
+                           else
+                           begin 
+                             if cplusblocklevel < 0 then
+                               Dec(cplusblocklevel);
+                             write(outfile,'{$if');
+                             copy_until_eol;
+                             writeln(outfile,'}');
+                             flush(outfile);
+                             block_type:=bt_no;
+                           end;
+                        end; 
+"# "[0-9]+" "           if NotInCPlusBlock then
                           (* preprocessor line info *)
                           repeat
                             c:=get_char;
@@ -768,8 +961,9 @@ D [0-9]
                               #0 :
                                 commenteof;
                             end;
-                          until false;
-                        end;
+                          until false
+                        else
+                          skip_until_eol;
 "#"[ \t]*"pragma"       begin
                            if not stripinfo then
                             begin
@@ -783,55 +977,64 @@ D [0-9]
                             skip_until_eol;
                            block_type:=bt_no;
                         end;
-"#"[ \t]*"define"       begin
-                           commentstr:='';
-                           in_define:=true;
-                           in_space_define:=1;
-                           return(DEFINE);
-                        end;
-"char"                  return(_CHAR);
-"union"                 return(UNION);
-"enum"                  return(ENUM);
-"struct"                return(STRUCT);
-"{"                     return(LGKLAMMER);
-"}"                     return(RGKLAMMER);
-"typedef"               return(TYPEDEF);
-"int"                   return(INT);
-"short"                 return(SHORT);
-"long"                  return(LONG);
-"signed"                return(SIGNED);
-"unsigned"              return(UNSIGNED);
-"__int8"                return(INT8);
-"__int16"               return(INT16);
-"__int32"               return(INT32);
-"__int64"               return(INT64);
-"int8"                  return(INT8);
-"int16"                 return(INT16);
-"int32"                 return(INT32);
-"int64"                 return(INT64);
-"float"                 return(REAL);
-"const"                 return(_CONST);
-"CONST"                 return(_CONST);
-"FAR"                   return(_FAR);
-"far"                   return(_FAR);
-"NEAR"                  return(_NEAR);
-"near"                  return(_NEAR);
-"HUGE"                  return(_HUGE);
-"huge"                  return(_HUGE);
-"while"                 return(_WHILE);
-[A-Za-z_][A-Za-z0-9_]*  begin
-                           if in_space_define=1 then
-                             in_space_define:=2;
-                           return(ID);
-                        end;
-";"                     return(SEMICOLON);
-[ \f\t]                 begin
+"#"[ \t]*"define"       if NotInCPlusBlock then
+                           begin
+                             commentstr:='';
+                             in_define:=true;
+                             in_space_define:=1;
+                             return(DEFINE);
+                           end
+                        else
+                          skip_until_eol;
+"char"                  if NotInCPlusBlock then return(_CHAR) else skip_until_eol;
+"union"                 if NotInCPlusBlock then return(UNION) else skip_until_eol;
+"enum"                  if NotInCPlusBlock then return(ENUM) else skip_until_eol;
+"struct"                if NotInCPlusBlock then return(STRUCT) else skip_until_eol;
+"{"                     if NotInCPlusBlock then return(LGKLAMMER) else skip_until_eol;
+"}"                     if NotInCPlusBlock then return(RGKLAMMER) else skip_until_eol;
+"typedef"               if NotInCPlusBlock then return(TYPEDEF) else skip_until_eol;
+"int"                   if NotInCPlusBlock then return(INT) else skip_until_eol;
+"short"                 if NotInCPlusBlock then return(SHORT) else skip_until_eol;
+"long"                  if NotInCPlusBlock then return(LONG) else skip_until_eol;
+"signed"                if NotInCPlusBlock then return(SIGNED) else skip_until_eol;
+"unsigned"              if NotInCPlusBlock then return(UNSIGNED) else skip_until_eol; 
+"__int8"                if NotInCPlusBlock then return(INT8) else skip_until_eol;
+"__int16"               if NotInCPlusBlock then return(INT16) else skip_until_eol;
+"__int32"               if NotInCPlusBlock then return(INT32) else skip_until_eol;
+"__int64"               if NotInCPlusBlock then return(INT64) else skip_until_eol;
+"int8"                  if NotInCPlusBlock then return(INT8) else skip_until_eol;
+"int16"                 if NotInCPlusBlock then return(INT16) else skip_until_eol;
+"int32"                 if NotInCPlusBlock then return(INT32) else skip_until_eol;
+"int64"                 if NotInCPlusBlock then return(INT64) else skip_until_eol;
+"float"                 if NotInCPlusBlock then return(REAL) else skip_until_eol;
+"const"                 if NotInCPlusBlock then return(_CONST) else skip_until_eol;
+"CONST"                 if NotInCPlusBlock then return(_CONST) else skip_until_eol;
+"FAR"                   if NotInCPlusBlock then return(_FAR) else skip_until_eol;
+"far"                   if NotInCPlusBlock then return(_FAR) else skip_until_eol;
+"NEAR"                  if NotInCPlusBlock then return(_NEAR) else skip_until_eol;
+"near"                  if NotInCPlusBlock then return(_NEAR) else skip_until_eol;
+"HUGE"                  if NotInCPlusBlock then return(_HUGE) else skip_until_eol;
+"huge"                  if NotInCPlusBlock then return(_HUGE) else skip_until_eol;
+"while"                 if NotInCPlusBlock then return(_WHILE) else skip_until_eol;
+[A-Za-z_][A-Za-z0-9_]*  if NotInCPlusBlock then 
+                           begin
+                             if in_space_define=1 then
+                               in_space_define:=2;
+                             return(ID);
+                          end
+                          else 
+                            skip_until_eol;
+";"                     if NotInCPlusBlock then return(SEMICOLON) else skip_until_eol;
+[ \f\t]                 if NotInCPlusBlock then 
+                        begin
                            if (arglevel=0) and (in_space_define=2) then
                             begin
                               in_space_define:=0;
                               return(SPACE_DEFINE);
                             end;
-                        end;
+                        end
+                        else
+                          skip_until_eol;
 \n                      begin
                            if in_define then
                             begin
@@ -843,7 +1046,10 @@ D [0-9]
                               else
                               begin
                                 in_define:=false;
-                                return(NEW_LINE);
+                                if NotInCPlusBlock then 
+                                  return(NEW_LINE)
+                                else
+                                  skip_until_eol                                  
                               end;
                             end;
                        end;