]> git.draconx.ca Git - gob-dx.git/blobdiff - src/parse.y
Release 2.0.16
[gob-dx.git] / src / parse.y
index 53d32eb3d055fd0f82314be3b71b8adbeccedaaa..b8792bbfa387600d088de35dde8d15d22a0c72b9 100644 (file)
@@ -1,7 +1,7 @@
 /* GOB C Preprocessor
  * Copyright (C) 1999-2000 the Free Software Foundation.
  * Copyright (C) 2000 Eazel, Inc.
- * Copyright (C) 2001-2004 George (Jiri) Lebl
+ * Copyright (C) 2001-2009 George (Jiri) Lebl
  *
  * Author: George Lebl
  *
@@ -65,6 +65,7 @@ static char *initializer = NULL;
 static int initializer_line = 0;
 static int glade_widget = FALSE;
 
+static char *funcattrs = NULL;
 static char *onerror = NULL;
 static char *defreturn = NULL;
 
@@ -205,6 +206,7 @@ push_function (int scope, int method, char *oid, char *id,
                         "flags:steal", flags,
                         "id:steal", id,
                         "args:steal", funcargs,
+                        "funcattrs:steal", funcattrs,
                         "onerror:steal", onerror,
                         "defreturn:steal", defreturn,
                         "cbuf:steal", c_cbuf,
@@ -224,6 +226,7 @@ push_function (int scope, int method, char *oid, char *id,
        gtktypes = NULL;
        funcargs = NULL;
 
+       funcattrs = NULL;
        onerror = NULL;
        defreturn = NULL;
 
@@ -233,6 +236,8 @@ push_function (int scope, int method, char *oid, char *id,
 static void
 free_all_global_state(void)
 {
+       g_free(funcattrs);
+       funcattrs = NULL;
        g_free(onerror);
        onerror = NULL;
        g_free(defreturn);
@@ -336,9 +341,15 @@ find_var_or_die(const char *id, int line)
 }
 
 static gboolean
-set_return_value(char *type, char *val)
+set_attr_value(char *type, char *val)
 {
-       if(strcmp(type, "onerror")==0) {
+       if(strcmp(type, "attr")==0) {
+               if(!funcattrs) {
+                       funcattrs = val;
+                       return TRUE;
+               } else
+                       return FALSE;
+       } else if(strcmp(type, "onerror")==0) {
                if(!onerror) {
                        onerror = val;
                        return TRUE;
@@ -473,7 +484,6 @@ add_construct_glade (char * file, char * root, char * domain)
 {
        Node *var;
        Type * type;
-       GList * flags = NULL;
        
        type = (Type *)node_new (TYPE_NODE,
                                 "name", "GladeXML",
@@ -678,7 +688,7 @@ ensure_property (void)
 %token SIGNED UNSIGNED LONG SHORT INT FLOAT DOUBLE CHAR
 
 %token <id> TOKEN NUMBER TYPETOKEN ARRAY_DIM SINGLE_CHAR
-%token <cbuf> CCODE HTCODE PHCODE HCODE ACODE ATCODE STRING
+%token <cbuf> CCODE ADCODE HTCODE PHCODE HCODE ACODE ATCODE STRING
 %token <line> PUBLIC PRIVATE PROTECTED CLASSWIDE PROPERTY ARGUMENT
 %token <line> VIRTUAL SIGNAL OVERRIDE
 %token <line> NICK BLURB MAXIMUM MINIMUM DEFAULT_VALUE ERROR FLAGS TYPE
@@ -701,6 +711,15 @@ ccode:             CCODE                   {
                        nodes = g_list_append(nodes,node);
                        g_string_free($<cbuf>1,FALSE);
                                        }
+       |       ADCODE                  {
+                       Node *node = node_new (CCODE_NODE,
+                                              "cctype", AD_CCODE,
+                                              "cbuf:steal", ($<cbuf>1)->str,
+                                              "line_no", ccode_line,
+                                              NULL);
+                       nodes = g_list_append(nodes,node);
+                       g_string_free($<cbuf>1,FALSE);
+                                       }
        |       HCODE                   {
                        Node *node = node_new (CCODE_NODE,
                                               "cctype", H_CCODE,
@@ -1665,7 +1684,7 @@ codenocode:       '{' CCODE                       { $<cbuf>$ = $<cbuf>2; }
        ;
 
 /*here CCODE will include the ending '}' */
-method:                SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenocode {
+method:                SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' methodmods codenocode {
                        if(!has_self) {
                                yyerror(_("signal without 'self' as "
                                          "first parameter"));
@@ -1677,11 +1696,18 @@ method:         SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc
                                free_all_global_state();
                                YYERROR;
                        }
+                       if (funcattrs != NULL) {
+                               char *error = g_strdup_printf
+                                       (_("function attribute macros ('%s' in this case) may not be used with signal methods"),
+                                        funcattrs);
+                               yyerror (error);
+                               YYERROR;
+                       }
                        push_function(the_scope, $<sigtype>3,NULL,
                                      $<id>5, $<cbuf>10,$<line>1,
                                      ccode_line, vararg, $<list>2);
                                                                        }
-       |       scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' returnvals codenocode {
+       |       scope SIGNAL flags simplesigtype type TOKEN '(' funcargs ')' methodmods codenocode {
                        if(!has_self) {
                                yyerror(_("signal without 'self' as "
                                          "first parameter"));
@@ -1693,11 +1719,18 @@ method:         SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc
                                free_all_global_state();
                                YYERROR;
                        }
+                       if (funcattrs != NULL) {
+                               char *error = g_strdup_printf
+                                       (_("function attribute macros ('%s' in this case) may not be used with signal methods"),
+                                        funcattrs);
+                               yyerror (error);
+                               YYERROR;
+                       }
                        push_function(the_scope, $<sigtype>4, NULL,
                                      $<id>6, $<cbuf>11, $<line>2,
                                      ccode_line, vararg, $<list>3);
                                                                        }
-       |       VIRTUAL scope type TOKEN '(' funcargs ')' returnvals codenocode {
+       |       VIRTUAL scope type TOKEN '(' funcargs ')' methodmods codenocode {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
                                          "first parameter"));
@@ -1709,11 +1742,18 @@ method:         SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc
                                free_all_global_state();
                                YYERROR;
                        }
+                       if (funcattrs != NULL) {
+                               char *error = g_strdup_printf
+                                       (_("function attribute macros ('%s' in this case) may not be used with virtual methods"),
+                                        funcattrs);
+                               yyerror (error);
+                               YYERROR;
+                       }
                        push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>4,
                                      $<cbuf>9, $<line>1,
                                      ccode_line, vararg, NULL);
                                                                        }
-       |       scope VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode {
+       |       scope VIRTUAL type TOKEN '(' funcargs ')' methodmods codenocode {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
                                          "first parameter"));
@@ -1725,28 +1765,49 @@ method:         SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc
                                free_all_global_state();
                                YYERROR;
                        }
+                       if (funcattrs != NULL) {
+                               char *error = g_strdup_printf
+                                       (_("function attribute macros ('%s' in this case) may not be used with virtual methods"),
+                                        funcattrs);
+                               yyerror (error);
+                               YYERROR;
+                       }
                        push_function(the_scope, VIRTUAL_METHOD, NULL, $<id>4,
                                      $<cbuf>9, $<line>2,
                                      ccode_line, vararg, NULL);
                                                                        }
-       |       VIRTUAL type TOKEN '(' funcargs ')' returnvals codenocode       {
+       |       VIRTUAL type TOKEN '(' funcargs ')' methodmods codenocode       {
                        if(!has_self) {
-                               yyerror(_("virtual method without 'self' as "
+                               yyerror(_("virtual method without 'szelf' as "
                                          "first parameter"));
                                free_all_global_state();
                                YYERROR;
                        }
+                       if (funcattrs != NULL) {
+                               char *error = g_strdup_printf
+                                       (_("function attribute macros ('%s' in this case) may not be used with virtual methods"),
+                                        funcattrs);
+                               yyerror (error);
+                               YYERROR;
+                       }
                        push_function(PUBLIC_SCOPE, VIRTUAL_METHOD, NULL,
                                      $<id>3, $<cbuf>8, $<line>1,
                                      ccode_line, vararg, NULL);
                                                                        }
-       |       OVERRIDE '(' TYPETOKEN ')' type TOKEN '(' funcargs ')' returnvals codenocode    {
+       |       OVERRIDE '(' TYPETOKEN ')' type TOKEN '(' funcargs ')' methodmods codenocode    {
+                       if (funcattrs != NULL) {
+                               char *error = g_strdup_printf
+                                       (_("function attribute macros ('%s' in this case) may not be used with override methods"),
+                                        funcattrs);
+                               yyerror (error);
+                               YYERROR;
+                       }
                        push_function(NO_SCOPE, OVERRIDE_METHOD, $<id>3,
                                      $<id>6, $<cbuf>11,
                                      $<line>1, ccode_line,
                                      vararg, NULL);
                                                                        }
-       |       scope type TOKEN '(' funcargs ')' returnvals codenocode {
+       |       scope type TOKEN '(' funcargs ')' methodmods codenocode {
                        if(the_scope == CLASS_SCOPE) {
                                yyerror(_("a method cannot be of class scope"));
                                free_all_global_state();
@@ -1767,22 +1828,40 @@ method:         SIGNAL flags fullsigtype type TOKEN '(' funcargs ')' returnvals codenoc
                                push_function(NO_SCOPE, CLASS_INIT_METHOD, NULL,
                                              $<id>1, $<cbuf>5, $<line>2,
                                              ccode_line, FALSE, NULL);
+                       } else if(strcmp($<id>1, "constructor")==0) {
+                               push_init_arg($<id>3, FALSE);
+                               push_function(NO_SCOPE, CONSTRUCTOR_METHOD, NULL,
+                                             $<id>1, $<cbuf>5, $<line>2,
+                                             ccode_line, FALSE, NULL);
+                       } else if(strcmp($<id>1, "dispose")==0) {
+                               push_init_arg($<id>3, FALSE);
+                               push_function(NO_SCOPE, DISPOSE_METHOD, NULL,
+                                             $<id>1, $<cbuf>5, $<line>2,
+                                             ccode_line, FALSE, NULL);
+                       } else if(strcmp($<id>1, "finalize")==0) {
+                               push_init_arg($<id>3, FALSE);
+                               push_function(NO_SCOPE, FINALIZE_METHOD, NULL,
+                                             $<id>1, $<cbuf>5, $<line>2,
+                                             ccode_line, FALSE, NULL);
+
                        } else {
                                g_free($<id>1);
                                g_free($<id>3);
                                g_string_free($<cbuf>5,TRUE);
                                yyerror(_("parse error "
-                                         "(untyped blocks must be init or "
-                                         "class_init)"));
+                                         "(untyped blocks must be init, "
+                                         "class_init, constructor, dispose "
+                                         "or finalize)"));
                                YYERROR;
                        }
                                                }
        ;
 
-returnvals:    TOKEN retcode           {
+methodmods:    TOKEN retcode           {
+                       g_free(funcattrs); funcattrs = NULL;
                        g_free(onerror); onerror = NULL;
                        g_free(defreturn); defreturn = NULL;
-                       if(!set_return_value($<id>1, $<id>2)) {
+                       if(!set_attr_value($<id>1, $<id>2)) {
                                g_free($<id>1);
                                g_free($<id>2);
                                yyerror(_("parse error"));
@@ -1791,16 +1870,17 @@ returnvals:     TOKEN retcode           {
                        g_free($<id>1);
                                        }
        |       TOKEN retcode TOKEN retcode     {
+                       g_free(funcattrs); funcattrs = NULL;
                        g_free(onerror); onerror = NULL;
                        g_free(defreturn); defreturn = NULL;
-                       if(!set_return_value($<id>1, $<id>2)) {
+                       if(!set_attr_value($<id>1, $<id>2)) {
                                g_free($<id>1); g_free($<id>2);
                                g_free($<id>3); g_free($<id>4);
                                yyerror(_("parse error"));
                                YYERROR;
                        }
-                       if(!set_return_value($<id>3, $<id>4)) {
-                               onerror = defreturn = NULL;
+                       if(!set_attr_value($<id>3, $<id>4)) {
+                               funcattrs = onerror = defreturn = NULL;
                                g_free($<id>1); g_free($<id>2);
                                g_free($<id>3); g_free($<id>4);
                                yyerror(_("parse error"));
@@ -1809,7 +1889,39 @@ returnvals:      TOKEN retcode           {
                        g_free($<id>1);
                        g_free($<id>3);
                                                }
+       |       TOKEN retcode TOKEN retcode TOKEN retcode       {
+                       g_free(funcattrs); funcattrs = NULL;
+                       g_free(onerror); onerror = NULL;
+                       g_free(defreturn); defreturn = NULL;
+                       if(!set_attr_value($<id>1, $<id>2)) {
+                               g_free($<id>1); g_free($<id>2);
+                               g_free($<id>3); g_free($<id>4);
+                               g_free($<id>5); g_free($<id>6);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+                       if(!set_attr_value($<id>3, $<id>4)) {
+                               funcattrs = onerror = defreturn = NULL;
+                               g_free($<id>1); g_free($<id>2);
+                               g_free($<id>3); g_free($<id>4);
+                               g_free($<id>5); g_free($<id>6);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+                       if(!set_attr_value($<id>5, $<id>6)) {
+                               funcattrs = onerror = defreturn = NULL;
+                               g_free($<id>1); g_free($<id>2);
+                               g_free($<id>3); g_free($<id>4);
+                               g_free($<id>5); g_free($<id>6);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+                       g_free($<id>1);
+                       g_free($<id>3);
+                       g_free($<id>5);
+                                               }
        |                               {
+                       g_free(funcattrs); funcattrs = NULL;
                        g_free(onerror); onerror = NULL;
                        g_free(defreturn); defreturn = NULL;
                                        }