/****************************************************************************/ // MGRMISC.C 05.11.1990 / 06.06.1992 /****************************************************************************/ /* */ /* Copyright (c) 1989-1993 Bernhard Strassl */ /* Institute for Applied Computer Science and Information Systems */ /* University of Vienna, Austria */ /* */ /* See file COPYRIGHT in this directory for details. If this file is */ /* missing please mail to bernhard@ani.univie.ac.at */ /****************************************************************************/ #include #include #include #include #include extern "C" { int strcasecmp(const char*, const char*); } #ifndef SYS_SUBSTVAR #define SYS_SUBSTVAR(n) ":" << n #endif SqlParser::SqlParser() { inputs = new BindDescr; outputs = new BindDescr; all = new BindDescr; tokndx = 0; indP = FALSE; } char* SqlParser::parse(char* stmt) { BindInfo* bi; bool inout = FALSE; // FALSE = :token is input (bindvar) // TRUE = :token is output (select buffer) bool update = FALSE; // TRUE while xxx = :xxx statements are expected int tmpType, tmpLength; int inCount = 0, outCount = 0; int* curCounter = &inCount; BindDescr* curDescr = inputs; int stmtlen = strlen(stmt) + 1; char* outbuff = new char[stmtlen]; char* insep = ""; char* upsep = ""; istrstream in(stmt, stmtlen - 1); ostrstream out; while(in >> tokbuf) { if(!strcasecmp(tokbuf, P_SELECTKEY)) { inout = TRUE; // :token is database output (select buffers) curCounter = &outCount; curDescr = outputs; if(*insep == ',') { insep = ""; out << " "; } continue; } if(update == TRUE) { if(!strcasecmp(tokbuf, P_WHEREKEY)) update = FALSE; else out << upsep; upsep = ""; } if(!strcasecmp(tokbuf, P_UPDATEKEY)) update = TRUE; if(tokbuf[0] == ':') { tmpType = getType(); tmpLength = getLength(); bi = new BindInfo(++(*curCounter), (void* )NULL, tmpType, tmpLength, 0, indP); indP = FALSE; // reset to FALSE after BindInfo knows about it curDescr->addInfo((SqlInfo* )bi); all->addInfo((SqlInfo* )bi); if(curDescr == inputs) { out << insep << " " << SYS_SUBSTVAR(*curCounter); insep = upsep = ","; } continue; } if(inout == TRUE) { inout = FALSE; curCounter = &inCount; curDescr = inputs; } else { if(*insep == ',') { insep = ""; out << " "; } } out << tokbuf << " "; } out.put('\0'); return(strcpy(new char[strlen(out.str()) + 1] /* outbuff */, out.str())); } int SqlParser::getType() { char* aToken; for(int i = 1; isalpha(tokbuf[i]); i++); switch(tokbuf[i]) { case '[': // length following... tokndx = i + 1; break; case '?': // uses indicator variable... indP = TRUE; tokndx = 0; break; case ',': case ' ': case '\0': tokndx = 0; break; default: cb_error("class SqlParser: syntax error in SQL statement"); return(0); } tokbuf[i] = '\0'; for(int j = 0; j < CB_MAX_PARSERCONST; j++) { if(aToken = (char * )pc[j]) { if(!strcasecmp(&(tokbuf[1]), aToken)) { if(j == CB_PBUFFER && !tokndx) cb_error("class SqlParser: buffer length must specified"); return(j); } } } cb_error("class SqlParser: invalid datatype, BUFFER assumed"); return(CB_PBUFFER); } int SqlParser::getLength() { int dec = 1, len = 0; char chk; if(!tokndx) return(0); for(int i = tokndx; isdigit(tokbuf[i]); i++); chk = tokbuf[i + 1]; if(tokbuf[i] != ']' || !(chk == '?' || chk == ',' || chk == ' ' || chk == '\0')) { cb_error("class SqlParser: syntax error in SQL statement"); return(0); } if(chk == '?') indP = TRUE; for(--i; i >= tokndx; i--) { len += ((tokbuf[i] - '0') * dec); dec *= 10; } return(len); } extern "C" { char* malloc(unsigned int); } void init_parser_constants() { // pc = new char*[CB_MAX_PARSERCONST]; pc = (char** )malloc(CB_MAX_PARSERCONST * sizeof(char*)); for(int i = 0; i < CB_MAX_PARSERCONST; i++) pc[i] = (char* )NULL; pc[CB_PBUFFER] = P_PBUFFER; pc[CB_PSTR] = P_PSTR; pc[CB_PUCHAR] = P_PUCHAR; pc[CB_PCHAR] = P_PCHAR; pc[CB_PUINT] = P_PUINT; pc[CB_PINT] = P_PINT; pc[CB_PULONG] = P_PULONG; pc[CB_PLONG] = P_PLONG; pc[CB_PFLOAT] = P_PFLOAT; pc[CB_PDOUBLE] = P_PDOUBLE; pc[CB_PDATE] = P_PDATE; pc[CB_PROWID] = P_PROWID; pc[CB_PRECNO] = P_PRECNO; pc[CB_PLSTRING] = P_PLSTRING; pc[CB_PLSTREAM] = P_PLSTREAM; // for(i = 0; i < CB_MAX_PARSERCONST; i++) }