1: # include   "../ingres.h"
   2: # include   "../aux.h"
   3: # include   "../symbol.h"
   4: # include   "../tree.h"
   5: # include   "../pipes.h"
   6: # include   "ovqp.h"
   7: 
   8: /*
   9: **	This file contains the string
  10: **	manipulation routines
  11: */
  12: 
  13: 
  14: 
  15: extern char *Ovqpbuf;
  16: 
  17: 
  18: concatsym(ss1, ss2)
  19: struct symbol   *ss1, *ss2;
  20: 
  21: /*
  22: **	Concat takes the two character strings in
  23: **	ss1 and ss2 and concatenates them together
  24: **	into a new location.
  25: **
  26: **	trailing blanks are removed from the first symbol.
  27: **	The size of the concatenation equals the sum of
  28: **	the two original strings.
  29: */
  30: 
  31: {
  32:     register struct symbol  *s1, *s2;
  33:     register char       *p;
  34:     int         size1, size2, i;
  35:     char            *px;
  36:     char            *bmove();
  37:     char            *need();
  38: 
  39:     s1 = ss1;
  40:     s2 = ss2;
  41: 
  42:     size1 = size(s1);   /* compute size w/o trailing blanks */
  43:     if (size1 == 0 && s1->len != 0)
  44:         size1++;    /* don't allow string to be trunc to zero length */
  45:     size2 = s2->len & 0377; /* size of second string remains the same */
  46:     i = (s1->len & 0377) + size2;   /* i equals sum of original sizes */
  47:     if (i > 255)
  48:         i = 255;    /* a string can't exceed this size */
  49:     if (size2 + size1 > 255)
  50:         size2 = 255 - size1;    /* adjust size2 to not exceed 255 */
  51: 
  52:     px = p = need(Ovqpbuf, i);  /* request the needed space */
  53:     p = bmove(cpderef(s1->value), p, size1);    /* copy first string */
  54:     p = bmove(cpderef(s2->value), p, size2);
  55:     cpderef(s1->value) = px;
  56:     s1->len = i;
  57:     /* pad with blanks if necessary */
  58:     i -= size1 - size2;
  59:     while (i--)
  60:         *p++ = ' ';
  61: 
  62: #	ifdef xOTR1
  63:     if (tTf(32, 1))
  64:     {
  65:         printf("Concat:");
  66:         prstack(s1);
  67:     }
  68: #	endif
  69: }
  70: 
  71: 
  72: size(sym)
  73: struct symbol   *sym;
  74: 
  75: /*
  76: **	Size determines the size of a character symbol
  77: **	without trailing blanks.
  78: */
  79: {
  80:     register char       *c;
  81:     register int        i;
  82:     register struct symbol  *s;
  83: 
  84:     s = sym;
  85:     c = cpderef(s->value);
  86:     i = s->len & 0377;
  87: 
  88:     for (c += i; i; i--)
  89:         if(*--c != ' ')
  90:             break;
  91: 
  92:     return (i);
  93: }
  94: 
  95: 
  96: /*
  97: **	Converts the numeric symbol to
  98: **	ascii. Formats to be used are determined
  99: **	by Out_arg.
 100: */
 101: 
 102: ascii(ss)
 103: struct symbol   *ss;
 104: {
 105:     register struct symbol  *s;
 106:     register int        i;
 107:     register char       *p;
 108:     char            temp[MAXFIELD];
 109:     extern struct out_arg   Out_arg;    /* used for float conversions */
 110:     char            *locv();
 111:     char            *need();
 112: 
 113:     s = ss;
 114:     p = temp;
 115:     switch(s->type)
 116:     {
 117: 
 118:       case INT:
 119:         if (s->len == 4)
 120:         {
 121:             i = Out_arg.i4width;
 122:             p = locv(i4deref(s->value));
 123:         }
 124:         else
 125:         {
 126:             itoa(i2deref(s->value), p);
 127:             if (s->len == 2)
 128:                 i = Out_arg.i2width;
 129:             else
 130:                 i = Out_arg.i1width;
 131:         }
 132:         break;
 133: 
 134:       case CHAR:
 135:         return;
 136: 
 137:       case FLOAT:
 138:         if (s->len == 4)
 139:         {
 140:             i = Out_arg.f4width;
 141:             ftoa(f4deref(s->value), p, i, Out_arg.f4prec, Out_arg.f4style);
 142:         }
 143:         else
 144:         {
 145:             i = Out_arg.f8width;
 146:             ftoa(f8deref(s->value), p, i, Out_arg.f8prec, Out_arg.f8style);
 147:         }
 148:     }
 149:     cpderef(s->value) = need(Ovqpbuf, i);
 150:     pmove(p, cpderef(s->value), i, ' ');    /* blank pad to fixed length i */
 151:     s->type = CHAR;
 152:     s->len = i;
 153: }
 154: 
 155: 
 156: /*
 157: **	LEXCOMP performs character comparisons between the two
 158: **	strings ss1 and ss2. All blanks and null are ignored in
 159: **	both strings. In addition pattern matching is performed
 160: **	using the "shell syntax". Pattern matching characters
 161: **	are converted to the pattern matching symbols PAT_ANY etc.
 162: **	by the scanner.
 163: **
 164: **	Pattern matching characters can appear in either or
 165: **	both strings. Since they cannot be stored in relations,
 166: **	pattern matching chars in both strings can only happen
 167: **	if the user types in such an expression.
 168: **
 169: **	examples:
 170: **
 171: **	"Smith, Homer" = "Smith,Homer"
 172: **
 173: **	"abcd" < "abcdd"
 174: **
 175: **	"abcd" = "aPAT_ANYd"
 176: **
 177: **	returns	<0 if s1 < s2
 178: **		 0 if s1 = s2
 179: **		>0 if s1 > s2
 180: */
 181: 
 182: lexcomp(ss1, len1, ss2, len2)
 183: char    *ss1, *ss2;
 184: int len1, len2;
 185: {
 186:     register char   *s1, *s2;
 187:     register int    l1;
 188:     int     l2;
 189:     char        c1, c2;
 190: 
 191:     s1 = ss1;
 192:     s2 = ss2;
 193:     l1 = len1;
 194:     l2 = len2;
 195: 
 196: loop:
 197:     while (l1--)
 198:     {
 199:         switch (c1 = *s1++)
 200:         {
 201: 
 202:           case ' ':
 203:           case '\0':
 204:             break;
 205: 
 206:           case PAT_ANY:
 207:             return (pmatch(s1, l1, s2, l2));
 208: 
 209:           case PAT_LBRAC:
 210:             return (lmatch(s1, l1, s2, l2));
 211: 
 212:           default:
 213:             while (l2--)
 214:             {
 215:                 switch (c2 = *s2++)
 216:                 {
 217: 
 218:                   case ' ':
 219:                   case '\0':
 220:                     continue;
 221: 
 222:                   case PAT_ANY:
 223:                     return (pmatch(s2, l2, --s1, ++l1));
 224: 
 225:                   case PAT_LBRAC:
 226:                     return (lmatch(s2, l2, --s1, ++l1));
 227: 
 228:                   default:
 229:                     if (c1 == c2)
 230:                         goto loop;
 231:                     if (c1 == PAT_ONE || c2 == PAT_ONE)
 232:                         goto loop;
 233:                     return (c1 - c2);
 234:                 }
 235:             }
 236:             return (1); /* s1 > s2 */
 237:         }
 238:     }
 239: 
 240:     /* examine remainder of s2 for any characters */
 241:     while (l2--)
 242:         if ((c1 = *s2++) != ' ' && (c1 != '\0') && (c1 != PAT_ANY))
 243:             return (-1);    /* s1 < s2 */
 244:     return (0);
 245: }
 246: 
 247: 
 248: pmatch(pat, plen, str, slength)
 249: char    *pat;       /* the string holding the pattern matching char */
 250: char    *str;       /* the string to be checked */
 251: int plen, slength;  /* the lengths */
 252: {
 253:     register char   d, *s;
 254:     register int    slen;
 255:     char        c;
 256: 
 257:     s = str;
 258:     slen = slength;
 259: 
 260:     if (plen == 0)
 261:         return  (0);    /* a match if no more chars in p */
 262: 
 263:     /*
 264: 	** If the next character in "pat" is not another
 265: 	** pattern matching character, then scan until
 266: 	** first matching char and continue comparison.
 267: 	*/
 268:     if ((c = *pat) != PAT_ANY && c != PAT_LBRAC && c != PAT_ONE)
 269:     {
 270:         while (slen--)
 271:         {
 272:             if ((d = *s) == c || d == PAT_ANY || d == PAT_LBRAC && d != PAT_ONE)
 273:             {
 274:                 if (lexcomp(pat, plen, s, slen + 1) == 0)
 275:                     return (0);
 276:             }
 277:             s++;
 278:         }
 279:     }
 280:     else
 281:     {
 282:         while (slen)
 283:             if (lexcomp(pat, plen, s++, slen--) == 0)
 284:                 return (0); /* match */
 285:     }
 286:     return (-1);    /* no match */
 287: }
 288: 
 289: lmatch(pat, plen, str, slen)
 290: char    *pat;   /* the string holding the pattern matching char */
 291: char    *str;   /* the other string */
 292: int plen, slen; /* their respective sizes */
 293: {
 294:     register char   *p, *s;
 295:     register int    cc;
 296:     int     oldc, c, found;
 297: 
 298:     p = pat;
 299:     s = str;
 300: 
 301:     /* find a non-blank, non-null char in s */
 302:     while (slen--)
 303:     {
 304:         if ((c = *s++) != ' ' && c != '\0')
 305:         {
 306:             /* search for a match on 'c' */
 307:             found = 0;  /* assume failure */
 308:             oldc = 0777;    /* make previous char large */
 309: 
 310:             while (plen--)
 311:             {
 312: 
 313:                 switch(cc = *p++)
 314:                 {
 315: 
 316:                   case PAT_RBRAC:
 317:                     if (found)
 318:                         return (lexcomp(p, plen, s, slen));
 319:                     return (-1);
 320: 
 321:                   case '-':
 322:                     if (plen-- == 0)
 323:                         return (-1);    /* not found */
 324:                     if (oldc <= c && c <= (cc = *p++))
 325:                         found++;
 326:                     break;
 327: 
 328:                   default:
 329:                     if (c == (oldc = cc))
 330:                         found++;
 331:                 }
 332:             }
 333:             return (-1);    /* no match */
 334:         }
 335:     }
 336:     return (1);
 337: }

Defined functions

ascii defined in line 102; used 1 times
concatsym defined in line 18; used 1 times
lexcomp defined in line 182; used 5 times
lmatch defined in line 289; used 2 times
pmatch defined in line 248; used 2 times
size defined in line 72; used 1 times
  • in line 42
Last modified: 1995-03-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3210
Valid CSS Valid XHTML 1.0 Strict