home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
os2prgc.zip
/
str.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-06
|
19KB
|
830 lines
/*****************************************************************************
STR.C -- Sample code for string and character type handling.
Copyright (C) 1993,94,95 by Craig Morrison, All Rights Reserved.
You may use this code in your own projects, regardless of renumeration.
All I ask is that you prominently display the above copyright notice.
Should you need assistance, I can be contacted at the following addresses:
Fidonet: Craig Morrison, 1:201/60@fidonet.org
Internet: cam@wpc.cioe.com
Post: Craig Morrison
1316 Ferry St.
Lafayette, IN 47901-1533
USA
NOTES:
You'll notice the complete lack of any references to run-time
library functions. This was done on purpose so that *I* could
control what happens when a thread gets killed. This package
contains just about everything you'll need to do comm port/file
I/O, string manipulation and ordinal number conversions.
This module provides the character type and string manipulation
functions.
*****************************************************************************/
#include <stdio.h>
/*****************************************************************************
Converts 'a...z' to 'A...Z'
*****************************************************************************/
char cupper(char c)
{
if ((c>=97) && (c<=122))
c &= ~32;
return(c);
}
/*****************************************************************************
Converts 'A...Z' to 'a...z'
*****************************************************************************/
char clower(char c)
{
if ((c>=65) && (c<=90))
c |= 32;
return(c);
}
/*****************************************************************************
Copies src to dest.
*****************************************************************************/
char *cpystr(char *dest, char *src)
{
char *r = dest;
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return(r);
}
/*****************************************************************************
Concatenates src onto dest.
*****************************************************************************/
char *catstr(char *dest, char *src)
{
char *r = dest;
while (*dest) dest++;
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return(r);
}
/*****************************************************************************
Copies src to dest, for no more than len characters.
*****************************************************************************/
char *cpystrn(char *dest, char *src, unsigned long len)
{
unsigned long cur = 0;
char *r = dest;
while ((cur < len) && (*src))
{
*dest = *src;
dest++;
src++;
cur++;
}
*dest = '\0';
return(r);
}
/*****************************************************************************
Concatenates src onto dest, dest will never be longer than len.
*****************************************************************************/
char *catstrn(char *dest, char *src, unsigned long len)
{
unsigned long cur = 0;
char *r = dest;
while (*dest)
{
cur++;
dest++;
}
if (cur < len)
{
while ((cur < len) && (*src))
{
*dest = *src;
dest++;
src++;
cur++;
}
*dest = '\0';
}
return(r);
}
/*****************************************************************************
Compares s1 to s2, case sensitive.
*****************************************************************************/
int cmpstr(char *s1, char *s2)
{
while ((*s1) && (*s2))
{
if (*s1 < *s2)
return -1;
else if (*s1 > *s2)
return 1;
s1++;
s2++;
}
if ((!(*s1)) && (!(*s2)))
return 0;
else
{
if (!(*s1))
return -1;
else
return 1;
}
}
/*****************************************************************************
Compares s1 to s2, case insensitive.
*****************************************************************************/
int cmpstri(char *s1, char *s2)
{
while ((*s1) && (*s2))
{
if (cupper(*s1) < cupper(*s2))
return -1;
else if (cupper(*s1) > cupper(*s2))
return 1;
s1++;
s2++;
}
if ((!(*s1)) && (!(*s2)))
return 0;
else
{
if (!(*s1))
return -1;
else
return 1;
}
}
/*****************************************************************************
Compares s1 to s2, no more than len characters are compared.
*****************************************************************************/
int cmpstrn(char *s1, char *s2, unsigned long len)
{
unsigned long cur = 0;
while ((*s1) && (*s2) && (cur<len))
{
if (*s1 < *s2)
return -1;
else if (*s1 > *s2)
return 1;
s1++;
s2++;
cur++;
}
if (((!(*s1)) && (!(*s2))) || (cur==len))
return 0;
else
{
if (!(*s1))
return -1;
else
return 1;
}
}
/*****************************************************************************
Compares s1 to s2, no more than len characters are compared,
case insensitive.
*****************************************************************************/
int cmpstrni(char *s1, char *s2, unsigned long len)
{
unsigned long cur = 0;
while ((*s1) && (*s2) && (cur<len))
{
if (cupper(*s1) < cupper(*s2))
return -1;
else if (cupper(*s1) > cupper(*s2))
return 1;
s1++;
s2++;
cur++;
}
if (((!(*s1)) && (!(*s2))) || (cur==len))
return 0;
else
{
if (!(*s1))
return -1;
else
return 1;
}
}
/*****************************************************************************
Determines the length of s.
*****************************************************************************/
unsigned long lenstr(char *s)
{
unsigned long cur = 0;
while (*s)
{
s++;
cur++;
}
return(cur);
}
/*****************************************************************************
Finds h in s, case sensitive.
*****************************************************************************/
char *strinstr(char *n, char *h)
{
while (*n)
{
if (!cmpstrn(n, h, lenstr(h)))
return(n);
n++;
}
return (char *)NULL;
}
/*****************************************************************************
Finds h in s, case insensitive.
*****************************************************************************/
char *strinstri(char *n, char *h)
{
while (*n)
{
if (!cmpstrni(n, h, lenstr(h)))
return(n);
n++;
}
return (char *)NULL;
}
/*****************************************************************************
Finds the first instance of c in s.
*****************************************************************************/
char *charinstr(char *s, char c)
{
if (!c)
{
while (*s) s++;
return(s);
}
else
{
while (*s)
{
if (*s == c)
return(s);
s++;
}
return (char *)NULL;
}
}
/*****************************************************************************
Finds the last instance of c in s.
*****************************************************************************/
char *rcharinstr(char *s, char c)
{
unsigned long cur;
cur = lenstr(s);
if (cur)
{
while (*s) s++;
s--;
while (cur--)
{
if (*s == c)
return(s);
s--;
}
return (char *)NULL;
}
else
return (char *)NULL;
}
/*****************************************************************************
Converts s to uppercase.
*****************************************************************************/
char *supper(char *s)
{
char *p = s;
while (*s)
{
*s = cupper(*s);
s++;
}
return(p);
}
/*****************************************************************************
Converts s to lowercase.
*****************************************************************************/
char *slower(char *s)
{
char *p = s;
while (*s)
{
*s = clower(*s);
s++;
}
return(p);
}
/*****************************************************************************
Moves s to d for l bytes, the regions may overlap.
*****************************************************************************/
void movemem(void *d, void *s, unsigned long l)
{
char *pd = (char *)d,
*ps = (char *)s;
unsigned long i;
if (pd<ps)
{
for (i=0; i<l; i++,pd++,ps++)
*pd = *ps;
}
else
{
pd += (l-1);
ps += (l-1);
for (;l>0;l--,pd--,ps--)
*pd = *ps;
}
}
/*****************************************************************************
Sets the memory region d, with f for l bytes.
*****************************************************************************/
void setmem(void *d, char f, unsigned long l)
{
char *pd = (char *)d;
for (;l>0;l--,pd++)
*pd = f;
}
/*****************************************************************************
Converts an unsigned long into its string representation in buf.
*****************************************************************************/
char *ultoasc(unsigned long num, char *buf)
{
char r[40];
char *p, *s;
long n;
if (!num)
cpystr(buf, "0");
else
{
p = r;
*p = '\0';
while (num)
{
*p = '0' + (num % 10);
num /= 10;
p++;
*p = '\0';
}
n = lenstr(r);
s = buf;
p = r;
p += (n-1);
while(n--)
{
*s = *p;
s++;
*s = '\0';
p--;
}
}
return(buf);
}
/*****************************************************************************
Converts a long into its string representation in buf.
*****************************************************************************/
char *ltoasc(long num, char *buf)
{
char r[40];
buf[0] = '\0';
if (num<0)
{
buf[0] = '-';
buf[1] = '\0';
num = -num;
}
catstrn(buf, ultoasc(num, r), 39);
return(buf);
}
/*****************************************************************************
Is character 'A...Z,a...z'?
*****************************************************************************/
int isalpha(char c)
{
if (((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')))
return 1;
else
return 0;
}
/*****************************************************************************
Is character '0...0'?
*****************************************************************************/
int isdig(char c)
{
if (c>='0' && c<='9')
return 1;
else
return 0;
}
/*****************************************************************************
Is character ' \t\r\n'?
*****************************************************************************/
int iswspace(char c)
{
int rc = 0;
switch(c)
{
case '\t':
case '\r':
case '\n':
case ' ':
rc = 1;
break;
}
return(rc);
}
/*****************************************************************************
Converts the ASCII representation of a long value to a long.
*****************************************************************************/
long asctol(char *n)
{
char *p;
int isneg = 0;
long num = 0;
while ((*n) && (iswspace(*n)))
n++;
if (*n)
{
if (*n=='-')
{
isneg = 1;
n++;
}
while ((*n) && isdig(*n))
{
num = (num * 10) + ((long)(*n-'0'));
n++;
}
if (isneg)
num = -num;
}
return(num);
}
/*****************************************************************************
Converts the ASCII representation of an unsigned long value to an unsigned
long.
*****************************************************************************/
unsigned long asctoul(char *n)
{
char *p;
unsigned long num = 0;
while ((*n) && (iswspace(*n)))
n++;
if (*n)
{
while ((*n) && isdig(*n))
{
num = (num * 10) + ((long)(*n-'0'));
n++;
}
}
return(num);
}
/*****************************************************************************
Performs escape character translation on a subset of the C escape set.
*****************************************************************************/
unsigned char *translate(unsigned char *string)
{
char *here=string;
size_t len=lenstr(string);
int num;
int numlen;
while (NULL!=(here=charinstr(here,'\\')))
{
numlen=1;
switch (here[1])
{
case '\\':
break;
case 'r':
*here = '\r';
break;
case 'n':
*here = '\n';
break;
case 't':
*here = '\t';
break;
case 'v':
*here = '\v';
break;
case 'a':
*here = '\a';
break;
}
num = here - string + numlen;
here++;
movemem(here,here+numlen,len-num );
}
return string;
}
/*****************************************************************************
Scans the comma-delimited string i, returns one segment of it in o.
Commas inside double quoted (") string segments are ignored. If you need
double quotes in the string double them up (""). Double quotes must be
paired up.. I.E; ""22, 22"".
If the input string is:
"22, 34", 25
On return o would contain `22, 34' and i would be pointing just past the
second "," in the input string.
*****************************************************************************/
char *GetNextString(char *i, char *o)
{
int inQuotes = 0;
while ((iswspace(*i)) && (*i)) i++;
while (*i)
{
if (*i=='"')
{
i++;
inQuotes = ~inQuotes;
}
if ((!inQuotes) && (*i == ','))
break;
*o = *i;
i++;
o++;
}
*o = '\0';
return(((*i != 0) ? i+1 : i));
}
/*****************************************************************************
Performs a subset of the tranlsations and substitutions that the printf()
family of run-time library functions do.
Format specifiers are simple, the recognized specifiers are:
%% %
%s String
%u Unsigned Long
%d Long
Escape characters recognized are:
\\ \
\" "
\r carriage return
\n linefeed
\t tab
\v vertical tab
\a bell
items[] is an array of unsigned longs. It is your responsibility to make
sure that there are as many elements in items[] as there are format
specifiers in fmt.
It is also your responsibility to make sure that buf is large enough to
contain all the translations in fmt.
The return value is the number of format specifiers converted.
*****************************************************************************/
int formatStr(char *buf, char *fmt, unsigned long *items)
{
char n[32];
char *s;
unsigned long ul;
long l;
int i = 0;
while(*fmt)
{
if (*fmt=='%')
{
fmt++;
switch(*fmt)
{
case 's':
s = (char *)items[i];
cpystr(buf, s);
i++;
buf += lenstr(buf);
break;
case 'u':
ul = (unsigned long)items[i];
cpystr(buf, ultoasc(ul, n));
i++;
buf += lenstr(buf);
break;
case 'l':
l = (long)items[i];
cpystr(buf, ltoasc(l, n));
i++;
buf += lenstr(buf);
break;
default:
*buf = *fmt;
buf++;
*buf = 0;
break;
}
}
else
{
if (*fmt=='\\')
{
fmt++;
switch(*fmt)
{
case '\\':
*buf = '\\';
break;
case '"':
*buf = '"';
break;
case 'r':
*buf = '\r';
break;
case 'n':
*buf = '\n';
break;
case 't':
*buf = '\t';
break;
case 'v':
*buf = '\v';
break;
case 'a':
*buf = '\a';
break;
default:
*buf = *fmt;
break;
}
buf++;
*buf = 0;
}
else
{
*buf = *fmt;
buf++;
*buf = 0;
}
}
fmt++;
}
return(i);
}