]> git.draconx.ca Git - gob-dx.git/blobdiff - src/lexer.l
Release 0.92.2
[gob-dx.git] / src / lexer.l
index 0037b85181537998dce2b3ebe8401a4b7e0b3b95..d896eb2f4b504e997ae87ab60081eb68b1da441c 100644 (file)
 
 #include "config.h"
 #include <glib.h>
+#include <string.h>
 
 #include "parse.h"
+#include "main.h"
+#include "util.h"
 
 static int parenth_depth = 0;
 static int before_comment = INITIAL;
-static int class_after_c = FALSE;
-static int header_c = FALSE;
+static gboolean class_after_c = FALSE;
+static int code_type = CCODE;
 
 static GString *cbuf = NULL;
 int ccode_line = 1;
 
+GList *include_files = NULL;
+/* 0 no, 1 means yes, 2+ means don't even start looking anymore */
+static int look_for_includes = 0;
+
 int line_no = 1;
 
 static void
@@ -70,6 +77,23 @@ add_to_cbuf(char *s)
 <*>MOTHERFUCKER                { fprintf(stderr,"You are a bad bad person!\n"); REJECT; }
 
 \/\/.*$                        { ; /*comment, ignore*/ }
+<C_CODE>^#[ \t]*include[ \t][<"][^\n">]*[>"] {
+       if(look_for_includes==1) {
+               char *p;
+               char *file;
+               char *str = g_strdup(yytext);
+               file = strchr(str,'"');
+               if(!file) file = strchr(str,'<');
+               file++;
+               p = strchr(file,'"');
+               if(!p) p = strchr(file,'>');
+               *p = '\0';
+               include_files = g_list_prepend(include_files,g_strdup(file));
+               g_free(str);
+       }
+       REJECT;
+}
+
 <C_CODE>\/\/.*$                { add_to_cbuf(yytext); /*comment, ignore*/ }
 <CLASS_CODE>\/\/.*$    { ; /*comment, ignore*/ }
 <CLASS_CODE_I>\/\/.*$  { ; /*comment, ignore*/ }
@@ -94,11 +118,27 @@ add_to_cbuf(char *s)
        if(before_comment == C_CODE) add_to_cbuf(yytext);
                }
 
-^\%h\{         {
+^\%(ht|headertop)\{            {
                        BEGIN(C_CODE);
                        parenth_depth = 1;
                        class_after_c = FALSE;
-                       header_c = TRUE;
+                       code_type = HTCODE;
+                       clear_cbuf();
+                       ccode_line = line_no;
+               }
+^\%(ph|privateheader)\{                {
+                       BEGIN(C_CODE);
+                       parenth_depth = 1;
+                       class_after_c = FALSE;
+                       code_type = PHCODE;
+                       clear_cbuf();
+                       ccode_line = line_no;
+               }
+^\%(h|header)\{                {
+                       BEGIN(C_CODE);
+                       parenth_depth = 1;
+                       class_after_c = FALSE;
+                       code_type = HCODE;
                        clear_cbuf();
                        ccode_line = line_no;
                }
@@ -106,18 +146,19 @@ add_to_cbuf(char *s)
                        BEGIN(C_CODE);
                        parenth_depth = 1;
                        class_after_c = FALSE;
-                       header_c = FALSE;
+                       code_type = CCODE;
                        clear_cbuf();
                        ccode_line = line_no;
+                       if(look_for_includes==0)
+                               look_for_includes=1;
                }
 <C_CODE>^\%\}  {
                        BEGIN(INITIAL);
                        yylval.cbuf = cbuf;
                        cbuf = NULL;
-                       if(header_c)
-                               return HCODE;
-                       else
-                               return CCODE;
+                       if(look_for_includes==1)
+                               look_for_includes=0;
+                       return code_type;
                }
 
 <C_CODE>\'\{\'         { add_to_cbuf(yytext); }
@@ -161,10 +202,47 @@ add_to_cbuf(char *s)
 <C_CODE>\n     { add_to_cbuf(yytext); }
 
 class          {
+                       look_for_includes = 2;
                        BEGIN(CLASS_CODE);
                        return CLASS;
                }
 
+^[ \t]*requires[ \t]+[0-9]+\.[0-9]+\.[0-9]+[\t ]*$     {
+                       int maj = 0,min = 0,pl = 0;
+                       int rmaj = 0,rmin = 0,rpl = 0;
+                       char *p;
+                       
+                       sscanf(VERSION,"%d.%d.%d",&rmaj,&rmin,&rpl);
+                       p = strchr(yytext,'r');
+                       g_assert(p); /* we MUST have found it */
+                       sscanf(p,"requires %d.%d.%d",&maj,&min,&pl);
+                       if(rmaj < maj ||
+                          (rmaj == maj && rmin < min) ||
+                          (rmaj == maj && rmin == min && rpl < pl)) {
+                               char *s;
+                               s = g_strdup_printf(
+                                   "GOB version %d.%d.%d required "
+                                   "(this is %s)\n"
+                                   "To upgrade your gob, see: "
+                                   "http://www.5z.com/jirka/gob.html",
+                                   maj,min,pl,VERSION);
+                               print_error(FALSE,s, line_no);
+                               g_free(s);
+                       }
+               }
+
+<CLASS_CODE,CLASS_CODE_I>class|this    {
+                       if(for_cpp) {
+                               char *s;
+                               s = g_strdup_printf("'%s' keyword should not "
+                                                   "be used when generating "
+                                                   "C++ code",yytext);
+                               print_error(TRUE,s, line_no);
+                               g_free(s);
+                       }
+                       REJECT;
+               }
+
 <CLASS_CODE>from       {return FROM;}
 
 <CLASS_CODE_I>void     {return VOID;}
@@ -185,6 +263,7 @@ class               {
 
 <CLASS_CODE_I>public   {yylval.line = line_no; return PUBLIC;}
 <CLASS_CODE_I>private  {yylval.line = line_no; return PRIVATE;}
+<CLASS_CODE_I>protected        {yylval.line = line_no; return PROTECTED;}
 <CLASS_CODE_I>argument {yylval.line = line_no; return ARGUMENT;}
 <CLASS_CODE_I>virtual  {yylval.line = line_no; return VIRTUAL;}
 <CLASS_CODE_I>signal   {yylval.line = line_no; return SIGNAL;}
@@ -203,6 +282,11 @@ class              {
                        return TOKEN;
                }
 
+<CLASS_CODE_I>(\[[0-9]*\])+    {
+                       yylval.id = g_strdup(yytext);
+                       return ARRAY_DIM;
+               }
+
 <CLASS_CODE>\{ {
                        BEGIN(CLASS_CODE_I);
                        return '{';
@@ -211,8 +295,9 @@ class               {
                        BEGIN(C_CODE);
                        parenth_depth=1;
                        class_after_c = TRUE;
-                       ccode_line = line_no;
                        yylval.line = line_no;
+                       clear_cbuf();
+                       ccode_line = line_no;
                        return '{';
                }
 <CLASS_CODE_I>\}       {