/* ******************************************************************************* * 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_loop.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:40 $ * $Revision: 1.2 $ * Purpose : * ******************************************************************************* * * Change History * * $Log: vre_loop.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_loop.c,v 1.2 2002/10/07 09:37:40 mpoole Exp $" /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #ifdef INCLUDE_GETOPT #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* ------------------------------------------------------------------ defines ------------------------------------------------------------------ */ static struct match_token com_2[] = { { 1, "^set" }, { 2, "^show" }, { 3, "^define" }, { 4, "^read" }, { 5, "^vars" }, { 6, "^types" }, { 0, NULL } }; static struct match_token mod_sizes[] = { { 1, "^byte" }, { 2, "^word" }, { 3, "^long" }, { 4, "^string" }, { 0, NULL } }; static char last_list[]="Last values"; static char ADDR[]="addr"; static char TYPE[]="type"; static char whitespace[]="\t "; static void *my_seg_base=NULL; static char *last_type=NULL; /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ static int get_last_int( char *key ) { return( get_private_int( last_list, key )); } static char * get_last_str( char *key ) { return( get_private_string( last_list, key )); } static int set_last_int( char *key, int newval ) { return( set_private_int( last_list, key, newval )); } static int set_last_str( char *key, char *newval ) { return( set_private_string( last_list, key, newval )); } static int get_hex_param( char *np, char **nnp ) { int rv; rv = strtol( np, nnp, 16 ); return(rv); } static int get_val_at( int pval, size_t isize ) { int rv; if ( isize == 1 || pval & 1) { /* char boundary */ rv = *(unsigned char *)((unsigned char *)my_seg_base + pval); }else if ( isize==2 || pval & 2) { rv = *(unsigned short *)((unsigned char *)my_seg_base + pval); }else { rv = *(unsigned long *)((unsigned char *)my_seg_base + pval); } return(rv); } int vre_Get_ADDR( char *np, char **nnp ) { int use_contents=0; size_t isize=(size_t)4; int last_val; off_t offv; void *tokptr; last_val = get_last_int( ADDR ); if ( np && (np = mpstrtok( np, &tokptr, whitespace )) && np && *np == '@') { use_contents=1; np++; } if (np && *np) { /* is it an element */ if ( vre_Get_Info( np, &isize, NULL, &offv, NULL, NULL )) { /* it is, so add it to the last value */ last_val += offv; }else { int new_val; char *tp; new_val = get_hex_param( np, &tp ); if (tp!=np) last_val = new_val; } np = mpstrtok( NULL, &tokptr, whitespace ); } (void) mpstrtok( NULL, &tokptr, NULL ); if (nnp) *nnp = np; if (use_contents) last_val = get_val_at( last_val, isize ); set_last_int( ADDR, last_val ); return(last_val); } static int change_a_loc( FILE *fp, void *vp, char *np ) { char *nnp; off_t offst; int what,ln; size_t isize; void *tokptr; what = match_a_string( np, mod_sizes, &nnp ); if (what==0) { nnp = mpstrtok( np, &tokptr, whitespace ); if( vre_Get_Info( nnp, &isize, NULL, &offst, NULL, NULL )) { if (isize==4) isize--; what = isize; offst += vre_Get_ADDR( NULL, NULL ); nnp = mpstrtok( NULL, &tokptr, whitespace ); } (void) mpstrtok( NULL, &tokptr, NULL ); }else { offst = (off_t)get_hex_param( nnp, &nnp ); } switch (what) { case 1 : /* byte */ ln = get_hex_param( nnp, NULL ); *(unsigned char *)((char *)vp + offst) = ln; break; case 2 : /* word */ ln = get_hex_param( nnp, NULL ); *(unsigned short *)((char *)vp + offst) = ln; break; case 3 : /* long */ ln = get_hex_param( nnp, NULL ); *(unsigned long *)((char *)vp + offst) = ln; break; case 4 : /* string */ strcpy( (char *)vp + offst, nnp ); break; default : fprintf( fp, "Unknown size\n" ); break; } return(1); } static char * get_last_type( char *np, char **nnp ) { char *cp; char *rv; void *tokptr; rv = get_last_str( TYPE ); np = mpstrtok( np, &tokptr, whitespace ); if (np && *np) { cp = mpstrtok( NULL, &tokptr, whitespace ); if (vre_Find_Type(np)) { /* got a valid type */ rv = np; } if (nnp) { *nnp = (cp)?cp:(np+strlen(np)); } }else { if (nnp) *nnp = np; } mpstrtok( NULL, &tokptr, NULL ); if (last_type!=NULL) free( last_type ); if (rv) { last_type = strdup(rv); set_last_str( TYPE, rv ); }else last_type = rv; return(last_type); } static int show_something( FILE *fp, void *vp, char *np ) { char *tp_nm,*of_pt; off_t offst; tp_nm = get_last_type( np, &of_pt ); if (tp_nm) { offst = vre_Get_ADDR( of_pt, NULL ); vre_Disp_Item( fp, tp_nm, NULL, (char *)vp + offst, vp, VRE_DISP_ELEM_NAMES, NULL ); } return(0); } static int list_vars( FILE *fp, char *np ) { fprintf( fp, "ADDR=%x\n", get_last_int( ADDR ) ); fprintf( fp, "TYPE=%s\n", get_last_str( TYPE ) ); return(0); } int vre_Interactive_Loop( char *line, FILE *fp, void *base ) { char *lbuf; char *np=NULL; int sv; off_t soff; my_seg_base = base; lbuf=strdup(line); if (lbuf) { sv = match_a_string( lbuf, com_2, &np ); switch( sv ) { case 1 : /* set */ change_a_loc( fp, base, np ); break; case 2 : /* show */ show_something( fp, base, np ); break; case 3 : /* define */ vre_Parse_Line( fp, np ); break; case 4 : /* read */ vre_Parse_File( fp, eval_config_default( NULL, np ) ); break; case 5 : /* list variables */ list_vars( fp, np ); break; case 6 : /* list types */ vre_Disp_Types( fp, 0 ); break; default : if (strlen(lbuf)) { soff = vre_Get_ADDR( lbuf, NULL ); fprintf( fp, "ADDR=%x\n", (int)soff ); } } free(lbuf); } return(1); } /* -- End of File -- */