#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 0int 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;elsereturn 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 lengthreturn -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 encounteredreturn -1;}}return 0;}