BadgerDB
/afs/cs.wisc.edu/u/n/w/nwilliam/private/workspace/Quut/src/parser/SqlScanner.h
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
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends