/* 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 #include #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)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 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