/* ******************************************************************************* * 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_alloc.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:40 $ * $Revision: 1.2 $ * Purpose : * ******************************************************************************* * * Change History * * $Log: vre_alloc.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_alloc.c,v 1.2 2002/10/07 09:37:40 mpoole Exp $" /* vre2disp.c vogon record editor. Display only version ******************************************************************** Copyright 1989,90,91,94,95 Martin Poole Released for use by Y2 Computing Limited - 1990 Released for use by Perot Systems Europe Limited - 1995. ******************************************************************** */ /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include #include /* ------------------------------------------------------------------ defines ------------------------------------------------------------------ */ static dl_List_t object_list; static int done_init=0; static FILE *err_fp=NULL; /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ static int init_obj_list( void ) { if (done_init==0) { done_init=1; dl_Init_List( &object_list, LN_IGNORECASE ); } return(0); } int vre_Init_VRE( FILE *fp ) { err_fp = fp; init_obj_list(); return(0); } static struct vre_type_obj * alloc_type( const char *nm ) { struct vre_type_obj *top; top = (struct vre_type_obj *)malloc( sizeof(struct vre_type_obj) + strlen(nm) ); if (top) { dl_Init_Node( &top->to_Node, top->to_Name, top ); top->to_Flags = 0; top->to_Disp = (vre_disp_t)NULL; dl_Init_List( &top->to_Elems, LN_IGNORECASE ); strcpy( top->to_Name, nm ); } return(top); } struct vre_type_obj * vre_Find_Type( const char *nm ) { init_obj_list( ); return( (struct vre_type_obj *) dl_Find_Item_By_Name( &object_list, nm )); } int vre_Add_Type( struct vre_type_obj *top ) { int rv=0; init_obj_list( ); if (!dl_Find_Item_By_Name( &object_list, top->to_Name )) { dl_Add_Tail( &object_list, &top->to_Node ); rv = 1; } return(rv); } struct vre_type_obj * vre_Type_Synonym( const char *nm, const char *synm ) { struct vre_type_obj *top=NULL,*top2; init_obj_list( ); top2 = (struct vre_type_obj *)dl_Find_Item_By_Name( &object_list, synm ); if (top2) { top = (struct vre_type_obj *)dl_Find_Item_By_Name( &object_list, nm ); if (top) return(NULL); top = alloc_type( nm ); if (top) { top->to_Flags = TO_TYPEDEF; top->to_Disp = (vre_disp_t)top2; top->to_Size = top2->to_Size; top->to_Align = top2->to_Align; dl_Add_Tail( &object_list, &top->to_Node ); } } return(top); } struct vre_type_obj * vre_New_Type( const char *nm, vre_disp_t disp, size_t isize, int ialign, int add ) { struct vre_type_obj *top; init_obj_list( ); top = (struct vre_type_obj *)dl_Find_Item_By_Name( &object_list, nm ); if (top) return(NULL); top = alloc_type( nm ); if (top) { if (disp) { top->to_Flags = TO_DISPLAY; top->to_Disp = disp; } else { top->to_Flags = TO_COMPOSITE; top->to_Disp = (vre_disp_t)NULL; } top->to_Size = isize; top->to_Align = ialign; if (add) dl_Add_Tail( &object_list, &top->to_Node ); } return(top); } struct vre_elem_obj * vre_New_Elem( const char *nm, const char *typ, off_t offset, int arr_sz ) { struct vre_elem_obj *eop=NULL; size_t als; init_obj_list( ); if (dl_Find_Item_By_Name( &object_list, typ )) { /* Type exists so allow creation */ als = sizeof(struct vre_elem_obj) + (size_t)(strlen(nm) + strlen(typ) + 1); eop = malloc( als ); if (eop) { strcpy( eop->eo_Type, typ ); eop->eo_Name = eop->eo_Type + strlen(eop->eo_Type) + 1; strcpy( eop->eo_Name, nm ); dl_Init_Node( &eop->eo_Node, eop->eo_Name, eop ); eop->eo_Offset = offset; eop->eo_Arr_sz = arr_sz; } }else if (err_fp) fprintf( err_fp, "Cannot find type <%s\n", typ ); return(eop); } struct vre_elem_obj * vre_Cat_New_Elem( struct vre_type_obj *ntyp, const char *el_nm, const char *el_typ, int arr_sz ) { struct vre_elem_obj *eop=NULL; struct vre_type_obj *top; off_t offset; top = vre_Find_Type( el_typ ); if (ntyp && top) { offset = (ntyp->to_Size + (top->to_Align - 1)) & ~(top->to_Align - 1); eop = vre_New_Elem( el_nm, top->to_Name, offset, arr_sz ); if (eop) { dl_Add_Tail( &ntyp->to_Elems, &eop->eo_Node ); /* and now adjust the typ size */ if (ntyp->to_Align < top->to_Align) { /* set the align acording to the largest alignment */ ntyp->to_Align = top->to_Align; } if (offset>= ntyp->to_Size) { /* it's on the end of the structure */ if (arr_sz > 1) ntyp->to_Size = offset + (top->to_Size * arr_sz); else ntyp->to_Size = offset + top->to_Size; } }else { if (err_fp) fprintf( stderr, "Unable to create new element <%s>\n", el_nm ); } }else { /* not enough specified */ if (err_fp) fprintf( stderr, "Unable to add element <%s><%s>\n", el_nm, el_typ ); } return(eop); } static void disp_this_type( struct vre_type_obj *top, struct vre_disp_walk_item *dwip ); /* forward definition */ static void disp_elems( struct vre_elem_obj *eop, struct vre_disp_walk_item *dwip ) { struct vre_type_obj *top; const void *optr; const char *olds; char *cp; top = dl_Find_Item_By_Name( &object_list, eop->eo_Type ); if (top) { cp = malloc( strlen(dwip->prefix) + strlen(eop->eo_Name) + 1 ); if (cp) { optr = dwip->ptr; dwip->ptr = ((const char *)dwip->ptr + eop->eo_Offset); olds = dwip->prefix; dwip->prefix = cp; sprintf( cp, "%s%s", olds, eop->eo_Name ); dwip->eop = eop; dwip->top = top; disp_this_type( top, dwip ); free( cp ); dwip->prefix = olds; dwip->ptr = optr; }else { fprintf( dwip->fp, " ** Cannot allocate for recursion **\n" ); } } return; } int vre_Disp_Prefix( FILE *fp, const void *ptr, const void *base, const char *prefix, const char *suffix ) { static char e_str[]="\0"; fprintf( fp, "%08x %s%s ", (int)((const char *)ptr - (const char *)base), (prefix)?prefix:e_str, (suffix)?suffix:e_str ); return(0); } static void disp_this_type( struct vre_type_obj *top, struct vre_disp_walk_item *dwip ) { const char *olds; char *cp; if (dwip->flags & VRE_DISP_ELEM_NAMES) vre_Disp_Prefix( dwip->fp, dwip->ptr, dwip->base, dwip->prefix, NULL ); while ( top && (top->to_Flags & TO_TYPEDEF)) top = (struct vre_type_obj *)top->to_Disp; if (top) { if (top->to_Flags & TO_DISPLAY) { (* top->to_Disp)( dwip->ptr, dwip ); fputc( '\n', dwip->fp ); }else { cp = malloc( strlen(dwip->prefix) + strlen(top->to_Name) + 2 ); if (cp) { olds = dwip->prefix; dwip->prefix = cp; if (dwip->flags & VRE_DISP_ELEM_NAMES) sprintf( cp, "%s.", olds ); fputc( '\n', dwip->fp ); dl_Walk_List( &top->to_Elems, (dl_Walk_List_t)disp_elems, dwip ); free( cp ); dwip->prefix = olds; }else { fprintf( dwip->fp, " ** Cannot allocate for recursion **\n" ); } } }else { fprintf( dwip->fp, " ** Cannot find type for display **\n" ); } return; } int vre_Get_Info( const char *el_nm, size_t *isize, int *ialign, off_t *offset, int *arr_sz, int *flags ) { struct vre_type_obj *top; struct vre_elem_obj *eop; int rv=0; off_t soff; char *pstr; char *cp; void *tokptr; static char seps[]="."; pstr = strdup(el_nm); if (pstr) { /* mark off the single word */ cp = strstr( pstr, "\t " ); if (cp) *cp = '\0'; /* set things up and walk the elements adding up the details */ cp=mpstrtok( pstr, &tokptr, seps ); if (cp) { top = vre_Find_Type( cp ); if (top) { soff=0; eop = (struct vre_elem_obj *) -1; while ( (cp = mpstrtok( NULL, &tokptr, seps )) && eop && top ) { eop = (struct vre_elem_obj *)dl_Find_Item_By_Name( &top->to_Elems, cp ); if (eop) { soff += eop->eo_Offset; top = vre_Find_Type( eop->eo_Type ); } }; if (eop && top) { if (offset) *offset = soff; if (isize) *isize = top->to_Size; if (arr_sz) *arr_sz = eop->eo_Arr_sz; if (ialign) *ialign = top->to_Align; rv = 1; } } } (void)mpstrtok( NULL, &tokptr, NULL ); free(pstr); } return(rv); } off_t vre_Get_Offset( const char *el_nm ) { off_t offset= -1,soff; if ( vre_Get_Info( el_nm, NULL, NULL, &soff, NULL, NULL )) offset=soff; return(offset); } int vre_Disp_Item( FILE *fp, const char *type, const char *name, const void *ptr, const void *base, int flags, void *u_param ) { struct vre_type_obj *top; struct vre_disp_walk_item dwi; init_obj_list( ); top = (struct vre_type_obj *)dl_Find_Item_By_Name( &object_list, type ); if (top) { dwi.fp = fp; dwi.prefix = (name)?name:type; dwi.ptr = ptr; dwi.base = base; dwi.flags = flags; dwi.u_param = u_param; disp_this_type( top, &dwi ); }else { fprintf(fp, "Cannot find object of type <%s>\n", type ); } return(0); } static void disp_elem( void *vp1, void *vp2 ) { FILE *fp; struct vre_elem_obj *eop; eop = vp1; fp = vp2; fprintf( fp, " Name: %s Offset: %08lx Arr: %08x Type: %s\n", eop->eo_Name, eop->eo_Offset, eop->eo_Arr_sz, eop->eo_Type ); return; } static void disp_type( void *vp1, void *vp2 ) { FILE *fp; struct vre_type_obj *top; top = vp1; fp = vp2; if (top->to_Flags & TO_TYPEDEF) { struct vre_type_obj *top2; top2 = top; if (top2 && (top2->to_Flags & TO_TYPEDEF)); top2 = (struct vre_type_obj *) top2->to_Disp; fprintf( fp, "Type: %s\n Flags: %08x Display: %p (%s)\n", top->to_Name, top->to_Flags, top->to_Disp, top2->to_Name ); }else fprintf( fp, "Type: %s\n Flags: %08x Display: %p\n", top->to_Name, top->to_Flags, top->to_Disp ); fprintf( fp, " Size: %08x Align: %08x\n", top->to_Size, top->to_Align ); dl_Walk_List( &top->to_Elems, (dl_Walk_List_t)disp_elem, fp ); return; } int vre_Disp_Types( FILE *fp, int flags ) { dl_Walk_List( &object_list, (dl_Walk_List_t)disp_type, fp ); return(0); } /* -- End of File -- */