home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Boldly Go Collection
/
version40.iso
/
TS
/
17A
/
DRWIN101.ZIP
/
STRUTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-27
|
45KB
|
970 lines
/*
This module contains c utility routines.
*/
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <alloc.h>
#include <dos.h>
#include <ctype.h>
#include "strutil.h"
char* _hextab="0123456789ABCDEF0"; /*used for hex translations*/
int pnum; //number of parameters parsed
int ppos[MAX_PARAMS]; //offset of each parameter
int plen[MAX_PARAMS]; //length of each parameter
/****************************************************************************/
/* strgetch */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function returns the key pressed. If a special function key is */
/* pressed, it returns the scan code of the key + 256. */
/* Constants are defined in [cutil.h] for use with this function. */
/*-----------------------------Arguments------------------------------------*/
/*-----------------------------Return value---------------------------------*/
/* Returns 256+scan code for special keys, ASCII value for others. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Constraints----------------------------------*/
/*--Date--------Programmer---------Comments---------------------------------*/
/* 1990.01.01 D. Rogers initial code */
/****************************************************************************/
int strgetch(void)
{
int c;
c=getch();
if (c)
return(c);
else
return(0x0100+getch());
} /*strgetch*/
/****************************************************************************/
/****************************************************************************/
/* strdattim */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function returns a string which contains the current date and */
/* time in a format which depends on the argument: */
/* 0 YYYY.MM.DD HH:MM:SS */
/* 1 MM/DD/YY HH:MM:SS */
/* 2 DD/MM/YY HH:MM:SS */
/*-----------------------------Arguments------------------------------------*/
/*-----------------------------Return value---------------------------------*/
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Constraints----------------------------------*/
/*--Date--------Programmer-------------Comments-----------------------------*/
/* 1989.10.XX Doug Rogers */
/****************************************************************************/
char *strdattim(WORD form)
{
static char dt[40];
struct date d;
struct time t;
getdate(&d);
gettime(&t);
switch (form) {
case 2:
sprintf(dt,"%02d/%02d/%02d %02d:%02d:%02d",
d.da_day,d.da_mon,d.da_year%100,t.ti_hour,t.ti_min,t.ti_sec);
break;
case 1:
sprintf(dt,"%02d/%02d/%02d %02d:%02d:%02d",
d.da_mon,d.da_day,d.da_year%100,t.ti_hour,t.ti_min,t.ti_sec);
break;
case 0:
default:
sprintf(dt,"%04d.%02d.%02d %02d:%02d:%02d",
d.da_year,d.da_mon,d.da_day,t.ti_hour,t.ti_min,t.ti_sec);
} /*switch*/
return (dt);
} /*strdattim*/
/****************************************************************************/
/****************************************************************************/
/* strsub */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Copies substring of length len starting at position pos in s into the */
/* destination string d. */
/*-----------------------------Arguments------------------------------------*/
/* char* s source string for operation */
/* int pos position (offset) in source string for substring */
/* int len length of substring */
/* char* d destination string to hold substring */
/*-----------------------------Return value---------------------------------*/
/* Returns the destination string pointer, d. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/* No check is performed on the size of the destination string. */
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
char* strsub(char *s,int pos,int len,char *d)
{
s=&s[pos];
while (len-- && *s) *d++=*s++;
*d=0;
return d;
} /*strsub*/
/****************************************************************************/
/* strNcpy */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Copies from source string s to destination up to n characters. If n */
/* is specified as 0, no length checking is performed. This differs from */
/* strncpy() in that it always places a 0 in the (n-1)st offset of d. */
/*-----------------------------Arguments------------------------------------*/
/* char* d destination string pointer */
/* char* s source string pointer */
/* int n number of characters to copy, max, including term */
/*-----------------------------Return value---------------------------------*/
/* Returns d. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
char* strNcpy(char* d,char* s,int n)
{
n--; /*leave room for terminator*/
if (n<0) /*if infinite copy..*/
strcpy(d,s); /*..copy forever*/
else { /*otherwise..*/
strncpy(d,s,n); /*..copy up to n*/
d[n]=0; /*..make sure terminator is there*/
} /*else limit*/
return d;
} /*strNcpy*/
/****************************************************************************/
/* strisalnum */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Determines if the string s contains only alphanumerics. */
/*-----------------------------Arguments------------------------------------*/
/* char* s string to check */
/*-----------------------------Return value---------------------------------*/
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int strisalnum(char *s)
{
while (*s) if (!isalnum(*s++)) return 0;
return 1;
} /*strisalnum*/
/****************************************************************************/
/* strcmpshort, stricmpshort */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Compares two strings up to the length of string t. strcmpshort() is */
/* case-sensitive, stricmpshort() is not. */
/*-----------------------------Arguments------------------------------------*/
/* char* s pointer to string to compare */
/* char* t pointer to string to compare against */
/*-----------------------------Return value---------------------------------*/
/* Return 1 if s is greater than t, 0 if they are equal, and -1 if s is */
/* less than t. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/* These functions do NOT return 1 is the strings are equal. They are */
/* like the <string.h> strcmp() and stricmp() functions. */
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int strcmpshort(char* s,char* t)
{
while (*t) {
if (*s<*t) return -1;
if (*s>*t) return +1;
s++;
t++;
} /*while*/
return 0;
} /*strcmpshort*/
int stricmpshort(char* s,char* t)
{
char sc,tc;
while (*t) {
sc=*s;
tc=*t;
if (_upper(sc)<_upper(tc)) return -1;
if (_upper(sc)>_upper(tc)) return +1;
s++;
t++;
} /*while*/
return 0;
} /*stricmpshort*/
/****************************************************************************/
/* strcompress */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Strips all extraneous whitespace from a string. Whitespace at the */
/* beginning and the end of the string is deleted and all other */
/* whitespace is reduced to a single space. */
/* If quoted text (either with ' or ") appears, that text is left */
/* unaltered. n is the size of the destination, including termination. */
/* If n is specified as 0, no limit will be placed on the size of the */
/* destination string. */
/*-----------------------------Arguments------------------------------------*/
/* char* d place to put resulting string (could be same as s) */
/* char* s string to compress */
/* int n size of destination string */
/*-----------------------------Return value---------------------------------*/
/* Returns d. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
char* strcompress(char* d,char* s,int n)
{
enum {START,INWORD,WHITE,QUOTE,END};
int j=0;
int state;
char q,c;
n--; /*leave room for NUL*/
state=START; /*starting state*/
for (;*s && ((j<n)||(n<0));s++) {
c=*s;
switch (state) {
case START:
if ((c=='\"') || (c=='\'')) {
q=c;
d[j++]=c;
state=QUOTE;
} /* if 1 */
else if (!isspace(c)) {
d[j++]=c;
state=INWORD;
} /* else 1 */
break; /* case START */
case INWORD:
if ((c=='\"') || (c=='\'')) {
q=c;
d[j++]=c;
state=QUOTE;
}
else if (isspace(c)) {
d[j++]=' ';
state=WHITE;
}
else {
d[j++]=c;
}
break; /* case INWORD */
case WHITE:
if ((c=='\"') || (c=='\'')) {
q=c;
d[j++]=c;
state=QUOTE;
}
else if (!isspace(c)) {
d[j++]=c;
state=INWORD;
}
break; /* case WHITE */
case QUOTE:
if (c==q) {
d[j++]=c;
state=INWORD;
}
else
d[j++]=c;
break; /* case QUOTE */
default : state=INWORD; break;
} /* switch */
} /* for */
if (state==WHITE) j--;
d[j]=0;
return d;
} /*strcompress*/
/* strcomment ***************************************************************/
/* */
/* This routine places a NUL at the position of the first comment char. */
/* */
/*************************************************** Doug Rogers 1989.01.12 */
char* strcomment(char *s,char comchar)
{
enum {START,NORMAL,WHITE,QUOTE,END};
int i,state;
char q;
state=START;
for (i=0;(s[i]!=0)&&(state!=END);i++) {
switch (state) {
case START:
if (s[i]==comchar) {
s[i]=0;
state=END;
}
else if ((s[i]=='\"') || (s[i]=='\'')) {
q=s[i];
state=QUOTE;
} /* if 1 */
else if (!isspace(s[i])) {
state=NORMAL;
} /* else 1 */
break; /* case START */
case NORMAL:
if (s[i]==comchar) {
s[i]=0;
state=END;
}
else if ((s[i]=='\"') || (s[i]=='\'')) {
q=s[i];
state=QUOTE;
}
else if (isspace(s[i])) {
state=WHITE;
}
else {
}
break; /* case NORMAL */
case WHITE:
if (s[i]==comchar) {
s[i]=0;
state=END;
}
else if ((s[i]=='\"') || (s[i]=='\'')) {
q=s[i];
state=QUOTE;
}
else if (!isspace(s[i])) {
state=NORMAL;
}
break; /*case WHITE*/
case QUOTE:
if (s[i]==q) {
state=NORMAL;
}
break; /*case QUOTE*/
default : state=END; break;
} /*switch*/
} /*for*/
return (s);
} /*strcomment*/
/****************************************************************************/
/* strcchr, strcstr */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This procedure converts string s into d in a C-like manner. The */
/* special characters are: */
/* \0 NUL (00h) \a BEL (07h) */
/* \b BS (08h) \t TAB (09h) */
/* \n LF (0Ah) \v VT (0Bh) */
/* \f FF (0Ch) \r CR (0Dh) */
/* * \e ESC (1Bh) \\ \ (5Ch) */
/* \" " (22h) \' ' (27h) */
/* \OOO up to three octal digits for ASCII code (1st D: 1<=D<=9) */
/* \xHH up to two hex digits for ASCII code (\XHH) */
/* * \dDDD up to three decimal digits */
/* *=non-standard conversion */
/* strcchr: */
/* Sets only one character (pointed to by d). Returns a pointer to the */
/* next character in the source string. */
/* strcstr: */
/* Returns the length of the new string. */
/* n is the size of the destination, including the terminating NUL char. */
/* If n is specified as 0, no limit will be placed on the size of the */
/* destination string. */
/*-----------------------------Arguments------------------------------------*/
/* char* d destination string */
/* char* s source string */
/* int maxn size of destination string */
/*-----------------------------Return value---------------------------------*/
/* strcchr: */
/* Returns pointer to next char in source string. */
/* strcstr: */
/* Returns length of destination string. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int /*inline*/ digval(char c)
{
if ((c>='0')&&(c<='9')) return c-'0';
if ((c>='A')&&(c<='Z')) return c-'A'+10;
if ((c>='a')&&(c<='z')) return c-'a'+10;
return 37;
} /*digval*/
char* strcchr(char* d,char* s)
{
int n=0;
int dig=0;
int base=8;
char c;
c=*s++;
if (c!='\\') { //if not a special char
*d=c; //..just copy it
return s; //..and quit
} //if not escape char
c=*s++;
switch (c) {
case 0: *d=0x5C; s--; return s; //\-terminated string, leave in
case 'a': *d=0x07; return s; //special chars...
case 'b': *d=0x08; return s;
case 't': *d=0x09; return s;
case 'n': *d=0x0A; return s;
case 'v': *d=0x0B; return s;
case 'f': *d=0x0C; return s;
case 'r': *d=0x0D; return s;
case 'e': *d=0x1B; return s; //extension to the standard (<ESC>)
case '\"': *d=0x22; return s;
case '\'': *d=0x27; return s;
case '\\': *d=0x5C; return s;
default:
if ((c=='x')||(c=='X')) { n=0; dig=0; base=16; }
else if ((c=='d')||(c=='D')) { n=0; dig=0; base=10; }
else if ((c>='0')&&(c<='7')) { n=c-'0'; dig=1; base=8; }
else { *d=c; return s; } //ignore ill-used \ char
} /*switch*/
while (dig<3) {
c=digval(*s++);
if (c<base) {
n = n*base + c;
dig++;
}
else {
s--;
break;
} //if base 16
} //while
if (dig)
*d = n;
else {
s--;
*d = *s++;
}
return s;
} /*strcchr*/
int strcstr(char *d,char *s,int maxn)
{
int i=0;
if (maxn--) /*reduce by 1 for terminator*/
while (*s && (i<maxn)) s=strcchr(&d[i++],s);
else
while (*s) s=strcchr(&d[i++],s);
d[i]=0;
return i;
} /*strcstr*/
/****************************************************************************/
/* str2cchr, str2cstr */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Converts from characters to C-type character sequences. See the */
/* description of strcchr() for a list of the conversions. Sequences */
/* requiring a numeric value will be converted to the \xHH format. */
/*-----------------------------Arguments------------------------------------*/
/* char* d destination string */
/* char c (str2cchr()) character to convert */
/* char* s (str2cstr()) string to convert */
/* int maxn (str2cstr()) size of destination (0==no limit) */
/*-----------------------------Return value---------------------------------*/
/* Both functions return the number of characters in the destination */
/* string. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int str2cchr(char* d,char c)
{
int i=0;
if ((c>=' ')&&(c<='~')&&(c!='\\')&&(c!='\"'))
d[i++]=c;
else {
d[i++]='\\';
switch (c) {
case 0x00: d[i++]='0'; break;
case 0x07: d[i++]='a'; break;
case 0x08: d[i++]='b'; break;
case 0x09: d[i++]='t'; break;
case 0x0a: d[i++]='n'; break;
case 0x0b: d[i++]='v'; break;
case 0x0c: d[i++]='f'; break;
case 0x0d: d[i++]='r'; break;
case 0x1b: d[i++]='e'; break;
case 0x5c: d[i++]='\\'; break;
case 0x22: d[i++]='\"'; break;
case 0x27: d[i++]='\''; break;
default:
d[i++]='x';
d[i++]=HEX1(c);
d[i++]=HEX0(c);
} //switch
} //else special
return i;
} //str2cchr
int str2cstr(char* d,char *s,int maxn)
{
int i=0,j,l;
char tmp[5];
if (maxn==0) //if no limit on size..
while (*s) i+=str2cchr(&d[i],*s++);
else {
maxn--;
while (*s && (i<maxn)) {
l=str2cchr(tmp,*s++);
if ((i+l)>=maxn) break;
for (j=0;j<l;j++) d[i++]=tmp[j];
} //while
} //else limiting size
d[i]=0;
return i;
} //str2cstr
/****************************************************************************/
/* strparse */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Parses the input string into a list of parameters specified by their */
/* position within the source string s and their length. The string s is */
/* also copied into the structure pointed to by sp. If sp is specified */
/* as NULL, the module global variable strp is used. */
/* Text enclosed in quotes (either ' or ") is considered to be a single */
/* parameter without the quotes appearing (that is, the pos field of sp */
/* will point just past the first quote and the length will stop short of */
/* the closing quote). If psep is 0, the copy of the source string, str */
/* of sp, will remain identical to the source string. If 1, each */
/* parameter in the str string will have a terminating NUL set at its */
/* end (str will be divided into sp->num separate Z-strings). */
/* Parameters are always delimited by whitespace (except those enclosed */
/* in quotes). */
/*-----------------------------Arguments------------------------------------*/
/* char* s source string to be parsed; it is left unaffected */
/* STR_PARAM* sp parameter list structure, defaults to strp */
/* int psep flag indicating parameter separation desired */
/*-----------------------------Return value---------------------------------*/
/* Returns the number of parameters encountered on the line. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int strparse(char *s,int psep) //returns pnum
{
enum {START,NORMAL,WHITE,QUOTE,END};
int i,state;
char q;
char c;
state=START;
pnum=0; /*reset count*/
for (i=0;(c=s[i])!=0;i++) {
switch (state) {
case START:
if ((c=='\"') || (c=='\'')) {
if (pnum<MAX_PARAMS) {
plen[pnum]=0;
ppos[pnum]=i+1;
}
q=c;
state=QUOTE;
} /* if 1 */
else if (!isspace(c)) {
if (pnum<MAX_PARAMS) {
plen[pnum]=1;
ppos[pnum]=i;
}
state=NORMAL;
} /* else 1 */
break; /* case START */
case NORMAL:
if ((c=='\"') || (c=='\'')) {
pnum++;
if (pnum<MAX_PARAMS) {
plen[pnum]=0;
ppos[pnum]=i+1;
}
q=c;
state=QUOTE;
}
else if (isspace(c))
state=WHITE;
else {
if (pnum<MAX_PARAMS) plen[pnum]++;
}
break; /* case NORMAL */
case WHITE:
if ((c=='\"') || (c=='\'')) {
pnum++;
if (pnum<MAX_PARAMS) {
plen[pnum]=0;
ppos[pnum]=i+1;
}
q=c;
state=QUOTE;
}
else if (!isspace(c)) {
pnum++;
if (pnum<MAX_PARAMS) {
plen[pnum]=1;
ppos[pnum]=i;
}
state=NORMAL;
}
break; /* case WHITE */
case QUOTE:
if (c==q)
state=WHITE;
else
if (pnum<MAX_PARAMS) plen[pnum]++;
break; /* case QUOTE */
default :
state=WHITE;
} /* switch */
} /* for */
if (state!=START) {
pnum++;
} /*if not an empty line*/
if (psep) strparamsep(s); /*if separating*/
return pnum;
} /*strparse*/
/****************************************************************************/
/* strparam */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Copies parameter p (its string characters) from the str field of the */
/* given STR_PARAM sp. n limits the size of d (including terminator), */
/* the destination string. If sp is NULL, the global STR_PARAM strp will */
/* be used. If d is NULL, nothing will be copied, but the appropriate */
/* pointer into the str field for the specified parameter will be */
/* returned. If n is 0, no size checking will be performed when writing */
/* the value into destination string. */
/*-----------------------------Arguments------------------------------------*/
/* char* d destination string pointer, NULL=just return ptr */
/* char *s pointer to parameter list structure, default strp */
/* int p parameter to load and/or return pointer to */
/*-----------------------------Return value---------------------------------*/
/* Returns pointer to destination string if d is specified. Returns */
/* pointer to the parameter's position (sp->pos) within the str field if */
/* d is passed as NULL. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
char* strparam(char* d,int p,char* s) //returns d
{
int i; /*index*/
if (p>=pnum) return NULL; /*parameter too big for this*/
for (i=0;i<plen[p];i++)
d[i]=s[ppos[p]+i];
d[i]=0;
return d; /*return pointer to destination*/
} /*strparam*/
/****************************************************************************/
/* strparamint */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* Gets an integer from the specified parameter p and puts it in the int */
/* pointed to by ip. If the STR_PARAM pointer sp is NULL, the global */
/* strp structure is used. */
/*-----------------------------Arguments------------------------------------*/
/* STR_PARAM* sp pointer to parameter list structure, NULL-->strp */
/* int p parameter to use to load int */
/* int* ip pointer to integer to hold read value */
/*-----------------------------Return value---------------------------------*/
/* Returns 1 if successfully read an int, 0 on failure. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Examples-------------------------------------*/
/*-----------------------------Constraints/Gotchas--------------------------*/
/*--Date--------Programmer----------Comments--------------------------------*/
/* 1990.01.01 A. Turing initial code */
/****************************************************************************/
int strparamint(char* s,int p,int *ip) //1 if parsed to int
{
if (p>=pnum) return 0; /*oops. bad parameter number*/
return (sscanf(&s[ppos[p]],"%d",ip)==1);
} /*strparamint*/
/* param_sep -- puts \0 at end of each parameter -- call strparse() first */
int strparamsep(char* s) //puts \0 after each param
{
int i;
for (i=0;i<pnum;i++) s[ppos[i]+plen[i]]=0;
return pnum;
} /*strparamsep*/
/****************************************************************************/
/* strmatch */
/****************************************************************************/
/*-----------------------------Description----------------------------------*/
/* This function matches a target string against a match mask which */
/* contains wildcard characters (* and ?). The * matches all sequences. */
/* The ? matches any single character and requires that one be present. */
/* For example: */
/* strmatch("?23","123")==1 */
/* strmatch("?123","123")==0, but strmatch("*123","123")==1 */
/* strmatch("12*34*56","123a34bcde56")==1 */
/* etc. */
/*-----------------------------Arguments------------------------------------*/
/* char *m match mask with wildcards */
/* char *s target string to test against mask */
/*-----------------------------Return value---------------------------------*/
/* Returns 1 if matched, 0 otherwise. */
/*-----------------------------Global constants-----------------------------*/
/*-------------------Mod-------Global variables-----------------------------*/
/*-----------------------------Functions called-----------------------------*/
/*-----------------------------Constraints----------------------------------*/
/*--Date--------Programmer-------------Comments-----------------------------*/
/* 1990.04.?? D. Rogers initial code */
/****************************************************************************/
int strmatch(char *m,char *s)
{
#define WILD_ONE '?' /*single-char wildcard match*/
#define WILD_ALL '*' /*variable length wildcard match*/
enum { MUST_MATCH, SEEK_MATCH, PART_MATCH }; /*states for match-checking*/
char *curm; /*current pointer to match str*/
char *curs; /*current pointer to target string*/
char state=MUST_MATCH; /*start checking the match*/
curm=m; /*start at same place*/
curs=s;
while (1) { /*go 'til end of match*/
switch(state) { /*depends on state*/
case MUST_MATCH: /*if normal char, must match*/
if (*curm==WILD_ALL) { /*check for variable wild char*/
while (*curm==WILD_ALL) curm++; /*go to next char to match*/
if (*curm==0) return 1; /*nothing left to match, so quit*/
state=SEEK_MATCH; /*look for next section of match str*/
break;
} /*if wild-all found*/
if (!*curm) { /*no more to match; done, 1way|other*/
if (*curs) return 0; else return 1; /*if extra, bad; if not, match*/
} /*if end of match string*/
if (!*curs) return 0; /*found end of line*/
if ((*curm!=WILD_ONE)&&(*curm!=*curs)) return 0; /*no match!*/
curm++; /*point to next match character*/
curs++; /*point to next target character*/
break;
case SEEK_MATCH: /*looking for match*/
if (!*curs) return 0; /*no chars left for match*/
if ((*curm==WILD_ONE)||(*curm==*curs)) { /*see if matched*/
curs++; /*point to next target position*/
s=curs; /*point to target position*/
m=curm; /*point to match position*/
m++; /*point to next match position*/
state=PART_MATCH; /*we're on to one!*/
break;
} /*if match started*/
curs++; /*try next position*/
break;
case PART_MATCH: /*started matching after WILD_ALL*/
if (!*m) { /*no more to match; done, 1way|other*/
if (*s) return 0; else return 1; /*if extra, bad; if not, match*/
} /*if end of match string*/
if (*m==WILD_ALL) { /*if up to next WILD_ALL*/
curm=m; /*skip up to now*/
curs=s; /*skip up to now on target, too*/
state=MUST_MATCH; /*great, now go back to start*/
break;
} /*if end of this section of must-match*/
if (!*s) return 0; /*match mask not done but we are, bad*/
if ((*m!=WILD_ONE)&&(*m!=*s)) { /*not aligned -- bad*/
state=SEEK_MATCH; /*go back and scan for a match*/
break;
} /*if*/
m++; /*looks good, go to next char*/
s++; /*in target, too*/
break;
default: /*should never reach here*/
return 0; /*..so get out*/
} /*switch*/
} /*while forever*/
} /*strmatch*/
//***************************************************************************
// strasc2ul
//***************************************************************************
//-----------------------------Description-----------------------------------
// Fills the unsigned long pointed to by ul with the value specified in the
// ASCIIZ string s. The following prefixes are allowed:
// 0<number> <number> is in octal
// 0x<number> <number> is in hexadecimal
// All other initial sequences (other than the same ones capitalized)
// will be read in the given default base. Initial white-space is skipped.
// Numbers may be preceded by a single '-' or '+'.
//-----------------------------Arguments-------------------------------------
// char* s ASCIIZ string to be converted
// unsigned long* ul pointer to DWORD to be changed
// unsigned base default base (0-->decimal)
//-----------------------------Return value----------------------------------
// Returns the number of characters processed -- NOT the number of fields.
// Returns 0 if no value was loaded (due to absence or error).
//-----------------------------Global constants------------------------------
//-------------------Mod-------Global variables------------------------------
//-----------------------------Functions called------------------------------
//-----------------------------Examples--------------------------------------
//-----------------------------Constraints/Gotchas---------------------------
//--Date--------Programmer----------Comments---------------------------------
// 1991.07.26 A. Turing initial code
//***************************************************************************
int strasc2ul(char* s,unsigned long* ul,unsigned base)
{
#define DIGIT(c) ( (c<'0')?-1:(c<='9')?c-'0':(c<'A')?-1:(c>'Z')?-1:c+10-'A' )
unsigned long val=0;
int i=0;
unsigned dig;
char c;
char minus=0;
while (s[i] && isspace(s[i])) i++;
if (!s[i]) return 0;
if ((base<2)||(base>36)) base=10; //make sure the base is ok
if (s[i]=='-') { minus=1; i++; } //look for -<number>
else if (s[i]=='+') { minus=0; i++; }
else if (s[i]=='0') { //could be a base indicator
i++;
if ((s[i]=='x')||(s[i]=='X')) { base=16; i++; }
else if ((s[i]<'0')||(s[i]>'7')) { *ul=0; return i; } //end if not octal
else base=8;
} //if checking for base
c=toupper(s[i++]); //check first digit
dig=DIGIT(c);
if (dig>=base) return 0; //first digit was bad
val=dig; //start first digit
while (1) {
c=toupper(s[i]);
dig=DIGIT(c);
if (dig>=base) break; //reached end of line
val=val*base+dig; //good char, so insert
i++;
} //while
if (minus) *ul=-val; else *ul=val;
return i;
} //strasc2ul
//***************************************************************************
// strul2asc
//***************************************************************************
//-----------------------------Description-----------------------------------
// Writes an unsigned long int ul to an ASCIIZ string s in the given base.
// The base may be from 2 to 36. No initial characters are inserted (like
// "0x" for base 16).
//-----------------------------Arguments-------------------------------------
// char* s string into which to write the converted longword
// unsigned long ul longword to write
// unsigned base base for conversion
//-----------------------------Return value----------------------------------
// Returns the number of characters written (not including the terminating
// 0).
//-----------------------------Global constants------------------------------
//-------------------Mod-------Global variables------------------------------
//-----------------------------Functions called------------------------------
//-----------------------------Examples--------------------------------------
//-----------------------------Constraints/Gotchas---------------------------
//--Date--------Programmer----------Comments---------------------------------
// 1990.07.26 A. Turing initial code
//***************************************************************************
int strul2asc(char* s,unsigned long ul,unsigned base)
{
static char basechar[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int i=0;
unsigned dig;
char c;
if ((base<2)||(base>36)) base=10;
if (ul==0UL) { s[i++]='0'; s[i]=0; return i; } //easy if zero
while (ul) { //convert to ascii
dig=(unsigned) (ul%(unsigned long)base);
s[i++]=basechar[dig];
ul/=(unsigned long)base;
} //while
for (dig=0;dig<(i/2);dig++) { //reverse order
c=s[dig];
s[dig]=s[i-dig-1];
s[i-dig-1]=c;
} //for
s[i]=0;
return i;
} //strul2asc