/* ******************************************************************************* * Copyright (c) 1996 Martin Poole * ******************************************************************************* ** ** WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! ** ** Any changes to be made to this file should first be checked with ** mplib1 source control for library integrity. ** ** mplib1 source control can be reached at mplib1@quatermass.co.uk ** * * $Source: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/vre_parse.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:40 $ * $Revision: 1.2 $ * Purpose : * ******************************************************************************* * * Change History * * $Log: vre_parse.c,v $ * Revision 1.2 2002/10/07 09:37:40 mpoole * Initial checkin of mplib1-3.1.0 * * Revision 1.1 2002/10/07 09:36:57 mpoole * Initial checkin of mplib1-3.1.0 * * ******************************************************************************* */ #ident "$Header: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/vre_parse.c,v 1.2 2002/10/07 09:37:40 mpoole Exp $" /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include #include /* ------------------------------------------------------------------ defines ------------------------------------------------------------------ */ static struct match_token vre_strs[] = { { 1, "^struct" }, { 2, "^};" }, { 3, "^{" }, { 4, "^typedef" }, { 5, "^extern" }, { 6, "^#" }, { 7, "^static" }, { 0, NULL } }; struct achunk { dl_Node_t ac_Node; char ac_Name[1]; }; static struct vre_type_obj *ntyp=NULL; static int doing_struct=0, achunk_init=0; static dl_List_t achunks; /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ static int init_achunks( void ) { if(achunk_init==0) { achunk_init=1; dl_Init_List( &achunks, 0 ); } return(0); } static int check_ptr( char *raw, char **after ) { int rv; while (*raw==' ' || *raw=='\t' || *raw=='(' ) raw++; rv = (*raw=='*'); if (rv) raw++; if (after) *after = raw; return(rv); } static int get_arr_sz( char *cp, char **ncp ) { int rv=0; /* skip whitespace */ while (*cp==' ' || *cp=='\t') cp++; if (*cp == '[') { /* it's an array */ cp++; rv = strtol( cp, ncp, 0 ); }else { if (ncp) *ncp = cp; } return(rv); } static char * get_c_var( char *raw, char **after, int *arr_szp ) { struct achunk *achp; char *sp, *cp; init_achunks(); sp = raw; while (*sp==' ' || *sp=='\t') sp++; cp = sp; if (after) *after = cp; while( isalnum(*cp) || *cp=='_' ) cp++; if (cp - sp) { achp = (struct achunk *)malloc( sizeof(struct achunk) + (cp - sp) ); if (achp) { dl_Init_Node( &achp->ac_Node, achp->ac_Name, achp ); strncpy( achp->ac_Name, sp, (size_t)(cp - sp) ); achp->ac_Name[cp-sp] = '\0'; if (arr_szp) *arr_szp = get_arr_sz( cp, &cp ); if (after) *after = cp; cp = achp->ac_Name; }else cp = NULL; }else cp = NULL; return(cp); } static void free_em( void *vp1, void *vp2 ) { struct achunk *achp= vp1; dl_Remove_Node( &achp->ac_Node ); free( achp ); return; } static void free_c_vars( void ) { init_achunks(); dl_Walk_List( &achunks, (dl_Walk_List_t)free_em, NULL ); return; } static void free_elems( void *vp1, void *vp2 ) { free(vp1); return; } static int End_New_Typ( FILE *fp ) { if (ntyp) { if ( vre_Add_Type(ntyp)==0 ) { fprintf(fp, "Unable to add type <%s>\n", ntyp->to_Name ); dl_Walk_List( &ntyp->to_Elems, (dl_Walk_List_t)free_elems, NULL ); free(ntyp); } ntyp = NULL; } doing_struct = 0; return(0); } static int get_type_and_var( char *dp, char **el_nm, char **tp_nm, int *is_ptr, int *arr_szp, struct vre_type_obj **top ) { int rv=0; char *cp; if (match_string(dp, "^struct", &cp)) dp = cp; if (match_string(dp, "^unsigned", &cp)) dp = cp; *tp_nm = get_c_var( dp, &dp, NULL ); *is_ptr = check_ptr( dp, &dp ); *el_nm = get_c_var( dp, &dp, arr_szp ); if (*el_nm && *tp_nm) { if (*is_ptr) *top = vre_Find_Type( "pointer" ); else *top = vre_Find_Type( *tp_nm ); if (*top) rv=1; } return(rv); } static int Add_Struct_Elem( FILE *fp, char *dp ) { /* struct vre_elem_obj *eop;*/ struct vre_type_obj *top; char *tp_nm,*el_nm; /* off_t offset;*/ int is_ptr, arr_sz; if (ntyp) { if (get_type_and_var( dp, &el_nm, &tp_nm, &is_ptr, &arr_sz, &top )) { if (vre_Cat_New_Elem( ntyp, el_nm, top->to_Name, arr_sz )==NULL) { fprintf( fp, "Unable to create new element <%s>\n", el_nm ); } }else { /* not enough specified */ fprintf( fp, "Unable to add element <%s>\n", (el_nm)?el_nm:"" ); } free_c_vars(); }else { fprintf(fp, "No type currently being defined\n" ); } return(0); } static int do_typedef( FILE *fp, char *dp ) { struct vre_type_obj *top; char *tp_nm,*el_nm; int is_ptr; if (get_type_and_var( dp, &el_nm, &tp_nm, &is_ptr, NULL, &top )) vre_Type_Synonym( el_nm, top->to_Name ); else fprintf( fp, "No name and type for typedef <%s>\n", dp ); free_c_vars(); return(0); } static int Start_New_Typ( FILE *fp, char *dp ) { char *cp; int rv=0; cp = get_c_var( dp, NULL, NULL ); if (cp) { ntyp = vre_New_Type( cp, NULL, 0, 0, 0 ); if (ntyp==NULL) { fprintf( fp, "Unable to create new type <%s>\n", cp ); }else rv = 1; } free_c_vars(); return(rv); } int vre_Parse_Line( FILE *fp, char *line ) { char *str,*dp; str = strdup( line ); if(str) { /* skip leading whitespace */ while ( *str==' ' || *str=='\t' ) str++; /* OK let's start cutting it up */ switch(match_a_string( str, vre_strs, &dp )) { case 1 : /* it's a type */ if (doing_struct) { Add_Struct_Elem( fp, dp ); }else { End_New_Typ( fp ); if (Start_New_Typ( fp, dp )) doing_struct = 1; } break; case 2 : /* end of structure */ End_New_Typ( fp ); break; case 3 : /* ignore */ break; case 4 : /* typedef */ do_typedef( fp, dp ); break; case 5 : /* extern */ case 6 : /* hash */ case 7 : /* hash */ break; default : /* whoops */ if (ntyp && doing_struct) { /* try and parse as structure element */ Add_Struct_Elem( fp, str ); } else { fprintf( fp, "Unrecognised command <%s>\n", str ); } break; } free(str); } return(0); } int vre_Parse_File( FILE *fp, const char *fname ) { FILE *ifh; char tbuf[500],*cp; ifh=fopen(fname,"r"); if (ifh) { while(fgetline(ifh,tbuf,500)==0) { cp = tbuf; /* skip leading whitespace */ while ( *cp==' ' || *cp=='\t' ) cp++; if (strlen(cp)) vre_Parse_Line( fp, cp ); } fclose(ifh); } return(0); } /* -- End of File -- */