/* ******************************************************************************* * Copyright (c) 1997 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/build_argv.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:37 $ * $Revision: 1.2 $ * ******************************************************************************* * * Change History * * $Log: build_argv.c,v $ * Revision 1.2 2002/10/07 09:37:37 mpoole * Initial checkin of mplib1-3.1.0 * * Revision 1.1 2002/10/07 09:36:54 mpoole * Initial checkin of mplib1-3.1.0 * * ******************************************************************************* */ #ident "$Header: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/build_argv.c,v 1.2 2002/10/07 09:37:37 mpoole Exp $" /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include #include #include #include /* ------------------------------------------------------------------ defines ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ static struct argv_track * init_argv_track( struct argv_track *argvtp ) { if (argvtp==NULL) argvtp = malloc( sizeof(struct argv_track) ); if (argvtp) { dl_Init_Node( &argvtp->v_node, NULL, argvtp ); dl_Init_List( &argvtp->m_track, 0 ); dl_Init_List( &argvtp->v_parts, 0 ); dl_Init_List( &argvtp->f_track, 0 ); argvtp->argv = NULL; argvtp->argc = 0; } return(argvtp); } void free_argv_track( struct argv_track *argvtp ) { if (argvtp) { dl_Walk_List( &argvtp->m_track, (dl_Walk_List_t)free, NULL ); init_argv_track( argvtp ); free( argvtp ); } return; } static int track_this( struct argv_track *argvtp, dl_List_t *tlist, void *tp ) { dl_Node_t *np; int rv; np = dl_Remove_Head( &argvtp->f_track ); if (np==NULL) { int t=5; np = malloc( NODE_SIZE * t ); if (np) { dl_Init_Node( np, NULL, np ); dl_Add_Tail( &argvtp->m_track, np++ ); while(--t) { dl_Init_Node( np, NULL, np ); dl_Add_Tail( &argvtp->f_track, np++ ); }; np = dl_Remove_Head( &argvtp->f_track ); }; } if (np) { dl_Init_Node( np, NULL, tp ); dl_Add_Tail( tlist, np ); rv=1; } else rv=0; return(rv); } static int split_this( struct argv_track *argvtp, char *raw ) { char *cp; int rv=0; void *tokptr; static char seps[]=" \t\n"; /* printf("parse: %s\n", raw );*/ cp = mpstrtok( raw, &tokptr, seps ); while( cp ) { /* Now add this item to the v_part list */ /* printf("track: %s\n", cp );*/ /* First we expand the parameter if needed */ if (strchr(cp,'$') || strchr(cp,'%')) { cp = strdup( eval_config_default( NULL, cp ) ); track_this( argvtp, &argvtp->m_track, cp ); } track_this( argvtp, &argvtp->v_parts, cp ); cp = mpstrtok( NULL, &tokptr, seps ); } (void)mpstrtok( NULL, &tokptr, NULL ); return(rv); } static void count_em( void *vp, int *nc ) { *nc = *nc +1; return; } static void v_init( char *cp, char ***vp ) { /* printf("v_add: %p=%s\n", *vp, cp);*/ **vp = cp; *vp = *vp+1; return; } static int build_argv( struct argv_track *argvtp ) { char **vp; int rv=0; /* Now count the number of elements */ argvtp->argc=0; dl_Walk_List( &argvtp->v_parts, (dl_Walk_List_t)count_em, &argvtp->argc ); /* Add the terminating NULL pointer */ track_this( argvtp, &argvtp->v_parts, NULL ); /* Now allocate a suitable array of pointers */ vp = malloc( (argvtp->argc+1) * sizeof(char *) ); if (vp) { /* printf("char pointer array: %p\n", vp );*/ track_this( argvtp, &argvtp->m_track, vp ); argvtp->argv = vp; /* Looks good so far */ dl_Walk_List( &argvtp->v_parts, (dl_Walk_List_t)v_init, &vp ); rv=1; } return(rv); } struct argv_track * build_argv_track( struct argv_track *argvtp, ... ) { va_list ap; char *cp,*rcp; free_argv_track(argvtp); argvtp = init_argv_track( argvtp ); if (argvtp) { va_start(ap,argvtp); while ( (cp = va_arg(ap, char* )) ) { /* dup, split, and add this string to the argv list */ rcp = strdup(cp); track_this( argvtp, &argvtp->m_track, rcp ); split_this( argvtp, rcp ); }; va_end(ap); build_argv( argvtp ); } return(argvtp); } /* -- End of File -- */