Changeset 287


Ignore:
Timestamp:
Apr 1, 2007, 12:52:34 PM (18 years ago)
Author:
cinc
Message:

Implemented interface forward declaration.

Location:
trunk/idl-compiler
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/idl-compiler/h-emitter_c/h_file_emitter.c

    r282 r287  
    7272}
    7373
    74 
    75 static void emitParentHeader(PPARSEINFO pLocalPI, PINTERFACE pif)
    76 {
    77   FILE* fh=pLocalPI->outFile;
    78   PINTERFACE pifParent=getParentInterface(pif);
    79 
    80   /* Include header of parent */
    81   if(pifParent){
    82     fprintf(fh, "/* Include for the parent class */\n");
    83     if(pifParent->chrFileStem)
    84       fprintf(fh, "#include \"%s.h\"\n\n", pifParent->chrFileStem);
    85   }
     74/**
     75   This function writes an #include statement to the header for each found
     76   interface. Thus all the interface information is known to the sourcefile
     77   using this header.
     78 */
     79static void emitInterfaceIncludes(PPARSEINFO pLocalPI, PINTERFACE pif)
     80{
     81  FILE* fh=pLocalPI->outFile;
     82  int a;
     83
     84  for(a=0;a<pLocalPI->pInterfaceArray->len;a++)
     85    {
     86      PINTERFACE pifAll=g_ptr_array_index(pLocalPI->pInterfaceArray, a);
     87
     88      fprintf(fh, "/* Include for class %s */\n", pifAll->chrName);
     89      if(pifAll->chrFileStem)
     90        fprintf(fh, "#include \"%s.h\"\n", pifAll->chrFileStem);
     91    }
     92  fprintf(fh, "\n");
    8693}
    8794
     
    332339            {
    333340              emitHFileHeader(pLocalPI, pif);
    334               emitParentHeader(pLocalPI, pif);
     341              emitInterfaceIncludes(pLocalPI, pif);
    335342              emitClassVersion(pLocalPI, pif);
    336343              emitClassDataStructs(pLocalPI, pif);
  • trunk/idl-compiler/include/parser.h

    r280 r287  
    7373}METHOD, *PMETHOD;
    7474
     75/* Info about a symbol */
     76typedef struct
     77{
     78  gchar* chrSymbolName;
     79  guint  uiSymbolToken;
     80  guint  uiKind;
     81}SYMBOL, *PSYMBOL;
     82
    7583/* Struct holding all the info of a defined or declared interface */
    7684typedef struct
     
    8189  gulong ulMinor;    /* Class version            */
    8290  gboolean fIsForwardDeclaration;
     91  PSYMBOL pSymbolIFace; /* Found interfaces are registered as a symbol with the parser.
     92                           This is a pointer to the registered struct holding the necessary
     93                           info and may be used to deregister a symbol later.*/
     94  PSYMBOL pSymbolIFacePtr; /* Same as before but for the pointer on an interface which is
     95                            registered automatically. */
    8396  gboolean fIsInRootFile;
    8497  gchar* chrMetaClass; /* Pointer to metaclass name or NULL*/
     
    91104}INTERFACE,*PINTERFACE;
    92105
    93 /* Info about a symbol */
    94 typedef struct
    95 {
    96   gchar* chrSymbolName;
    97   guint  uiSymbolToken;
    98   guint  uiKind;
    99 }SYMBOL, *PSYMBOL;
    100106
    101107typedef struct
  • trunk/idl-compiler/parser_c/interface_parser.c

    r275 r287  
    4646{
    4747  PSYMBOL pNewSymbol=g_malloc0(sizeof(SYMBOL));
     48
     49  pParseInfo->pCurInterface->pSymbolIFace=pNewSymbol;
    4850
    4951  if(!strcmp(pParseInfo->chrRootSourceFile, pParseInfo->pCurInterface->chrSourceFileName))
     
    6567     to the interface. */
    6668  pNewSymbol=g_malloc0(sizeof(SYMBOL));
     69  pParseInfo->pCurInterface->pSymbolIFacePtr=pNewSymbol;
    6770  pNewSymbol->uiKind=KIND_TYPESPEC;
    6871  pNewSymbol->uiSymbolToken=IDL_SYMBOL_REGINTERFACE;
     
    7275                             pNewSymbol);
    7376  //g_message("%s: %s", __FUNCTION__, pNewSymbol->chrSymbolName);
     77}
     78
     79static void deRegisterInterface(PINTERFACE pif)
     80{
     81  /* Remove the interface from our list */
     82  g_ptr_array_remove(pParseInfo->pInterfaceArray, (gpointer) pif);
     83
     84  /* Any found interface was registered as a new type so it can be
     85     used in other classes. */
     86  g_tree_remove(pParseInfo->pSymbolTree, pif->pSymbolIFace);
     87
     88  g_scanner_scope_remove_symbol(gScanner, ID_SCOPE, pif->pSymbolIFace->chrSymbolName);
     89  /* For legacy support and convenience we automatically registered a pointer type
     90     to the interface. */
     91  g_tree_remove(pParseInfo->pSymbolTree, pif->pSymbolIFacePtr);
     92  g_scanner_scope_remove_symbol(gScanner, ID_SCOPE, pif->pSymbolIFacePtr->chrSymbolName);
     93  /* We don't clean up. Looking at the whole mess with string dupes and stuff in side the
     94     structs I just decided to use a GC instead... */
    7495}
    7596
     
    164185  Note that the current token is the 'interface' keyword.
    165186
    166   I:= IDL_SYMBOL_INTERFACE G_TOKEN_INDENTIFIER
     187  I:= IDL_SYMBOL_INTERFACE G_TOKEN_IDENTIFIER
    167188 */
    168189static void parseIFace(GTokenType token)
    169190{
    170   if(!matchNext(G_TOKEN_IDENTIFIER))
    171     {
     191  if(matchNext(G_TOKEN_IDENTIFIER))
     192    {
     193      /* Save interface info */
     194      GTokenValue value=gScanner->value;
     195      pParseInfo->pCurInterface->chrName=g_strdup(value.v_identifier);
     196    }
     197  else
     198    if(matchNext(G_TOKEN_SYMBOL))
     199      {
     200        /* If the interface name is a symbol, it means the interface was
     201           already registered before. Maybe because of a forward statement.
     202           We will check that in the function which called us. */
     203       
     204        /* Check if it's one of our interface symbols */
     205        PSYMBOL pCurSymbol;
     206        GTokenValue value;
     207       
     208        value=gScanner->value;
     209        pCurSymbol=value.v_symbol;
     210        if(IDL_SYMBOL_REGINTERFACE!=pCurSymbol->uiSymbolToken)
     211          {
     212            //g_message("%s %d", pCurSymbol->chrSymbolName, pCurSymbol->uiKind);
     213            g_scanner_unexp_token(gScanner,
     214                                  G_TOKEN_SYMBOL,
     215                                  NULL,
     216                                  NULL,
     217                                  NULL,
     218                                  "Keyword 'interface' is not followed by a valid identifier.",
     219                                  TRUE); /* is_error */
     220            exit(1);
     221          }
     222       
     223        /* Save interface info */
     224        pParseInfo->pCurInterface->chrName=g_strdup(value.v_identifier);
     225      }
     226    else{
    172227      g_scanner_unexp_token(gScanner,
    173228                            G_TOKEN_IDENTIFIER,
     
    179234      exit(1);
    180235    }
    181   /* Save interface info */
    182   GTokenValue value=gScanner->value;
    183   pParseInfo->pCurInterface->chrName=g_strdup(value.v_identifier);
    184236}
    185237
     
    273325                            "No opening brace in interface definition.",
    274326                            TRUE); /* is_error */
    275       exit(1);
    276      
     327      exit(1);     
    277328    }
    278329  parseIFaceBody();
     
    301352  /* Get the interface name */
    302353  parseIFace(token);
    303   pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile);
    304 
    305   /* It's save to register the interface right here even if the struct is almost empty.
    306      If anything goes wrong later we will exit anyway. */
    307   registerInterface(); 
    308 
    309   if(matchNext(';'))
    310     {
     354
     355  if(matchNext(';')) /* forward declaration */
     356    {
     357      PINTERFACE pif;
     358
     359      /* Check if we already have a (maybe forward) declaration */
     360      pif=findInterfaceFromName(pParseInfo->pCurInterface->chrName);
     361      if(pif)
     362        {
     363          g_free(pParseInfo->pCurInterface);
     364        }
     365      pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile);
    311366      pParseInfo->pCurInterface->fIsForwardDeclaration=TRUE;
    312     }
    313   else if(matchNext(':'))
    314     {
    315       parseSubclassedIFace();
    316     }
    317   else if(matchNext('{'))
    318     {
    319       parseIFaceBody();
     367      /* It's save to register the interface right here even if the struct is almost empty.
     368         If anything goes wrong later we will exit anyway. */
     369      registerInterface(); 
    320370    }
    321371  else
    322372    {
    323       g_message("Line %d: Error in interface declaration",  g_scanner_cur_line(gScanner));
    324       exit(0);
    325     }
    326 }
    327 
     373      PINTERFACE pif;
     374
     375      /* Check if we already have a (maybe forward) declaration */
     376      pif=findInterfaceFromName(pParseInfo->pCurInterface->chrName);
     377      if(pif)
     378        {
     379          if(pif->fIsForwardDeclaration)
     380            {
     381              /* Remove the forward declaration and insert the real thing afterwards. */
     382              deRegisterInterface(pif);
     383            }
     384          else
     385            {
     386              /* Oops, we already have an interface declaration */
     387              g_scanner_unexp_token(gScanner,
     388                                    G_TOKEN_SYMBOL,
     389                                    NULL,
     390                                    NULL,
     391                                    NULL,
     392                                    "An interface with this name was already declared.",
     393                                    TRUE); /* is_error */
     394              exit(1);
     395            }
     396        }
     397      pParseInfo->pCurInterface->chrSourceFileName=g_strdup(pParseInfo->chrCurrentSourceFile);
     398      pParseInfo->pCurInterface->fIsForwardDeclaration=TRUE;
     399      /* It's save to register the interface right here even if the struct is almost empty.
     400         If anything goes wrong later we will exit anyway. */
     401      registerInterface(); 
     402      if(matchNext(':'))
     403        {
     404         
     405          parseSubclassedIFace();
     406        }
     407      else if(matchNext('{'))
     408        {         
     409          parseIFaceBody();
     410        }
     411      else
     412        {
     413          g_message("Line %d: Error in interface declaration",  g_scanner_cur_line(gScanner));
     414          exit(0);
     415        }
     416    }
     417}
     418
Note: See TracChangeset for help on using the changeset viewer.