archie/prospero/lib/psrv/wais_gw/cutil.c

778 lines
16 KiB
C
Raw Permalink Normal View History

2024-05-27 16:13:40 +02:00
/*****************************************************************************
* (c) Copyright 1992 Wide Area Information Servers, Inc *
* of California. All rights reserved. *
* *
* This notice is intended as a precaution against inadvertent publication *
* and does not constitute an admission or acknowledgement that publication *
* has occurred or constitute a waiver of confidentiality. *
* *
* Wide Area Information Server software is the proprietary and *
* confidential property of Wide Area Information Servers, Inc. *
*****************************************************************************/
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
#define cutil_c
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <pfs.h>
#include <perrno.h>
#include "cutil.h"
#include "futil.h"
#ifdef NOTUSEDANDNOTTHREADSAFE
long myPID = -1;
#endif /*NOTUSEDANDNOTTHREADSAFE*/
typedef long (longfunc)(long c);
/*---------------------------------------------------------------------------*/
char*
s_strdup(char* s)
{
unsigned long len;
char* copy = NULL;
if (s == NULL)
return(NULL);
len = strlen(s);
copy = (char*)s_malloc((size_t)(sizeof(char)*(len + 1)));
strncpy(copy,s,len + 1);
return(copy);
}
/*---------------------------------------------------------------------------*/
#if !defined(IN_RMG) && !defined(PFS_THREADS)
char*
strtokf(char* s1,longfunc *isDelimiter)
{
static char* searchStr = NULL;
static longfunc *delimiterFunc;
long i;
char* startTok = NULL;
if (s1 != NULL)
searchStr = s1;
if (isDelimiter != NULL)
delimiterFunc = isDelimiter;
if (searchStr == NULL || searchStr[0] == '\0')
return(NULL);
if (delimiterFunc == NULL)
return(NULL);
for (i = 0; searchStr[i] != '\0'; i++)
{ if ((*delimiterFunc)((long)searchStr[i]) == NOT_DELIMITER)
break;
}
if (searchStr[i] == '\0')
return(NULL);
else
startTok = searchStr + i;
for (; searchStr[i] != '\0'; i++)
{ if ((*delimiterFunc)((long)searchStr[i]) == IS_DELIMITER)
break;
}
if (searchStr[i] != '\0')
{ searchStr[i] = '\0';
searchStr = searchStr + i + 1;
}
else
searchStr = searchStr + i;
return(startTok);
}
/*---------------------------------------------------------------------------*/
char*
strtokf_isalnum(char* s1)
{
static char* searchStr = NULL;
long i;
char* startTok = NULL;
if (s1 != NULL)
searchStr = s1;
if (searchStr == NULL || searchStr[0] == '\0')
return(NULL);
for (i = 0; searchStr[i] != '\0'; i++)
{ if (safeIsAlNum(searchStr[i]))
break;
}
if (searchStr[i] == '\0')
return(NULL);
else
startTok = searchStr + i;
for (; searchStr[i] != '\0'; i++)
{ if (!safeIsAlNum(searchStr[i]))
break;
}
if (searchStr[i] != '\0')
{ searchStr[i] = '\0';
searchStr = searchStr + i + 1;
}
else
searchStr = searchStr + i;
return(startTok);
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
boolean
substrcmp(char* string1,char* string2)
/* return true if they match up to the length of the smaller (but not if the
smaller is empty)
*/
{
register char *a, *b;
a = string1;
b = string2;
/* see if they are both empty - if so them match */
if (*a == '\0' && *b == '\0')
return(true);
/* see if either is empty (but not both) - no match */
if (*a == '\0' || *b == '\0')
return(false);
/* otherwise we need to look through each byte */
while (*a && *b)
{ if (*a++ != *b++)
return(false);
}
return(true);
}
/*---------------------------------------------------------------------------*/
char
char_downcase(unsigned long long_ch)
{
unsigned char ch = long_ch & 0xFF;
return(((ch >= 'A') && (ch <= 'Z')) ? (ch + 'a' -'A') : ch);
}
/*---------------------------------------------------------------------------*/
char*
string_downcase(char *word)
{
long i = 0;
if (word == NULL)
return(NULL);
while (word[i] != '\0')
{ word[i] = char_downcase((unsigned long)word[i]);
i++;
}
return(word);
}
/*---------------------------------------------------------------------------*/
long
cprintf(boolean print, char* format, ...)
{
va_list ap;
if (print == 1)
{ long res;
va_start(ap,format);
res = vprintf(format,ap);
va_end(ap);
return(res);
}
else
return(0);
}
/*---------------------------------------------------------------------------*/
void
printHexByte(unsigned char h)
{
if (h < 0x10)
printf("0%x",h);
else
printf("%x",h);
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
commafy(long val,char* buf)
/*
prints the value using format, then adds commas separating every
three orders of magnitude on the left side of the decimal point.
limitations
- there needs to be a buffer to write the result into. We provide
one for convenience, but of course that's not reentrant, so if you
are calling this is multiple times before using the result you'll
need to pass in your own buffer
- only works on longs
- only works on positive nums
- no other formatting allowed
*/
{
static char myBuf[100];
if (buf == NULL)
buf = myBuf;
if (val < 1000) /* 1 thousand */
sprintf(buf,"%ld",val);
else if (val < 1000000) /* 1 millon */
{ long lessThanAGrand = val%1000;
long moreThanAGrand = val - lessThanAGrand;
sprintf(buf,"%ld,%03ld",moreThanAGrand/1000,lessThanAGrand);
}
else if (val < 1000000000) /* 1 trillion, 1 gig */
{ long lessThanAGrand = val%1000;
long lessThanAMil = (val%1000000) - lessThanAGrand;
long moreThanAMil = val - lessThanAMil - lessThanAGrand;
sprintf(buf,"%ld,%03ld,%03ld",moreThanAMil/1000000,lessThanAMil/1000,
val%1000);
}
return(buf);
}
#endif NOTUSEDANDNOTTHREADSAFE
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
printable_time(void)
{
static char *string;
time_t tptr;
time(&tptr);
string = ctime(&tptr);
if (string)
{ if (string[strlen(string)-1] == '\n')
string[strlen(string)-1] = '\0';
return(string+4);
}
else
return("Time Unknown");
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
#ifdef BSD
#define NEED_VPRINTF
#endif
#ifdef NEED_VPRINTF
#ifdef OSK
#define LONGINT
#define INTSPRINTF
#endif
#ifdef NOVOID
typedef char *pointer;
#else
typedef void *pointer;
#endif
#ifdef INTSPRINTF
#define Sprintf(string,format,arg) (sprintf((string),(format),(arg)))
#else
#define Sprintf(string,format,arg) (\
sprintf((string),(format),(arg)),\
strlen(string)\
)
#endif
typedef int *intp;
int vsprintf(dest, format, args)
char *dest;
register char *format;
va_list args;
{
register char *dp = dest;
register char c;
register char *tp;
char tempfmt[64];
#ifndef LONGINT
int longflag;
#endif
tempfmt[0] = '%';
while( (c = *format++) != 0) {
if(c=='%') {
tp = &tempfmt[1];
#ifndef LONGINT
longflag = 0;
#endif
continue_format:
switch(c = *format++) {
case 's':
*tp++ = c;
*tp = '\0';
dp += Sprintf(dp, tempfmt, va_arg(args, char *));
break;
case 'u':
case 'x':
case 'o':
case 'X':
#ifdef UNSIGNEDSPECIAL
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long));
else
#endif
dp += Sprintf(dp, tempfmt, va_arg(args, unsigned));
break;
#endif
case 'd':
case 'c':
case 'i':
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
dp += Sprintf(dp, tempfmt, va_arg(args, long));
else
#endif
dp += Sprintf(dp, tempfmt, va_arg(args, int));
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
*tp++ = c;
*tp = '\0';
dp += Sprintf(dp, tempfmt, va_arg(args, double));
break;
case 'p':
*tp++ = c;
*tp = '\0';
dp += Sprintf(dp, tempfmt, va_arg(args, pointer));
break;
case '-':
case '+':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case ' ':
case '#':
case 'h':
*tp++ = c;
goto continue_format;
case 'l':
#ifndef LONGINT
longflag = 1;
*tp++ = c;
#endif
goto continue_format;
case '*':
tp += Sprintf(tp, "%d", va_arg(args, int));
goto continue_format;
case 'n':
*va_arg(args, intp) = dp - dest;
break;
case '%':
default:
*dp++ = c;
break;
}
} else *dp++ = c;
}
*dp = '\0';
return dp - dest;
}
int vfprintf(dest, format, args)
FILE *dest;
register char *format;
va_list args;
{
register char c;
register char *tp;
register int count = 0;
char tempfmt[64];
#ifndef LONGINT
int longflag;
#endif
tempfmt[0] = '%';
while(c = *format++) {
if(c=='%') {
tp = &tempfmt[1];
#ifndef LONGINT
longflag = 0;
#endif
continue_format:
switch(c = *format++) {
case 's':
*tp++ = c;
*tp = '\0';
count += fprintf(dest, tempfmt, va_arg(args, char *));
break;
case 'u':
case 'x':
case 'o':
case 'X':
#ifdef UNSIGNEDSPECIAL
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
count += fprintf(dest, tempfmt, va_arg(args, unsigned long));
else
#endif
count += fprintf(dest, tempfmt, va_arg(args, unsigned));
break;
#endif
case 'd':
case 'c':
case 'i':
*tp++ = c;
*tp = '\0';
#ifndef LONGINT
if(longflag)
count += fprintf(dest, tempfmt, va_arg(args, long));
else
#endif
count += fprintf(dest, tempfmt, va_arg(args, int));
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
*tp++ = c;
*tp = '\0';
count += fprintf(dest, tempfmt, va_arg(args, double));
break;
case 'p':
*tp++ = c;
*tp = '\0';
count += fprintf(dest, tempfmt, va_arg(args, pointer));
break;
case '-':
case '+':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case ' ':
case '#':
case 'h':
*tp++ = c;
goto continue_format;
case 'l':
#ifndef LONGINT
longflag = 1;
*tp++ = c;
#endif
goto continue_format;
case '*':
tp += Sprintf(tp, "%d", va_arg(args, int));
goto continue_format;
case 'n':
*va_arg(args, intp) = count;
break;
case '%':
default:
putc(c, dest);
count++;
break;
}
} else {
putc(c, dest);
count++;
}
}
return count;
}
vprintf(format, args)
char *format;
va_list args;
{
return vfprintf(stdout, format, args);
}
#endif
/*---------------------------------------------------------------------------*/
void
fs_checkPtr(void* ptr)
{
if (ptr == NULL)
p_err_string = qsprintf_stcopyr(p_err_string,
"checkPtr found a NULL pointer");
}
/*---------------------------------------------------------------------------*/
void*
fs_malloc(size_t size)
{
void* ptr = NULL;
if (size <= 0) {
/* Define error message - even though caller may change it */
p_err_string = qsprintf_stcopyr(p_err_string,
"Allocating zero or -ve size %d", size);
return(NULL);
}
#ifdef THINK_C
ptr = (void*)NewPtr((long)size);
s_checkPtr(ptr);
memset(ptr,0,(size_t)size);
#else
ptr = (void*)calloc((size_t)size,(size_t)1);
s_checkPtr(ptr);
if (!ptr) out_of_memory();
#endif
return(ptr);
}
/*---------------------------------------------------------------------------*/
void*
fs_realloc(void* ptr,size_t size)
{
register void* nptr = NULL;
if (size <= 0)
return(NULL);
if (ptr == NULL)
return(s_malloc(size));
#ifdef THINK_C
nptr = NewPtr(size);
s_checkPtr(nptr);
BlockMove(ptr,nptr,size);
DisposPtr(ptr);
#else
nptr = (void*)realloc(ptr,size);
s_checkPtr(ptr);
if (!ptr) out_of_memory();
#endif
return(nptr);
}
/*---------------------------------------------------------------------------*/
void
fs_free(void* ptr)
{
if (ptr != NULL)
{
#ifdef THINK_C
DisposPtr(ptr);
#else
free(ptr);
#endif
}
}
/*---------------------------------------------------------------------------*/
char*
fs_strncat(char* dst,char* src,size_t maxToAdd,size_t maxTotal)
{
size_t dstSize = strlen(dst);
size_t srcSize = strlen(src);
if (dstSize + srcSize < maxTotal)
return(strncat(dst,src,maxToAdd));
else
{ size_t truncateTo = maxTotal - dstSize - 1;
char saveChar;
char* result = NULL;
saveChar = src[truncateTo];
src[truncateTo] = '\0';
result = strncat(dst,src,maxToAdd);
src[truncateTo] = saveChar;
return(result);
}
}
/*---------------------------------------------------------------------------*/
char*
fs_strncpy(char* s1,char* s2,long n)
{
s1[n-1] = '\0';
return(strncpy(s1, s2, n - 1));
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
void
initMyPID(void)
{
if (myPID == -1)
myPID = getpid();
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
void
warn(char* message)
{
#ifdef THINK_C
Debugger();
#else
printf("%s\n<press return to continue>\n",message);
getchar();
#endif
}
/*---------------------------------------------------------------------------*/
char*
next_arg(long* argc,char*** argv)
{
if ((*argc)-- > 0)
{ char* arg = *((*argv)++);
return(arg);
}
else
{ return(NULL);
}
}
/*---------------------------------------------------------------------------*/
char*
peek_arg(long* argc,char*** argv)
{
if ((*argc) > 0)
return(**argv);
else
return(NULL);
}
/*---------------------------------------------------------------------------*/
#ifdef NOTUSEDANDNOTTHREADSAFE
char*
readNextArg(long* argc,char*** argv,boolean* useFile,FILE* file)
/*
Like next_arg(), but can read arguments from a file (one line per arg).
Note you must copy the returned value if you need access to more
than one argument at a time.
*/
{
static char buf[300];
if (file != NULL && useFile != NULL && *useFile)
{ if (fgets(buf,300,file) == NULL) /* nothing more on the file */
{ *useFile = false;
return(next_arg(argc,argv)); /* start reading regular args again */
}
else /* return a line from the file */
{ buf[strlen(buf) - 1] = '\0'; /* get rid of newline */
return(buf);
}
}
else /* just read regular args from the command line */
{ return(next_arg(argc,argv));
}
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/
#ifdef THINK_C
#if THINK_C == 1
#include <EventMgr.h>
#endif
#if THINK_C == 5
#include <Events.h>
#endif
#ifdef WAIStation
#include "CRetrievalApp.h"
#endif
#endif
#ifdef NOTUSEDANDNOTTHREADSAFE
void
beFriendly()
{
#ifdef never
#ifdef THINK_C
EventRecord macEvent;
static RgnHandle mouseRgn = NULL;
long sleepTime;
#ifdef WAIStation
gApplication->FrobWaitCursor();
#endif
if (mouseRgn == NULL)
mouseRgn = NewRgn();
sleepTime = 5;
WaitNextEvent(everyEvent,&macEvent,sleepTime,mouseRgn);
#endif
#endif
}
#endif /*NOTUSEDANDNOTTHREADSAFE*/
/*---------------------------------------------------------------------------*/