/* vtom.c - Copyright 1984, 1985, 1986 STSC, Inc. Property of STSC, Inc. */ #include #include #include #include #include #include "varmac.h" #include "errmacro.h" #define STDIN 0 #define STDOUT 1 #define TRUE 1 #define FALSE 0 #define BUFSIZE 30000 #define BUFOUT 40000 extern int errno, errinfo; char bufl[BUFSIZE]; /* Left arg Input buffer */ char bufr[BUFSIZE]; /* Right arg Input buffer */ char buf2[BUFOUT]; /* Output buffer */ int done() /* Exit routine */ { exit(0); } main(argc, argv) /* Main entry point for vtom routine */ int argc; /* argument count and */ char *argv[]; /* ... vector passed down from main's caller */ { long initbuf2(); /* Set up result object framework */ unsigned int getarg(); /* Fetch object from input stream */ register unsigned int len; /* Length of input stream */ register int wordlen; /* Length of a word */ register int maxwordlen; /* Length of longest word */ register unsigned int words; /* Number of words in stream */ register unsigned int n; /* Counter */ register char *inptr; /* Input pointer (into the vector) */ register char *inlim; /* 1 + Limit of input pointer */ register char *outptr; /* Output pointer (into the result matrix) */ register char *endptr; /* End of input values */ signal(SIGTERM, done); for (;;) { /* Loop until termination signal received */ /* Wait for left argument to qXP to arrive in input. This external process uses only the right argument, so the left argument is read into bufl[] and then simply ignored. */ getarg(bufl); /* Read the right argument into bufr[] */ len = getarg(bufr); if (len == -1) { /* Too much data for buffer */ error(WS_FULL); continue; } if (*desc(bufr) != CHAR) { error(DOMAIN_ERROR); continue; } if (*rank(bufr) != 1) { error(RANK_ERROR); continue; } /**** fprintf(stderr, "main> got %d bytes, nelm %d, desc %d, rank %d\r\n", len, *nelm(bufr), *desc(bufr), *rank(bufr)); ****/ /* Process the input: Count the number of tokens (sequences of non-blank characters) and keep a record of the longest sequence seen. These determine the shape of the matrix result */ len = *nelm(bufr); inptr = (char *)values(bufr); inlim = inptr + len; words = 0; wordlen = 0; maxwordlen = 0; while ( inptr < inlim ) { if ( *inptr++ == ' ' ) { if ( wordlen > 0 ) words++; if ( wordlen > maxwordlen ) maxwordlen = wordlen; wordlen = 0; } else { wordlen++; } } if ( wordlen > 0 ) words++; if ( wordlen > maxwordlen ) maxwordlen = wordlen; /** Prepare result space **/ len = initbuf2(CHAR, 2, (long) maxwordlen * (long) words); if (len == -1) { error(WS_FULL); continue; } *shape(buf2) = (long) words; /* Rows */ *(shape(buf2)+1) = (long) maxwordlen; /* Columns */ /****** fprintf(stderr, "rows>%d cols%d\n\r", words, maxwordlen ); ***/ /* Copy the input from the vector into the matrix */ inptr = valuesv(bufr); outptr = valuesm(buf2); endptr = *nelm(bufr) + inptr; for (n=0; n < words; n++) { wordlen = 0; while ( *inptr == ' ' ) inptr++; /* Skip blanks */ /* Copy input word to output */ while ( *inptr != ' ' && wordlen < maxwordlen) { *outptr++ = *inptr++; wordlen++; if (inptr >= endptr) break; } while ( wordlen++ < maxwordlen ){/* Pad with blanks */ *outptr++ = ' '; } } if (*length(buf2) != *tlength(buf2)) { /* Something that can't happen did happen*/ error(SYSTEM_ERROR); } else { /* Send result back to APL */ /**** fprintf(stderr, "writing %d bytes to pipe\r\n", len);*/ write(STDOUT, buf2, (unsigned) len); } } } error(type) /* Return Error response to APL */ int type; { long errtyp[2]; errtyp[0] = -1; /* Flag Error response */ errtyp[1] = (long) type; /* Error type */ write(STDOUT, errtyp, 8); fprintf(stderr, "error in vtom\r\n"); return; } long initbuf2(d, r, n) /* Define result buffer for return object */ register char d; /* descriptor byte */ register char r; /* rank byte */ register long n; /* nelm */ { long varsize(); register long len; /** Prepare result space **/ len = varsize(d, r, n); len += WSMGROH; /* Length and refcount too */ if (len > BUFOUT) { return(-1); } *length(buf2) = len; /* Leading byte length of result */ *tlength(buf2) = len; /* Trailing byte length of result */ *refcount(buf2)= 1L; /* Initialize reference count */ *desc(buf2) = d; /* Result Descriptor */ *rank(buf2) = r; /* Result rank */ *nelm(buf2) = n; /* Number of Elements */ return(len); } long varsize(d, r, n) /* Computes size needed for a variable */ register char d; /* descriptor byte */ register char r; /* rank byte */ register long n; /* nelm */ { register long z = 4+4; /* desc,rank word + nelm word */ z += 4 * r; /* one fullword for each coordinate */ switch (d) { case CHAR: z += n; break; case BOOL: z += ( n >> 3 ) + ((n & 7 ) ? 1 : 0); break; case INT: z += n * sizeof( long ); break; case FLOAT: z += n * sizeof( double ); break; default: fprintf (stderr,"unknown type\n\r"); return (0); } /* Round up to fullword if needed */ z = 0xfffffffc & (z+3); return(z); } unsigned int getarg(buffer) /* Empty pipe into local buffer */ register char *buffer; /* Return length of data object, or -1 for error */ { register unsigned int bytes, len, n; register char *bufp; n = read(STDIN, buffer, 4); /* Read length of Input */ bytes = *(int *) buffer; /* Length of input data */ len = bytes - 4; /* Remainder to read */ if (bytes > BUFSIZE) { /* Too much, clean up, WS full */ while (len > 0) { /* Pipe read transfers up to 5120 bytes per read */ n = read(STDIN, buffer, len); /* Purge rest of Input */ fprintf(stderr, "too much data, ask %u, got %u\r\n", len, n); len -= n; } return(-1); } bufp = buffer + 4; while (len > 0) { n = read(STDIN, bufp, len); /* Read rest of Input */ len -= n; bufp += n; } /***** fprintf(stderr, "getarg> got %u bytes, nelm %ld, desc %d, rank %d\r\n", bytes, *nelm(buffer), *desc(buffer), *rank(buffer)); ******/ return(bytes); }