dect
/
asl
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
asl/strutil.c

462 lines
11 KiB
C
Raw Normal View History

/* strutil.c */
/*****************************************************************************/
/* AS-Portierung */
/* */
/* haeufig benoetigte String-Funktionen */
/* */
/* Historie: 5. 5.1996 Grundsteinlegung */
/* 13. 8.1997 KillBlanks-Funktionen aus asmsub.c heruebergenommen */
/* 29. 8.1998 sprintf-Emulation */
/* 17. 4.1999 strcasecmp gegen Nullzeiger geschuetzt */
/* 30. 5.1999 ConstLongInt akzeptiert auf 0x fuer Hex-Zahlen */
/* */
/*****************************************************************************/
#include "stdinc.h"
#include <ctype.h>
#include <string.h>
#include "strutil.h"
#undef strlen /* VORSICHT, Rekursion!!! */
#ifdef BROKEN_SPRINTF
#undef sprintf
#endif
Boolean HexLowerCase; /* Hex-Konstanten mit Kleinbuchstaben */
/*--------------------------------------------------------------------------*/
/* eine bestimmte Anzahl Leerzeichen liefern */
char *Blanks(int cnt)
BEGIN
static char *BlkStr=" ";
if (cnt<0) cnt=0;
return BlkStr+(strlen(BlkStr)-cnt);
END
/****************************************************************************/
/* eine Integerzahl in eine Hexstring umsetzen. Weitere vordere Stellen als */
/* Nullen */
#define BufferCnt 8
char *HexString(LargeWord i, int Stellen)
BEGIN
static ShortString h[BufferCnt];
static int z = 0;
LargeWord digit;
char *ptr;
if (Stellen > sizeof(ShortString) - 1)
Stellen = sizeof(ShortString) - 1;
ptr = h[z] + sizeof(ShortString) - 1;
*ptr = '\0';
do
BEGIN
digit = i & 15;
if (digit < 10)
*(--ptr) = digit + '0';
else if (HexLowerCase)
*(--ptr) = digit - 10 + 'a';
else
*(--ptr) = digit - 10 + 'A';
i = i >> 4;
Stellen--;
END
while ((Stellen > 0) OR (i != 0));
z = (z + 1) % BufferCnt;
return ptr;
END
char *SysString(LargeWord i, LargeWord System, int Stellen)
BEGIN
static ShortString h[BufferCnt];
static int z = 0;
LargeWord digit;
char *ptr;
if (Stellen > sizeof(ShortString) - 1)
Stellen = sizeof(ShortString) - 1;
ptr = h[z] + sizeof(ShortString) - 1;
*ptr = '\0';
do
BEGIN
digit = i % System;
if (digit < 10)
*(--ptr) = digit + '0';
else if (HexLowerCase)
*(--ptr) = digit - 10 + 'a';
else
*(--ptr) = digit - 10 + 'A';
i /= System;
Stellen--;
END
while ((Stellen > 0) OR (i != 0));
z = (z + 1) % BufferCnt;
return ptr;
END
/*--------------------------------------------------------------------------*/
/* dito, nur vorne Leerzeichen */
char *HexBlankString(LargeWord i, Byte Stellen)
BEGIN
static String temp;
strmaxcpy(temp,HexString(i,0),255);
if (strlen(temp)<Stellen) strmaxprep(temp,Blanks(Stellen-strlen(temp)),255);
return temp;
END
/*---------------------------------------------------------------------------*/
/* Da manche Systeme (SunOS) Probleme mit der Ausgabe extra langer Ints
haben, machen wir das jetzt zu Fuss :-( */
char *LargeString(LargeInt i)
BEGIN
Boolean SignFlag=False;
static String s;
String tmp;
char *p,*p2;
if (i<0)
BEGIN
i=(-i); SignFlag=True;
END
p=tmp;
do
BEGIN
*(p++)='0'+(i%10);
i/=10;
END
while (i>0);
p2=s; if (SignFlag) *(p2++)='-';
while (p>tmp) *(p2++)=(*(--p));
*p2='\0'; return s;
END
/*---------------------------------------------------------------------------*/
/* manche haben's nicht... */
#if defined(NEEDS_STRDUP) || defined(CKMALLOC)
#ifdef CKMALLOC
char *mystrdup(char *s)
BEGIN
#else
char *strdup(char *s)
BEGIN
#endif
char *ptr=(char *) malloc(strlen(s)+1);
#ifdef CKMALLOC
if (ptr==Nil)
BEGIN
fprintf(stderr,"strdup: out of memory?\n"); exit(255);
END
#endif
if (ptr!=0) strcpy(ptr,s);
return ptr;
END
#endif
#ifdef NEEDS_CASECMP
int strcasecmp(const char *src1, const char *src2)
BEGIN
if (src1 == NULL) src1 = "";
if (src2 == NULL) src2 = "";
while (toupper(*src1)==toupper(*src2))
BEGIN
if ((NOT *src1) AND (NOT *src2)) return 0;
src1++; src2++;
END
return ((int) toupper(*src1))-((int) toupper(*src2));
END
int strncasecmp(const char *src1, const char *src2, int len)
BEGIN
if (src1 == NULL) src1 = "";
if (src2 == NULL) src2 = "";
while (toupper(*src1)==toupper(*src2))
BEGIN
if (--len==0) return 0;
if ((NOT *src1) AND (NOT *src2)) return 0;
src1++; src2++;
END
return ((int) toupper(*src1))-((int) toupper(*src2));
END
#endif
#ifdef NEEDS_STRSTR
char *strstr(char *haystack, char *needle)
BEGIN
int lh=strlen(haystack), ln=strlen(needle);
int z;
char *p;
for (z=0; z<=lh-ln; z++)
if (strncmp(p=haystack+z,needle,ln)==0) return p;
return Nil;
END
#endif
#ifdef BROKEN_SPRINTF
#include <varargs.h>
int mysprintf(va_alist) va_dcl
BEGIN
va_list pvar;
char *form,*dest,*run;
va_start(pvar);
dest=va_arg(pvar,char*);
form=va_arg(pvar,char*);
vsprintf(dest,form,pvar);
for (run=dest; *run!='\0'; run++);
return run-dest;
END
#endif
/*---------------------------------------------------------------------------*/
/* wenn man mit unsigned arbeitet, gibt das boese Seiteneffekte bei direkter
Arithmetik mit strlen... */
signed int strslen(const char *s)
BEGIN
return strlen(s);
END
/*---------------------------------------------------------------------------*/
/* das originale strncpy plaettet alle ueberstehenden Zeichen mit Nullen */
void strmaxcpy(char *dest, const char *src, int Max)
BEGIN
int cnt=strlen(src);
if (cnt>Max) cnt=Max;
memcpy(dest,src,cnt); dest[cnt]='\0';
END
/*---------------------------------------------------------------------------*/
/* einfuegen, mit Begrenzung */
void strmaxcat(char *Dest, const char *Src, int MaxLen)
BEGIN
int TLen=strlen(Src),DLen=strlen(Dest);
if (TLen>MaxLen-DLen) TLen=MaxLen-DLen;
if (TLen>0)
BEGIN
memcpy(Dest+DLen,Src,TLen);
Dest[DLen+TLen]='\0';
END
END
void strprep(char *Dest, const char *Src)
BEGIN
memmove(Dest+strlen(Src),Dest,strlen(Dest)+1);
memmove(Dest,Src,strlen(Src));
END
void strmaxprep(char *Dest, const char *Src, int MaxLen)
BEGIN
int RLen;
RLen=strlen(Src); if (RLen>MaxLen-strlen(Dest)) RLen=MaxLen-strlen(Dest);
memmove(Dest+RLen,Dest,strlen(Dest)+1);
memmove(Dest,Src,RLen);
END
void strins(char *Dest, const char *Src, int Pos)
BEGIN
memmove(Dest+Pos+strlen(Src),Dest+Pos,strlen(Dest)+1-Pos);
memmove(Dest+Pos,Src,strlen(Src));
END
void strmaxins(char *Dest, const char *Src, int Pos, int MaxLen)
BEGIN
int RLen;
RLen=strlen(Src); if (RLen>MaxLen-strlen(Dest)) RLen=MaxLen-strlen(Dest);
memmove(Dest+Pos+RLen,Dest+Pos,strlen(Dest)+1-Pos);
memmove(Dest+Pos,Src,RLen);
END
/*---------------------------------------------------------------------------*/
/* Bis Zeilenende lesen */
void ReadLn(FILE *Datei, char *Zeile)
BEGIN
/* int Zeichen='\0';
char *Run=Zeile;
while ((Zeichen!='\n') AND (Zeichen!=EOF) AND (!feof(Datei)))
BEGIN
Zeichen=fgetc(Datei);
if (Zeichen!=26) *Run++=Zeichen;
END
if ((Run>Zeile) AND ((Zeichen==EOF) OR (Zeichen=='\n'))) Run--;
if ((Run>Zeile) AND (Run[-1]==13)) Run--;
*Run++='\0';*/
char *ptr;
int l;
*Zeile='\0'; ptr=fgets(Zeile,256,Datei);
if ((ptr==Nil) AND (ferror(Datei)!=0)) *Zeile='\0';
l=strlen(Zeile);
if ((l>0) AND (Zeile[l-1]=='\n')) Zeile[--l]='\0';
if ((l>0) AND (Zeile[l-1]=='\r')) Zeile[--l]='\0';
if ((l>0) AND (Zeile[l-1]==26)) Zeile[--l]='\0';
END
/*--------------------------------------------------------------------*/
/* Zahlenkonstante umsetzen: $ hex, % binaer, @ oktal */
/* inp: Eingabezeichenkette */
/* erg: Zeiger auf Ergebnis-Longint */
/* liefert TRUE, falls fehlerfrei, sonst FALSE */
LongInt ConstLongInt(const char *inp, Boolean *err)
BEGIN
static char Prefixes[4]={'$','@','%','\0'}; /* die moeglichen Zahlensysteme */
static LongInt Bases[3]={16,8,2}; /* die dazugehoerigen Basen */
LongInt erg;
LongInt Base=10,z,val,vorz=1; /* Vermischtes */
/* eventuelles Vorzeichen abspalten */
if (*inp == '-')
BEGIN
vorz = (-1); inp++;
END
/* Sonderbehandlung 0x --> $ */
if ((strlen(inp) >= 2) && (*inp == '0') && (toupper(inp[1]) == 'X'))
BEGIN
inp += 2;
Base = 16;
END
/* Jetzt das Zahlensystem feststellen. Vorgabe ist dezimal, was
sich aber durch den Initialwert von Base jederzeit aendern
laesst. Der break-Befehl verhindert, dass mehrere Basenzeichen
hintereinander eingegeben werden koennen */
else
for (z = 0; z < 3; z++)
if (*inp == Prefixes[z])
BEGIN
Base = Bases[z]; inp++; break;
END
/* jetzt die Zahlenzeichen der Reihe nach durchverwursten */
erg=0; *err=False;
for(; *inp != '\0'; inp++)
BEGIN
/* Ziffern 0..9 ergeben selbiges */
if ((*inp>='0') AND (*inp<='9')) val=(*inp)-'0';
/* Grossbuchstaben fuer Hexziffern */
else if ((*inp>='A') AND (*inp<='F')) val=(*inp)-'A'+10;
/* Kleinbuchstaben nicht vergessen...! */
else if ((*inp>='a') AND (*inp<='f')) val=(*inp)-'a'+10;
/* alles andere ist Schrott */
else break;
/* entsprechend der Basis zulaessige Ziffer ? */
if (val>=Base) break;
/* Zahl linksschieben, zusammenfassen, naechster bitte */
erg=erg*Base+val;
END
/* bis zum Ende durchgelaufen ? */
if (*inp == '\0')
BEGIN
/* Vorzeichen beruecksichtigen */
erg*=vorz;
*err=True;
END
return erg;
END
/*--------------------------------------------------------------------------*/
/* alle Leerzeichen aus einem String loeschen */
void KillBlanks(char *s)
BEGIN
char *z,*dest;
Boolean InHyp=False,InQuot=False;
dest=s;
for (z=s; *z!='\0'; z++)
BEGIN
switch (*z)
BEGIN
case '\'': if (NOT InQuot) InHyp=NOT InHyp; break;
case '"': if (NOT InHyp) InQuot=NOT InQuot; break;
END
if ((NOT isspace((unsigned char)*z)) OR (InHyp) OR (InQuot)) *(dest++)=(*z);
END
*dest='\0';
END
/*--------------------------------------------------------------------------*/
/* fuehrende Leerzeichen loeschen */
void KillPrefBlanks(char *s)
BEGIN
char *z=s;
while ((*z!='\0') AND (isspace((unsigned char)*z))) z++;
if (z!=s) strcpy(s,z);
END
/*--------------------------------------------------------------------------*/
/* anhaengende Leerzeichen loeschen */
void KillPostBlanks(char *s)
BEGIN
char *z=s+strlen(s)-1;
while ((z>=s) AND (isspace((unsigned char)*z))) *(z--)='\0';
END
/*--------------------------------------------------------------------------*/
int strqcmp(const char *s1, const char *s2)
BEGIN
int erg=(*s1)-(*s2);
return (erg!=0) ? erg : strcmp(s1,s2);
END
void strutil_init(void)
BEGIN
HexLowerCase=False;
END