# rdmake --- create a relation from a description file and a data file include "rdb_def.r.i" define (DB,#) relation_des rd (RDSIZE) integer i, j, type, len, errs integer fp, flen (MAXFIELDS), fdelim (MAXFIELDS), findex (MAXFIELDS), lastfp integer row (RDATASIZE) integer getlin, add_field_to_rd, ctoi, find_field, ctoc, isatty character str (MAXLINE), word (MAXLINE), name (MAXLINE) character buf (MAXDATASIZE) longint l longint gctol longreal d longreal ctod define (SYNERR (m), {errs += 1; call print (ERROUT,m ": *s"s, str)}) errs = 0 init_rd (rd) ### Read in and build the relation descriptor for (fp = 1; getlin (str, STDIN2) ~= EOF; fp += 1) { i = 1 call getword (str, i, word) select (word (1)) when ('i'c, 'I'c) type = INTEGER_TYPE when ('r'c, 'R'c) type = REAL_TYPE when ('s'c, 'S'c) { type = STRING_TYPE j = 2 len = ctoi (word, j) if (len == 0 || word (j) ~= EOS) SYNERR ("Illegal length") } else SYNERR ("Illegal data type") call getword (str, i, name) if (~ IS_LETTER (name (1))) SYNERR ("Illegal field name") else for (j = 1; name (j) ~= EOS; j += 1) if (~ IS_LETTER (name (j)) && ~ IS_DIGIT (name (j)) && name (j) ~= '_'c) { SYNERR ("Illegal field name") break } if (find_field (rd, name) ~= 0) SYNERR ("Duplicate name") findex (fp) = add_field_to_rd (rd, type, len, name) if (findex (fp) == 0) SYNERR ("Can't add field") flen (fp) = MAXDATASIZE fdelim (fp) = ' 'c repeat { call getword (str, i, word) select (word (1)) when ('d'c, 'D'c) fdelim (fp) = word (2) # May be an EOS when ('l'c, 'L'c) { j = 2 flen (fp) = ctoi (word, j) if (flen (fp) < 1 || word (j) ~= EOS) SYNERR ("Illegal input length") } when (EOS, '#'c) break else SYNERR ("Unrecognized word") } } if (errs > 0) stop call save_rd (rd, STDOUT) ### Construct and output the relation data if (isatty (STDOUT) == YES) call print_header (rd, STDOUT) lastfp = fp - 1 while (getlin (buf, STDIN) ~= EOF) { i = 1 for (fp = 1; fp <= lastfp; fp += 1) { while (buf (i) == fdelim (fp)) i += 1 for (j = 1; buf (i) ~= NEWLINE && buf (i) ~= EOS _ && buf (i) ~= fdelim (fp) && j <= flen (fp); _ {i += 1; j += 1}) str (j) = buf (i) str (j) = EOS if (buf (i) == fdelim (fp)) i += 1 select (RFTYPE (rd, findex (fp))) when (INTEGER_TYPE) { j = 1 l = gctol (str, j, 10) if (str (j) ~= EOS) call print (ERROUT, "*s: bad integer*n"s, str) call put_data (rd, findex (fp), row, l) } when (REAL_TYPE) { j = 1 d = ctod (str, j) if (str (j) ~= EOS) call print (ERROUT, "*s: bad real*n"s, str) call put_data (rd, findex (fp), row, d) } when (STRING_TYPE) { j = ctoc (str, word, RFLEN (rd, findex (fp)) + 1) for (j += 1; j <= RFLEN (rd, findex (fp)); j += 1) word (j) = ' 'c call put_data (rd, findex (fp), row, word) } } call put_row (rd, STDOUT, row) } if (isatty (STDOUT) == YES) call print_trailer (rd, STDOUT) stop end # getword --- isolate a word from a string subroutine getword (str, i, word) character str (ARB), word (MAXLINE) integer i integer j SKIPBL (str, i) for (j = 1; str (i) ~= ' 'c && str (i) ~= NEWLINE && str (i) ~= EOS; {i += 1; j += 1} ) word (j) = str (i) word (j) = EOS return end include "rdb_sub.r.i"