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