/*--------------------------------------------------------------------------- Splitter: a module to break a line in a list of words, therby determinig type and storing results in a List. Mark Koennecke October 1996 Free for non commercial use, no warranties of any kind taken. ---------------------------------------------------------------------------*/ #include "fortify.h" #include #include #include #include "tcl.h" #include "splitter.h" typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType; /* ------------------------ local prototypes ------------------------------*/ static TokenList *CreateToken(TokenList *pN, TokenList *P); static CharType CheckSpecial(char *pWord); static int isEnd(char c); /*=========================================================================*/ static TokenList *CreateToken(TokenList *pN, TokenList *pP) { TokenList *pRes = NULL; pRes = (TokenList *) malloc(sizeof(TokenList)); if(!pRes)return NULL; pRes->fVal = .0; pRes->iVal = 0; pRes->Type = eUndefined; pRes->text = NULL; pRes->pNext = pN; if(pN) { pN->pPrevious = pRes; } pRes->pPrevious = pP; if(pP) { pP->pNext = pRes; } return pRes; } /*---------------------------------------------------------------------------*/ static CharType CheckSpecial(char *pWord) { CharType eRes = eText; int iFlag = 0; if(isspace(pWord[0]))return(eSpace); if(isdigit(pWord[0]))return(eNum); /* simple cases */ if(pWord[0] == '*') return(eeText); if(pWord[0] == '/') return(eeText); if(pWord[0] == '\\') return(eeText); if(pWord[0] == ']') return(eeText); if(pWord[0] == '[') return(eeText); if(pWord[0] == '"') return(eQuote); /* difficult cases, next characters will be searched for decision*/ if( pWord[0] == '-') iFlag = 1; if( pWord[0] == '+') iFlag = 1; if( pWord[0] == '.') iFlag = 1; if (iFlag == 1) { if( isdigit(pWord[1]) ) { return(eNum); } else if( isalpha(pWord[1] )) { return(eeText); } else if (!isspace( pWord[1]) ) { pWord++; return(CheckSpecial(pWord)); } } return(eeText); } /*--------------------------------------------------------------------------*/ static int isEnd(char c) { if( (c == '\0') || (c == '\n') || (c == '\r') ) { return 2; } else if ( c== ' ') { return 1; } else { return 0; } } /*--------------------------------------------------------------------------*/ TokenList *SplitText(char *pLine) { TokenList *pList = NULL; TokenList *pCurrent; char pBueffel[256]; char *pChar; CharType eWhat; int i, n; if(!pLine)return NULL; pChar = pLine; /* loop through line */ while(isEnd(*pChar) != 2) { eWhat = CheckSpecial(pChar); /* skip spaces */ if (eWhat == eSpace) { pChar++; continue; } /* no space, read word in first place */ if(eWhat == eQuote) { i = 0; pChar++; while( (isEnd(*pChar) != 2) && (CheckSpecial(pChar) != eQuote) && i < 250) { if (*pChar == '\\') { pBueffel[i] = Tcl_Backslash(pChar, &n); pChar += n; } else { pBueffel[i] = *pChar; pChar++; } i++; } pBueffel[i] = '\0'; pChar++; eWhat = eeText; } else { i = 0; while(!isEnd(*pChar)) { pBueffel[i] = *pChar; i++; pChar++; } pBueffel[i] = '\0'; } if(pList == NULL) { pList = CreateToken(NULL,NULL); pCurrent = pList; } else { pCurrent = CreateToken(NULL,pCurrent); } if(!pCurrent) return NULL; /* copyy text always */ pCurrent->text = strdup(pBueffel); if(eWhat == eeText) { pCurrent->Type = eText; } else if(eWhat == eNum) { /* float ? */ if(strchr(pBueffel,'.')== NULL) { pCurrent->Type = eInt; sscanf(pBueffel,"%ld",&(pCurrent->iVal)); } else { pCurrent->Type = eFloat; sscanf(pBueffel,"%f",&(pCurrent->fVal)); } } /* pChar++;*/ if(isEnd(*pChar) == 2)break; } /* eof big while */ return pList; } /*--------------------------------------------------------------------------*/ void DeleteTokenList(TokenList *pToken) { TokenList *pCurrent; TokenList *pTemp; pCurrent = pToken; while(pCurrent != NULL) { pTemp = pCurrent->pNext; if(pCurrent->text) { free(pCurrent->text); } free(pCurrent); pCurrent = pTemp; } } /*--------------------------------------------------------------------------*/ TokenList *SplitArguments(int argc, char *argv[]) { int i, ii; TokenList *pList = NULL; TokenList *pCurrent; CharType eWhat; /* loop through arguments */ for( i = 0; i < argc; i++) { /* figure out what we have */ for(ii = 0; ii < strlen(argv[i]); ii++) { eWhat = CheckSpecial(argv[i]); /* skip whitespace */ if(eWhat != eSpace) break; } /* Create Token */ if(pList == NULL) { pList = CreateToken(NULL, pList); pCurrent = pList; } else { pCurrent = CreateToken(NULL,pCurrent); } if(!pCurrent) return NULL; /* copy text always */ pCurrent->text = strdup(argv[i]); /* numbers */ if(eWhat == eNum) { /* float ? */ if(strchr(argv[i],'.')== NULL) { pCurrent->Type = eInt; /* sscanf(argv[i],"%d",&(pCurrent->iVal)); */ pCurrent->iVal = atoi(argv[i]); } else { pCurrent->Type = eFloat; sscanf(argv[i],"%f",&(pCurrent->fVal)); } } else { /* all else is text */ pCurrent->Type = eText; } } return pList; } /*--------------------------------------------------------------------------*/ int Text2Arg(char *pLine, int *argc, char **argv[]) { TokenList *pList = NULL; TokenList *pCurrent = NULL; char **margv = NULL; int margc = 0; int i = 0; /* split to a TokenList */ pList = SplitText(pLine); if(!pList) { return 0; } /* figure out how many args */ pCurrent = pList; while(pCurrent) { margc++; pCurrent = pCurrent->pNext; } /* allocate memory */ margv = (char **)malloc((margc + 2) * sizeof(char *)); if(!margv) { DeleteTokenList(pList); return 0; } /* copy to argc, argv */ *argc = margc; pCurrent = pList; i = 0; while(pCurrent) { margv[i] = strdup(pCurrent->text); i++; pCurrent = pCurrent->pNext; } /* done, clean up etc */ margv[i] = NULL; *argv = margv; DeleteTokenList(pList); return 1; } /*---------------------------------------------------------------------------*/ int Arg2Text(int argc, char *argv[], char *buf, int iBufLen) { int i, iBufCount = 0; strcpy(buf,"\0"); if(argc < 1) { return 1; } if(strlen(argv[0]) < iBufLen) { strcpy(buf, argv[0]); iBufCount += strlen(argv[0]); } else { return 0; } for(i = 1; i < argc; i++) { iBufCount += strlen(argv[i]) + 1; if(iBufCount >= iBufLen) { return 0; } strcat(buf," "); strcat(buf,argv[i]); } return 1; } /*--------------------------------------------------------------------------*/ int GetShellLine(FILE *fd, char *Buffer, int iBufLen) { char *pChar = NULL; while(fgets(Buffer,iBufLen-1,fd) != NULL) { if(Buffer[0] != '#') { return 1; } } return EOF; } /*---------------------------------------------------------------------*/ int isNumeric(char *pText) { int i, ii, iGood; static char pNum[13] = {"1234567890.+-"}; for(i = 0; i < strlen(pText); i++) { for(ii = 0; ii < 13; ii++) { iGood = 0; if(pText[i] == pNum[ii]) { iGood = 1; break; } } if(!iGood) { return 0; } } return 1; } /*--------------------------------------------------------------------------*/ char *Arg2Tcl0(int argc, char *argv[], char *buffer, int buffersize, char *prepend) { int i, l, firstArgToQuote, quote, prependlen; char ch; char *res, *arg; if (prepend) { prependlen = strlen(prepend); l = prependlen + 1; } else { prependlen = 0; l = 0; } firstArgToQuote = argc; quote = 0; for (i=0; i buffersize) { buffer = calloc(l,1); if (buffer == NULL) return NULL; } res = buffer; if (prepend) { strcpy(res, prepend); res += prependlen; *res++ = ' '; } for (i=0; i= firstArgToQuote) *res++ = '"'; arg = argv[i]; ch = *arg++; while (ch != '\0') { switch (ch) { case '"': *res++ = '\\'; *res++ = '"'; break; case '\\': *res++ = '\\'; *res++ = '\\'; break; case '\r': *res++ = '\\'; *res++ = 'r'; break; case '\n': *res++ = '\\'; *res++ = 'n'; break; default: *res++ = ch; break; } ch = *arg++; } if (i >= firstArgToQuote) *res++ = '"'; *res++ = ' '; } if (res > buffer) res--; /* remove trailing space */ *res='\0'; return buffer; } /*--------------------------------------------------------------------------*/ char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize) { return Arg2Tcl0(argc, argv, buffer, buffersize, NULL); } /*----------------------------------------------------------------------------*/ char *sicsNextNumber(char *pStart, char pNumber[80]){ int charCount = 0; pNumber[0] = '\0'; /* advance to first digit */ while(isspace(*pStart) && *pStart != '\0'){ pStart++; } if(*pStart == '\0'){ return NULL; } /* copy */ while(!isspace(*pStart) && *pStart != '\0' && charCount < 78){ pNumber[charCount] = *pStart; pStart++; charCount++; } pNumber[charCount] = '\0'; return pStart; } /*============================================================================ Testprogram, can be activated by defining MAIN */ #ifdef MAIN int main(int argc, char *argv[]) { TokenList *pList = NULL; TokenList *pCurrent; pList = SplitText("Hallo 22 mal 0.8 Furz"); pCurrent = pList; while(pCurrent) { if(pCurrent->Type == eText) { printf("TextToken = %s\n",pCurrent->text); } else if(pCurrent->Type == eFloat) { printf("FloatToken = %f\n",pCurrent->fVal); } else if(pCurrent->Type == eInt) { printf("IntToken = %d\n",pCurrent->iVal); } else { puts("ERRRRRRRRRROOOOOOOOOOOORRRRRRR!!!!!!!!"); } pCurrent = pCurrent->pNext; } DeleteTokenList(pList); } #endif