daemon@stag.UUCP (11/23/87)
It seems that in the source code which accompanies the recently posted extended argument passing proposal, I assumed the existence of some functions and a header file which are in dLibs, but are missing from the libraries of some other C compilers. The following code fragments are extracted from dLibs for the benifit of those trying to use the new XARG structure under other compiler/library combinations. ----------------------------------CUT--HERE--------------------------------- [BASEPAGE.H] /* * BASEPAGE.H Definition of the basepage structure */ typedef struct { char *p_lowtpa; char *p_hitpa; char *p_tbase; long p_tlen; char *p_dbase; long p_dlen; char *p_bbase; long p_blen; char *p_dta; char *p_parent; char *p_reserved; char *p_env; long p_undefined[20]; char p_cmdlin[128]; } BASEPAGE; [STRTOK.C] #include <stdio.h> static char *_strtok = NULL; /* local token pointer */ char *strtok(string, delim) register char *string; register char *delim; /* * Return a token from <string>. If <string> in not NULL, it is * the beginning of a string from which tokens are to be extracted. * Characters found in <delim> are skipped over to find the start * of a token, characters are then accumulated until a character in * <delim> is found, or the terminator of <string> is reached. * A pointer to the '\0' terminated token is then returned. Note * that this function modifies <string> (by inserting '\0's) in * the process. Subsequent calls to strtok() may specify NULL as * the <string> argument, in which case subsequent tokens are * returned, or NULL if there are no more tokens. */ { register char *p; char *strchr(); if(string == NULL) string = _strtok; while(*string && strchr(delim, *string)) ++string; if(*string == '\0') /* no more tokens */ return(NULL); p = string; while(*string && !strchr(delim, *string)) ++string; if(*string != '\0') *string++ = '\0'; _strtok = string; return(p); } [BLKCPY.S] * char *blkcpy(dest, source, len) * register char *dest; * register char *source; * register int len; * /* * * Copies the <source> block to the <dest>. <len> bytes are * * always copied. No terminator is added to <dest>. A pointer * * to <dest> is returned. * */ * { * register char *p = dest; * * if(source < dest) * { * dest += len; * source += len; * while(len--) * *--dest = *--source; * } * else * { * while(len--) * *dest++ = *source++; * } * return(p); * } .text .globl _lblkcpy _lblkcpy: move.l 12(a7),d0 ; number of bytes bra blkcpy0 .globl _blkcpy _blkcpy: move.w 12(a7),d0 ; number of bytes blkcpy0: move.l 4(a7),a1 ; destination move.l 8(a7),a0 ; source cmp.l a0,a1 ; check copy direction ble blkcpy4 add.l d0,a0 ; move pointers to end add.l d0,a1 bra blkcpy2 blkcpy1: move.b -(a0),-(a1) ; (s < d) copy loop blkcpy2: dbra d0,blkcpy1 bra blkcpy5 blkcpy3: move.b (a0)+,(a1)+ ; (s >= d) copy loop blkcpy4: dbra d0,blkcpy3 blkcpy5: move.l 4(a7),d0 ; return destination pointer rts [PUTENV.C] #include <stdio.h> extern char *_envp; #define ENVSIZ 2048 static int envset = FALSE; /* local env created? */ int putenv(entry) char *entry; /* * Add <entry> to the environment. <entry> can be any of the following * forms: * <VARIABLE> * <VARIABLE>= * <VARIABLE>=<value> * The first form removes <VARIABLE> from the environment. getenv() * will return NULL if looking for this variable. The second form adds * <VARIABLE> to the environment, with a null value. getenv() will * return a pointer to a '\0' character if looking for this variable. * Many environment handlers don't support such "tag variables", so * their use is not recommended. The final form is the most common, * and safest to use. <VARIABLE> is installed (or replaced) with the * value <value>. It should be noted that this function itself is not * supported in many systems and should be used will care to prevent * overflowing the space allocated for the environment. */ { register char *p, *q, *t, c; register int len; char *malloc(), *getenv(); if(!envset) /* no local env */ { if((p = malloc(ENVSIZ)) == NULL) return(FALSE); q = _envp; _envp = p; envset = TRUE; if(q) { while(*q) while(*p++ = *q++) ; } else *p++ = '\0'; *p++ = '\0'; *p = 0xFF; } for(t=entry; (c = *t) && (c != '='); ++t) ; *t = '\0'; if(p = getenv(entry)) /* remove old var */ { q = p; while(*q++) /* find end of old val */ ; p -= (len = strlen(entry)); while(strncmp(--p, entry, len)) /* find start of old var */ ; while(*q) /* copy environment tail */ while(*p++ = *q++) ; *p++ = '\0'; /* tie off environment */ *p = 0xFF; } if(c == '=') /* install new var */ { p = _envp; while(*p) /* find end of env */ while(*p++) ; *t = c; q = entry; while(*p++ = *q++) /* copy new entry */ ; *p++ = '\0'; /* tie off environment */ *p = 0xFF; } return(TRUE); } ----------------------------------CUT--HERE--------------------------------- You should also check the operation of your strchr() and strrchr() functions. If '\0' is specified as the character to search for, these functions should return a pointer to the '\0' which terminates the string. This is how the Un*x libraries (at least the ones I've used) work, and the XARG code uses strrchr() in this way. I've included putenv(), but not getenv() since most libraries provide one already. If you need getenv(), send me mail and I'll send you a copy of one that handles MWC-style and TOS-style environment variable, even if they are intermixed (*ack*). Dale Schumacher ..ihnp4!meccts!stag!syntel!dal (alias: Dalnefre')