#include <string.h> #include <ctype.h> #ifndef __APPLE__ #include <malloc.h> #endif #include <stdlib.h> //#include "lerror.h" #include "smatch.h" //#include "heap.h" #define Hallocate malloc #define Hdeallocate free #define MIN(a,b) ((a)<(b)?(a):(b)) /* * Returns the length of the string. */ int Slength(char *text) { if(text==0) return 0; else return strlen(text); } /* * Returns < 0 if the first string comes first in alphabetical order. * Returns = 0 if the two strings are the same. * Returns > 0 if the second string comes first in alphabetical order. */ int Scompare(char *text1, char *text2) { if(text1==0 && text2==0) { return 0; } else if(text1==0) { return -1; } else if(text2==0) { return 1; } return strcmp(text1,text2); } /* * Same as Scompare() except that the comparison is done from the end * of the string. Thus CBA comes before BCA. * * Returns < 0 if the first string comes first in alphabetical order. * Returns = 0 if the two strings are the same. * Returns > 0 if the second string comes first in alphabetical order. */ int ScompareBackwards(char *text1, char *text2) { int ic; int length, length1, length2; if(text1==0 && text2==0) { return 0; } else if(text1==0) { return -1; } else if(text2==0) { return 1; } length1=Slength(text1); length2=Slength(text2); length=MIN(length1,length2); /* * Comapre the strings character by character until one of them ends. */ for(ic=0; ic<length; ic++) { if(text1[length1-ic-1]<text2[length2-ic-1]) { return -1; } if(text1[length1-ic-1]>text2[length2-ic-1]) { return 1; } } /* * They're the same up until one of them ends. So the shorter one * comes first. */ if(length1==length2) { return 0; } else if(length1<length2) { return -1; } else { return 1; } } /* * Returns 0 if the two input strings are different. * Returns 1 if they are the same. */ int Sequal(char *text1, char *text2) { if(text1==0 && text2==0) return 1; else if(text1==0 || text2==0) return 0; return strcmp(text1,text2)==0; } /* * Copies the source string to the destination. */ void Scopy(char *destination, char *source) { if(destination==0) { return; } if(source==0) { strcpy(destination,""); return; } (void)strcpy(destination,source); } void Sdestroy(char *text) { if(text!=0) { Hdeallocate(text); } } /* * Creates and copies an existing string. */ char *Sduplicate(char *source) { char *result = 0; if( source != 0 ) { result = (char *)Hallocate(strlen(source) + 1); if( result != 0 ) { Scopy(result, source); } } return result; } /* * Makes the string empty. */ void Sempty(char *text) { if(text==0) return; Scopy(text,""); } /* * Copies the source string to the destination, converting uppercase letters * to lowercase letters in the process. */ void Stolower(char *destination, char *source) { int i; int length; if(destination==0) { return; } if(source==0) { Sempty(destination); return; } if(destination!=source) { (void)strcpy(destination,source); } length=strlen(destination); for (i=0; i<length; i++) { if (isupper(destination[i])) destination[i] = tolower(destination[i]); } } /* * Copies the source string to the destination, converting lowercase letters * to uppercase letters in the process. */ void Stoupper(char *destination, char *source) { int i; int length; if(destination==0) { return; } if(source==0) { Sempty(destination); return; } if(destination!=source) { (void)strcpy(destination,source); } length=strlen(destination); for (i=0; i<length; i++) { if (islower(destination[i])) destination[i] = toupper(destination[i]); } } /* * Truncates the string to the specified length. */ void Struncate(char *text, int length) { if(text==0) return; if(Slength(text)>length) text[length]=0; } /* * Appends the second string to the end of the first. */ void Sappend(char *text1, char *text2) { if(text1==0 || text2==0) return; (void)strcat(text1,text2); } /* * Appends the character the end of the text. */ void SappendChar(char *text1, char char1) { char text2[10]; if(text1==0) return; text2[0]=char1; text2[1]=0; (void)strcat(text1,text2); } static int space(char character) { if(character==' ' || character=='\t') return 1; else return 0; } /* * Skip over spaces and tabs. */ static int skip(char *text, int itext) { while(space(text[itext])) itext++; return itext; } // // removes eol, cr, space, and tab from end of input line // alters the input buffer // returns the new length of the buffer // int StrimEnd(char *buffer) { int length; length=strlen(buffer); while(length>0) { if(buffer[length-1]=='\n' || buffer[length-1]=='\r' || buffer[length-1]==' ' || buffer[length-1]=='\t') { buffer[length-1]=0; length--; } else { break; } } return length; } /* * Removes blanks from both ends of the string. */ void Strim(char *source) { char * dest; char * first; if(source==0) { return; } dest=source; /* * Skip over the initial spaces. */ for( ; (*source)!=0; source++) { if(space(*source)==0) { break; } } /* * Copy characters until the end. Remember the first space * we see. If we don't see any other characters, at the end we'll * zero the space. */ first=0; for( ; (*source)!=0; source++) { if(space(*source)==0) { first=0; } else if(first==0) { first=dest; } (*dest) = (*source); dest++; } if(first!=0) { (*first) = 0; } else { (*dest) = 0; } } /* * Compare two strings in a more liberal manner than Sequal(). * Spaces and tabs are equivalent. Spaces at the beginning and end of * the strings are ignored. Any number of spaces are equivalent. * Upper and lower case are equivalent. Returns 1 if the first * string is a subset of the second. Returns zero otherwise. */ int Ssub(char *sub, char *line) { int isub,lsub; int iline,lline; lsub=Slength(sub); lline=Slength(line); if((lsub==0) && (lline==0)) return 1; if((lsub==0) && (lline!=0)) return 0; if((lsub!=0) && (lline==0)) return 0; /* * skip leading spaces */ isub=0; isub=skip(sub,isub); iline=0; iline=skip(line,iline); /* * compare characters until * 1. a space is seen * 2. they don't match * 3. we run out of characters in sub * 4. we run out of characters in line */ for( ; iline<lline && isub<lsub; iline++, isub++) { if(space(sub[isub])) { if(space(line[iline])) { isub=skip(sub,isub)-1; iline=skip(line,iline)-1; } else return 0; } else if(tolower(sub[isub])!=tolower(line[iline])) return 0; } /* * see if there are trailing spaces on sub */ if(isub<lsub && iline>=lline) isub=skip(sub,isub); if(isub>=lsub && iline<=lline) return 1; else return 0; } /* * Compare two strings in a more liberal manner than Sequal(). * Spaces and tabs are equivalent. Spaces at the beginning and end of * the strings are ignored. Any number of spaces are equivalent. * Upper and lower case are equivalent. Returns 1 if the two * strings are the same. Returns zero otherwise. */ int Smatch(char *text1, char *text2) { return (Ssub(text1,text2) && Ssub(text2,text1)); } #define MAX_PAREN 20 /* * Returns index into the grouper array if the specified character * is a grouper. Otherwise returns -1. */ static int GrouperStart(int ngrouper, char *grouper, char gstart) { int igrouper; for(igrouper=0; igrouper<ngrouper; igrouper++) { if(grouper[igrouper*2]==gstart) return igrouper; } return -1; } /* * Returns index of the */ static int GrouperStop(int ngrouper, char *grouper, char gstart, char gstop) { int igrouper; for(igrouper=0; igrouper<ngrouper; igrouper++) { if(grouper[igrouper*2]==gstart && grouper[igrouper*2+1]==gstop) return igrouper; } return -1; } /* * Returns index if the character is a separator. * Otherwise returns -1. */ int Sisoneof(char *separator, char character) { int iseparator; int nseparator; nseparator=Slength(separator); for(iseparator=0; iseparator<nseparator; iseparator++) { if(separator[iseparator]==character) return iseparator; } return -1; } /* * Strips quotation marks from around the word. * Returns 0 if it does it; -1 if not. */ int Sunquote(char *word) { int ichar; int nchar; if(word==0) return -1; nchar=Slength(word); if(nchar<2) return -1; if((word[0]=='"') && (word[nchar-1]=='"')) { for(ichar=0; ichar<nchar-2; ichar++) word[ichar]=word[ichar+1]; word[nchar-2]=0; return 0; } if((word[0]=='\'') && (word[nchar-1]=='\'')) { for(ichar=0; ichar<nchar-2; ichar++) word[ichar]=word[ichar+1]; word[nchar-2]=0; return 0; } return -1; } /* * Chop the input string into words. * Words are separated by the specified separator character. * Words are grouped by the specified grouping characters. * Returns with words in the specified array "word". * Returns the number of words found. */ int Swords(char *text, int condense, char *separator, char *grouper, char *escaper, char **word) { int nword; /* number of words already found */ int wplace; /* set if we are in the middle of a word */ int tplace; int tlength; int nparen; char paren[MAX_PAREN]; // changed from int, 090714 int group; int ngrouper; int nescaper; int nseparator; if(text==0) return -1; tplace=0; wplace=0; nword=0; nparen=0; tlength=Slength(text); ngrouper=Slength(grouper)/2; nseparator=Slength(separator); nescaper=Slength(escaper); for(tplace=0; tplace<tlength; tplace++) { /* * are we inside a group? If so, see if this is the end. */ if(nparen>0) { if(GrouperStop(ngrouper,grouper,paren[nparen-1],text[tplace])>=0) { word[nword][wplace]=text[tplace]; wplace++; nparen--; continue; } } /* * Is this the start of a group? */ group=GrouperStart(ngrouper,grouper,text[tplace]); if(nparen<MAX_PAREN && group>=0) { word[nword][wplace]=text[tplace]; wplace++; paren[nparen]=text[tplace]; nparen++; continue; } /* * Is this an escape character? */ if(nparen<=0 && Sisoneof(escaper,text[tplace])>=0) { tplace++; word[nword][wplace]=text[tplace]; wplace++; continue; } /* * Is this a separator character? */ if(nparen<=0 && Sisoneof(separator,text[tplace])>=0) { if((!condense) || (wplace!=0)) { word[nword][wplace]=0; nword++; wplace=0; } continue; } /* * Just a regular old character. Put it in the output word. */ word[nword][wplace]=text[tplace]; wplace++; } if(wplace>0) { word[nword][wplace]=0; nword++; } return nword; } /* * Counts the words in the input string. * Words are separated by the specified separator character. * Words are grouped by the specified grouping characters. * Returns the number of words found. */ int ScountWords(char *text, int condense, char *separator, char *grouper, char *escaper) { int nword; /* number of words already found */ int wplace; /* set if we are in the middle of a word */ int tplace; int tlength; int nparen; char paren[MAX_PAREN]; // changed from int, 090712 int group; int ngrouper; int nescaper; int nseparator; if(text==0) return -1; tplace=0; wplace=0; nword=0; nparen=0; tlength=Slength(text); ngrouper=Slength(grouper)/2; nseparator=Slength(separator); nescaper=Slength(escaper); for(tplace=0; tplace<tlength; tplace++) { /* * are we inside a group? If so, see if this is the end. */ if(nparen>0) { if(GrouperStop(ngrouper,grouper,paren[nparen-1],text[tplace])>=0) { wplace++; nparen--; continue; } } /* * Is this the start of a group? */ group=GrouperStart(ngrouper,grouper,text[tplace]); if(nparen<MAX_PAREN && group>=0) { wplace++; paren[nparen]=text[tplace]; nparen++; continue; } /* * Is this an escape character? */ if(nparen<=0 && Sisoneof(escaper,text[tplace])>=0) { tplace++; wplace++; continue; } /* * Is this a separator character? */ if(nparen<=0 && Sisoneof(separator,text[tplace])>=0) { if((!condense) || (wplace!=0)) { nword++; wplace=0; } continue; } /* * Just a regular old character. Put it in the output word. */ wplace++; } if(wplace>0) { nword++; } return --nword; /* I don't know why it was off? PKB */ } /* * Chop the input string into words. * Words are separated by the specified separator character. * Words are grouped by the specified grouping characters. * Returns with words in the specified array "word". * Returns the number of words found. * * Grouping is performed to only one level. * * Example: "(I'm a string)" with () and '' as groupers ignores * the single quote within the parenthesized group. */ int SwordsNoNest(char *text, int condense, char *separator, char *grouper, char *escaper, char **word) { int nword; /* number of words already found */ int wplace; /* set if we are in the middle of a word */ int tplace; int tlength; int nparen; char paren[MAX_PAREN]; int group; int ngrouper; int nescaper; int nseparator; if(text==0) return -1; tplace=0; wplace=0; nword=0; nparen=0; tlength=Slength(text); ngrouper=Slength(grouper)/2; nseparator=Slength(separator); nescaper=Slength(escaper); for(tplace=0; tplace<tlength; tplace++) { /* * are we inside a group? If so, see if this is the end. */ if(nparen>0) { if(GrouperStop(ngrouper,grouper,paren[nparen-1],text[tplace])>=0) { word[nword][wplace]=text[tplace]; wplace++; nparen--; continue; } } /* * Is this the start of a group? */ if(nparen<=0) { group=GrouperStart(ngrouper,grouper,text[tplace]); if(nparen<MAX_PAREN && group>=0) { word[nword][wplace]=text[tplace]; wplace++; paren[nparen]=text[tplace]; nparen++; continue; } } /* * Is this an escape character? */ if(nparen<=0 && Sisoneof(escaper,text[tplace])>=0) { tplace++; word[nword][wplace]=text[tplace]; wplace++; continue; } /* * Is this a separator character? */ if(nparen<=0 && Sisoneof(separator,text[tplace])>=0) { if((!condense) || (wplace!=0)) { word[nword][wplace]=0; nword++; wplace=0; } continue; } /* * Just a regular old character. Put it in the output word. */ word[nword][wplace]=text[tplace]; wplace++; } if(wplace>0) { word[nword][wplace]=0; nword++; } return nword; } /* * Extract the word in the specified position. * Uses the same parameters as Swords() and follows * the same parsing rules. */ int SextractNoNest(char *text, int condense, char *separator, char *grouper, char *escaper, int position, char *word) { int nword; /* number of words already found */ int wplace; /* set if we are in the middle of a word */ int tplace; int tlength; int nparen; char paren[MAX_PAREN]; int group; int ngrouper; int nescaper; int nseparator; Sempty(word); if(text==0) return -1; tplace=0; wplace=0; nword=0; nparen=0; tlength=Slength(text); ngrouper=Slength(grouper)/2; nseparator=Slength(separator); nescaper=Slength(escaper); for(tplace=0; tplace<tlength; tplace++) { /* * are we inside a group? If so, see if this is the end. */ if(nparen>0) { if(GrouperStop(ngrouper,grouper,paren[nparen-1],text[tplace])>=0) { if(nword==position) { word[wplace]=text[tplace]; } wplace++; nparen--; continue; } } /* * Is this the start of a group? */ if(nparen<=0) { group=GrouperStart(ngrouper,grouper,text[tplace]); if(nparen<MAX_PAREN && group>=0) { if(nword==position) { word[wplace]=text[tplace]; } wplace++; paren[nparen]=text[tplace]; nparen++; continue; } } /* * Is this an escape character? */ if(nparen<=0 && Sisoneof(escaper,text[tplace])>=0) { tplace++; if(nword==position) { word[wplace]=text[tplace]; } wplace++; continue; } /* * Is this a separator character? */ if(nparen<=0 && Sisoneof(separator,text[tplace])>=0) { if((!condense) || (wplace!=0)) { if(nword==position) word[wplace]=0; nword++; if(nword>position) break; wplace=0; } continue; } /* * Just a regular old character. Put it in the output word. */ if(nword==position) { word[wplace]=text[tplace]; } wplace++; } if(wplace>0) { if(nword==position) word[wplace]=0; nword++; } if(nword>position) return 0; else return -1; } /* * Extract the word in the specified position. * Uses the same parameters as Swords() and follows * the same parsing rules. */ int Sextract(char *text, int condense, char *separator, char *grouper, char *escaper, int position, char *word) { int nword; /* number of words already found */ int wplace; /* set if we are in the middle of a word */ int tplace; int tlength; int nparen; char paren[MAX_PAREN]; int group; int ngrouper; int nescaper; int nseparator; Sempty(word); if(text==0) return -1; tplace=0; wplace=0; nword=0; nparen=0; tlength=Slength(text); ngrouper=Slength(grouper)/2; nseparator=Slength(separator); nescaper=Slength(escaper); for(tplace=0; tplace<tlength; tplace++) { /* * are we inside a group? If so, see if this is the end. */ if(nparen>0) { if(GrouperStop(ngrouper,grouper,paren[nparen-1],text[tplace])>=0) { if(nword==position) { word[wplace]=text[tplace]; } wplace++; nparen--; continue; } } /* * Is this the start of a group? */ group=GrouperStart(ngrouper,grouper,text[tplace]); if(nparen<MAX_PAREN && group>=0) { if(nword==position) { word[wplace]=text[tplace]; } wplace++; paren[nparen]=text[tplace]; nparen++; continue; } /* * Is this an escape character? */ if(nparen<=0 && Sisoneof(escaper,text[tplace])>=0) { tplace++; if(nword==position) { word[wplace]=text[tplace]; } wplace++; continue; } /* * Is this a separator character? */ if(nparen<=0 && Sisoneof(separator,text[tplace])>=0) { if((!condense) || (wplace!=0)) { if(nword==position) word[wplace]=0; nword++; if(nword>position) break; wplace=0; } continue; } /* * Just a regular old character. Put it in the output word. */ if(nword==position) { word[wplace]=text[tplace]; } wplace++; } if(wplace>0) { if(nword==position) word[wplace]=0; nword++; } if(nword>position) return 0; else return -1; } /* * Blanks the word in the specified position. * Uses the same parameters as Swords() and follows * the same parsing rules. */ int SblankWord(char *text, int condense, char *separator, char *grouper, char *escaper, int position) { int nword; /* number of words already found */ int wplace; /* set if we are in the middle of a word */ int tplace; int tlength; int nparen; char paren[MAX_PAREN]; int group; int ngrouper; int nescaper; int nseparator; if(text==0) return -1; tplace=0; wplace=0; nword=0; nparen=0; tlength=Slength(text); ngrouper=Slength(grouper)/2; nseparator=Slength(separator); nescaper=Slength(escaper); for(tplace=0; tplace<tlength; tplace++) { /* * are we inside a group? If so, see if this is the end. */ if(nparen>0) { if(GrouperStop(ngrouper,grouper,paren[nparen-1],text[tplace])>=0) { if(nword==position) { text[tplace] = ' '; /* blank out this word in the text */ } wplace++; nparen--; continue; } } /* * Is this the start of a group? */ group=GrouperStart(ngrouper,grouper,text[tplace]); if(nparen<MAX_PAREN && group>=0) { paren[nparen]=text[tplace]; nparen++; if(nword==position) { text[tplace] = ' '; /* blank out this word in the text */ } wplace++; continue; } /* * Is this an escape character? */ if(nparen<=0 && Sisoneof(escaper,text[tplace])>=0) { tplace++; if(nword==position) { text[tplace] = ' '; /* blank out this word in the text */ } wplace++; continue; } /* * Is this a separator character? */ if(nparen<=0 && Sisoneof(separator,text[tplace])>=0) { if((!condense) || (wplace!=0)) { nword++; if(nword>position) break; wplace=0; } continue; } /* * Just a regular old character. Put it in the output word. */ if(nword==position) { text[tplace] = ' '; /* blank out this word in the text */ } wplace++; } if(wplace>0) { nword++; } if(nword>position) return 0; else return -1; } /* * Blanks the separator in the specified position. * Uses the same parameters as Swords() and follows * the same parsing rules. */ int SblankSeparator(char *text, char *separator, char *grouper, char *escaper, int position) { int nword; /* number of words already found */ int wplace; /* set if we are in the middle of a word */ int tplace; int tlength; int nparen; char paren[MAX_PAREN]; int group; int ngrouper; int nescaper; int nseparator; if(text==0) return -1; tplace=0; wplace=0; nword=0; nparen=0; tlength=Slength(text); ngrouper=Slength(grouper)/2; nseparator=Slength(separator); nescaper=Slength(escaper); for(tplace=0; tplace<tlength; tplace++) { /* * are we inside a group? If so, see if this is the end. */ if(nparen>0) { if(GrouperStop(ngrouper,grouper,paren[nparen-1],text[tplace])>=0) { wplace++; nparen--; continue; } } /* * Is this the start of a group? */ group=GrouperStart(ngrouper,grouper,text[tplace]); if(nparen<MAX_PAREN && group>=0) { paren[nparen]=text[tplace]; nparen++; wplace++; continue; } /* * Is this an escape character? */ if(nparen<=0 && Sisoneof(escaper,text[tplace])>=0) { tplace++; wplace++; continue; } /* * Is this a separator character? */ if(nparen<=0 && Sisoneof(separator,text[tplace])>=0) { if(wplace!=0) { if(nword==position) { text[tplace] = ' '; /* blank out this separator in the text */ } nword++; if(nword>position) break; wplace=0; } continue; } wplace++; } if(wplace>0) { nword++; } if(nword>position) return 0; else return -1; } int SnoBlank(char *result, char *source) { int got; if(result==0) return -1; else if(source==0) { Sempty(result); return 0; } got=Sextract(source,1," \t","","",0,result); if(got==1) return 0; else return -1; } /*************************************************************** * * Sgreater() - indicate if string is greater than another * * Accepts string1 and string2, returns TRUE if string1 > string2, * otherwise returns FALSE. The check is strictly with regard * to ASCII order of the characters! * ***************************************************************/ #define TRUE 1 #define FALSE 0 int Sgreater(char *string1, char *string2) { /* if string1 is NULL, it's clearly not greater than anything, but * if string2 is NULL and string1 isn't, then we'll say it's greater */ if (!string1) return FALSE; if (!string2) return TRUE; /* now we loop through while they're equal, until they're unequal * and a decision is made, or one of them reaches the end */ while (*string1 && *string2) { if (*string1 > *string2) /* we are triumphant */ return TRUE; if (*string1 < *string2) /* we are desolate and defeated */ return FALSE; ++string1; ++string2; } /* we reached the end; if string1 is zero, it's not greater, but * otherwise string2 must have become zero, and we win the prize */ if (*string1 == '\0') return FALSE; else return TRUE; }
//convert hexstring to len bytes of data //returns 0 on success, -1 on error //data is a buffer of at least len bytes //hexstring is upper or lower case hexadecimal, NOT prepended with "0x" int hex2data(unsigned char *data, const char *hexstring, unsigned int len) { unsigned const char *pos = (unsigned const char *)hexstring; char *endptr; size_t count = 0; if ((hexstring[0] == '\0') || (strlen(hexstring) % 2)) { //hexstring contains no data //or hexstring has an odd length return -1; } for(count = 0; count < len; count++) { char buf[5] = {'0', 'x', pos[0], pos[1], 0}; data[count] = strtol(buf, &endptr, 0); pos += 2 * sizeof(char); if (endptr[0] != '\0') { //non-hexadecimal character encountered return -1; } } return 0; }