aboutsummaryrefslogtreecommitdiffstats
path: root/strutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'strutil.c')
-rw-r--r--strutil.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/strutil.c b/strutil.c
new file mode 100644
index 0000000..2135723
--- /dev/null
+++ b/strutil.c
@@ -0,0 +1,461 @@
+/* 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