/* uvec2str - copies a uvec into a strmalloc object * - outputs a (char *) ptr else NULL */ char *uvec2str(uvec const *uv, char const *token) { char **argv; char *tmp = (char *) NULL; int i,len = 0, toklen = (int)strlen(token); if (! token) { return tmp; } if (uvec_exists(uv)) { argv = uvec_vector(uv); /* count the total length */ for (i = 0; *argv != (char *) NULL; ++i, ++argv) { if (i) len += toklen; len += strlen(*argv); } /* alloc space */ if ((char *)NULL == (tmp = (uv->str_fns.str_alloc)("", (size_t)(len + 1)))) { return tmp; } /* copy stuff over */ argv = uvec_vector(uv); for (i = 0; *argv != (char *) NULL; ++i, ++argv) { if (i) strcat(tmp, token); strcat(tmp, *argv); } } return tmp; }
int uvec_find(uvec *uv, char const *str, enum uvec_order type) { int i = 0; char **vec; int (*cmp)(void const *, void const *); if (!uvec_exists(uv)) { return -2; } if (uvec_number(uv) > 0) { switch (type) { case UVEC_ASCEND: cmp = uvec_sort_cmp_descend; break; case UVEC_DESCEND: cmp = uvec_sort_cmp_ascend; break; #ifdef HAVE_STRCASECMP case UVEC_CASE_ASCEND: cmp = uvec_sort_cmp_case_descend; break; case UVEC_CASE_DESCEND: cmp = uvec_sort_cmp_case_ascend; break; #endif /* HAVE_STRCASECMP */ default: /* assume case sensitive */ cmp = uvec_sort_cmp_ascend; } } while (*(vec = (uvec_vector(uv) + i))) { if (!(*cmp)(vec, &str)) return i; i++; } return -1; /* string not found */ }
/* uvec_randomize - randomizes the vector - will be deterministic if * use the same seed, However, if seed<=0 then will "randomly" * choose one. */ int uvec_randomize(uvec const *uv, int seed) { char *swap; char **vec, **ptr1, **ptr2; int num, i; if (!uvec_exists(uv)) { return -1; } if (seed <=0) { seed = (int) time(NULL); } if (seed < 0) { return -2; } setseed(seed); num = uvec_number(uv); vec = uvec_vector(uv); /* make 3*number of swaps */ for (i = 0; i < 3*num; ++i) { ptr1 = vec + (int) (num*urand()); ptr2 = vec + (int) (num*urand()); swap = *ptr1; *ptr1 = *ptr2; *ptr2 = swap; } return 0; }
/* uvec_copy - copy one uvec to another unitialized one */ int uvec_copy(uvec *u, uvec const *v) { int rstat; if ((rstat = uvec_copy_vec(u, (char const * const *) uvec_vector(v), uvec_capacity(v)))) { return rstat - 128; } return 0; }
/* uvec_copy_str - create a uvec from a token delimited string * '\' before the token escapes it * ... but it's still possible to confuse the count */ int uvec_copy_str(uvec *u, char const *token, char const *string) { int num = uvec_count_tok(token,string); const char *ptr = string; const char *tokptr; int toklen = (int)strlen(token); int tokfound = 0; int rstat; size_t fraglen; if (num < 0) { return -1; } #if 0 if (! string) { return -2; } #endif /* 0 */ if ((rstat = uvec_init(u, (num + 1)))) { return (rstat - 128); } while (ptr && *ptr) { tokptr = ptr; while (! tokfound) { tokptr = strstr(tokptr, token); if (tokptr && (tokptr > string)) { if (*(tokptr-1) != '\\') { tokfound = 1; } else { tokptr++; continue; } } if ((tokptr == string) || !tokptr) { tokfound = 1; } } tokfound = 0; if (! tokptr) { if ((rstat = uvec_add(u, ptr))) { return (rstat - 128); } break; } else { /* add 1 to length and set last char to \0 */ fraglen = (size_t)(tokptr - ptr); uvec_nadd(u, ptr, (fraglen + 1)); ptr = uvec_vector(u)[uvec_end(u)]; *((char *)ptr + fraglen) = '\0'; } ptr = (tokptr + toklen); } return 0; }
int uvec_qsort(uvec *uv, int (*cmp)(void const *a, void const *b)) { int retval = -1; if (uvec_exists(uv) && cmp) { qsort((void *) uvec_vector(uv), (size_t) uvec_number(uv), sizeof(char *), cmp); return 0; } else { return retval; } }
/* uvec_reverse - reverses the element order of the vector */ int uvec_reverse(uvec const *uv) { int num; char **ptrstart, **ptrend; char *swap; if (!uvec_exists(uv)) { } num = uvec_number(uv); if (num > 1) { /* do reversal */ ptrstart = uvec_vector(uv); ptrend = ptrstart + uvec_end(uv); while (ptrstart < ptrend) { swap = *ptrend; *ptrend-- = *ptrstart; *ptrstart++ = swap; } } return 0; }
/* uvec_uniq - remove all adjacent duplicate elements * type = uvec sorting type ... the import information is whether * to use a caseless comparison or not. */ int uvec_uniq(uvec *uv, enum uvec_order type) { int i = 1; char **vec; int (*cmp)(void const *, void const *); if (!uvec_exists(uv)) { return -1; } if (uvec_number(uv) > 1) { switch (type) { case UVEC_ASCEND: cmp = uvec_sort_cmp_ascend; break; case UVEC_DESCEND: cmp = uvec_sort_cmp_descend; break; #ifdef HAVE_STRCASECMP case UVEC_CASE_ASCEND: cmp = uvec_sort_cmp_case_ascend; break; case UVEC_CASE_DESCEND: cmp = uvec_sort_cmp_case_descend; break; #endif /* HAVE_STRCASECMP */ default: return -2; } while (*(vec = (uvec_vector(uv) + i))) { if ((*cmp)(vec, (vec - 1))) { i++; /* go to next */ } else { uvec_delete(uv,i); /* found match */ } } } return 0; }
static int checkConflict( Tcl_Interp * interp, char *path, char **modulelist, unsigned int nummodules ) { uvec *new_modulelist; int new_nummodules, k; is_Result fstate; char *buffer; memset(error_module, '\0', MOD_BUFSIZE); /** ** Check all modules passed to me as parameter ** At first clarify if they really do exist ... **/ for (k = 0; k < nummodules; k++) { if (!(buffer = stringer(NULL,0,path,psep,modulelist[k],NULL))) if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) goto unwind0; if (!(fstate = is_("what", buffer))) { if (OK != ErrorLogger(ERR_FILEINDIR, LOC, modulelist[k], path, NULL)) if (!stringer(error_module, MOD_BUFSIZE, modulelist[k], NULL)) if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) goto unwind1; goto unwind1; } /** ** Is it a directory what has been passed? If it is, list the ** according directory and call myself recursively in order to **/ if (fstate == IS_DIR) { if (!(new_modulelist = SortedDirList(path, modulelist[k], &new_nummodules))) continue; if (TCL_ERROR == checkConflict(interp, path, uvec_vector(new_modulelist), new_nummodules)) { FreeList(&new_modulelist); goto unwind1; } FreeList(&new_modulelist); /** ** If it isn't a directory, check the current one for to be the ** required module file **/ } else { if (IsLoaded_ExactMatch (interp,modulelist[k],NULL,NULL) && strcmp(g_current_module, modulelist[k])) { /** ** Save the name of the offending module in a buffer ** for reporting purposes when we get back to the top. **/ if (!stringer(error_module, MOD_BUFSIZE, modulelist[k], NULL)) if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) goto unwind1; goto unwind1; } } /** if( directory) **/ } /** for **/ /** ** free resources **/ null_free((void *)&buffer); return (TCL_OK); /** -------- EXIT (SUCCESS) -------> **/ unwind1: null_free((void *)&buffer); unwind0: return (TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/ } /** End of 'checkConflict' **/
int main( int argc, char *argv[], char *environ[] ) { Tcl_Interp *interp; int return_val = 0; char *rc_name; char *rc_path; Tcl_Obj **objv; /** Tcl Object vector **/ int objc; /** Tcl Object vector count **/ #ifdef HAVE_SETLOCALE /* set local via LC_ALL */ setlocale(LC_ALL, ""); #endif #if ENABLE_NLS /* the text message domain. */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif /** ** check if first argument is --version or -V then output the ** version to stdout. This is a special circumstance handled ** by the regular options. **/ if (argc > 1 && *argv[1] == '-') { if (!strcmp("-V", argv[1]) || !strcmp("--version", argv[1])) { version(stdout); return 0; } } /** ** Initialization. **/ if (!(ModulePathVec = ModulePathList())) { ModulePath = NULL; /* goto unwind0; */ } else { ModulePath = uvec_vector(ModulePathVec); } /** ** Check the command line syntax. There will be no return from the ** initialization function in case of invalid command line arguments. **/ if (TCL_OK != Initialize_Module(&interp, argc, argv, environ)) goto unwind1; if (TCL_OK != Setup_Environment(interp)) goto unwind1; /** ** Check for command line switches **/ if (TCL_OK != Check_Switches(&argc, argv)) goto unwind1; /** ** Figure out, which global RC file to use. This depends on the environ- ** ment variable 'MODULERCFILE', which can be set to one of the following: ** ** <filename> --> SYSCONFDIR/<filename> ** <dir>/ --> <dir>/RC_FILE ** <dir>/<file> --> <dir>/<file> ** Use xgetenv to expand 1 level of env.vars. **/ if ((rc_name = xgetenv("MODULERCFILE"))) { /* found something in MODULERCFILE */ if (!(rc_path = stringer(NULL, 0, rc_name, NULL))) { if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) goto unwind2; else null_free((void *)&rc_name); } else { null_free((void *)&rc_name); if (!(rc_name = strrchr(rc_path, *psep))) { rc_name = rc_path; rc_path = etcpath; } else *rc_name++ = '\0'; if (!*rc_name) { rc_name = rc_file; } } } else { rc_path = stringer(NULL,0, etcpath, NULL); null_free((void *)&rc_name); rc_name = rc_file; } /** ** Source the global and the user defined RC file **/ g_current_module = (char *)NULL; if (TCL_ERROR == SourceRC(interp, rc_path, rc_name, Mod_Load) || TCL_ERROR == SourceRC(interp,getenv("HOME"),modulerc_file,Mod_Load)) exit(1); if (rc_path) null_free((void *)&rc_path); /** ** Invocation of the module command as specified in the command line **/ g_flags = 0; Tcl_ArgvToObjv(&objc, &objv, argc - 1, argv + 1); return_val = cmdModule((ClientData) 0, interp, objc, objv); /** ** If we were doing some operation that has already flushed its output, ** then we don't need to re-flush the output here. ** ** Also, if we've had an error here, then the whole modulecmd failed ** and not just the values for a single modulefile. So, we'll pass in ** a NULL here to indicate that any error message should say that ** absolutely NO changes were made to the environment. **/ if (TCL_OK == return_val) { Output_Modulefile_Changes(interp); #ifdef HAS_X11LIBS xresourceFinish(1); #endif } else { Unwind_Modulefile_Changes(interp, NULL); #ifdef HAS_X11LIBS xresourceFinish(0); #endif } /** ** Finally clean up. Delete the required hash tables and conditionally ** allocated areas. **/ Global_Hash_Tables(GHashDelete, NULL); if (line) null_free((void *)&line); if (error_line) null_free((void *)&error_line); /** ** This return value may be evaluated by the calling shell **/ OutputExit(); return (return_val ? return_val : g_retval); /* unwind3: null_free((void *) &rc_path); */ unwind2: null_free((void *)&rc_name); unwind1: FreeList(&ModulePathVec); unwind0: /* and error occurred of some type */ g_retval = (g_retval ? g_retval : 1); OutputExit(); return (g_retval); } /** End of 'main' **/