BadgerDB
|
00001 // 00002 // Author: Jignesh M. Patel 00003 // EECS Department, University of Michigan 00004 // Date: August 2000 00005 // 00006 00013 #ifndef SQL_SCANNER_H 00014 #define SQL_SCANNER_H 00015 00016 #include <stdio.h> 00017 #include <stdlib.h> 00018 #include <string.h> 00019 00020 extern void yyerror(const char*); 00021 00022 // TODO: Remove these global defines - JmP 00023 #define PxxSCAN_MAXCHAR 1024 // size of buffer of strings 00024 #define PxxSCAN_NPARAM 20 // max params per function (unused) 00025 00026 // Class encapsulating the Scanner support routines 00027 class PxxScanner 00028 { 00029 private: 00030 char _tokBuf[PxxSCAN_MAXCHAR]; // SQL token buffer, which also limits the size of the SQL query string 00031 unsigned int _tokptr; // Pointer to current token area in tokBuf. 00032 char* _varnames[PxxSCAN_NPARAM]; // Parameter names 00033 bool _debug; 00034 bool _quit; 00035 bool _verbose; 00036 00037 public: 00038 00039 PxxScanner() { Reset(); _debug = false;} 00040 00041 void Reset() 00042 { 00043 _tokptr = 0; 00044 _quit = false; 00045 _verbose = false; 00046 // if (yyin) yyrestart(yyin); 00047 } 00048 00049 // 00050 // lcaseNcopy: copies src to dst, converting it to lowercase, stopping at the 00051 // end of src or after max characters. 00052 // 00053 // Returns: the length of dst (which may be less than the length of src, if src is too long). 00054 // 00055 int LcaseNcopy(char *dst, char *src, int max) 00056 { 00057 int len; 00058 00059 for(len = 0; len < max && src[len] != '\0'; ++len) 00060 { 00061 dst[len] = src[len]; 00062 if (src[len] >= 'A' && src[len] <= 'Z') dst[len] += 'a' - 'A'; 00063 } 00064 dst[len] = '\0'; 00065 00066 return len; 00067 } 00068 00069 // Save the SQL Text 00070 char* SaveText(char *s, int slen, bool lower=false) 00071 { 00072 // Check if we have enough buffer area to hold this token. 00073 if (_tokptr+slen > PxxSCAN_MAXCHAR-1) 00074 { 00075 yyerror("Not enough buffer space"); 00076 exit (1); 00077 } 00078 00079 if (lower) 00080 { 00081 LcaseNcopy(_tokBuf+_tokptr, s, slen); 00082 } 00083 else 00084 { 00085 strncpy(_tokBuf+_tokptr, s, slen); 00086 _tokBuf[_tokptr+slen] = '\0'; 00087 } 00088 00089 if (_debug) 00090 { 00091 int i; 00092 for (i=0; i<PxxSCAN_MAXCHAR; i++) 00093 if (_tokBuf[i] == '\0') std::cout << "- "; 00094 else std::cout << _tokBuf[i] << " "; 00095 std::cout << std::endl; 00096 } 00097 00098 char* retStr = _tokBuf + _tokptr; 00099 _tokptr += slen+1; 00100 return retStr; 00101 } 00102 00103 // Save the quoted string 00104 char* SaveQuotedText(char *qstring, int slen, bool lower=false) 00105 { 00106 // copy everything following beginning quote 00107 return SaveText(qstring+1, slen-2, lower); 00108 } 00109 00110 // Save a parameter reference (unused until we use SQL Parameters) 00111 char* SaveParam(char *n) 00112 { 00113 int i; 00114 char pbuf[10]; 00115 00116 // look up the variable name in the table 00117 for(i = 1; i < PxxSCAN_NPARAM; i++) { 00118 if(!_varnames[i]) { 00119 // not there, enter it 00120 _varnames[i] = strdup(n); 00121 break; 00122 } 00123 00124 if(!strcmp(_varnames[i],n)) 00125 break; //already present 00126 } 00127 00128 if(i >= PxxSCAN_NPARAM) { 00129 yyerror("Too many parameter references"); 00130 exit(1); 00131 } 00132 00133 // save #n referece by variable number 00134 sprintf(pbuf, " #%d", i); 00135 return SaveText(pbuf, strlen (pbuf) ); 00136 } 00137 00138 void SetVerbose(bool onoff) {_verbose = onoff;} 00139 void TriggerQuit() {_quit = true;} 00140 bool Quitting() {return _quit;} 00141 00142 void PrintQuery() const 00143 { 00144 if (_verbose) 00145 { 00146 std::cout << "Query: "; 00147 unsigned i; 00148 bool space = false; 00149 for (i=0; i<_tokptr; i++) 00150 if (_tokBuf[i] == '\0') { std::cout << ""; } 00151 else if (_tokBuf[i] == '\t' || _tokBuf[i] == '\n' || _tokBuf[i] == ' ') 00152 { 00153 // deal with whitespace 00154 if (!space) std::cout << " "; 00155 space = true; 00156 } 00157 else 00158 { 00159 std::cout << _tokBuf[i]; 00160 space = false; 00161 } 00162 } 00163 std::cout << std::endl; 00164 } 00165 }; 00166 00167 #endif