void varread(void) /* read into variable */ { Datum d; extern Biobuf *bin; Symbol *var = (Symbol *) *pc++; int c; Again: do c = Bgetc(bin); while(c==' ' || c=='\t' || c=='\n'); if(c == Beof){ Iseof: if(moreinput()) goto Again; d.val = var->u.val = 0.0; goto Return; } if(strchr("+-.0123456789", c) == 0) execerror("non-number read into", var->name); Bungetc(bin); if(Bgetd(bin, &var->u.val) == Beof) goto Iseof; else d.val = 1.0; Return: var->type = VAR; push(d); }
int main(void) { while (moreinput()) { parse(); optimize(); addable(); generate(); peephole(); writeout(); } return 0; }
void varread(void) /* read into variable */ { Datum d; extern FILE *fin; Symbol *var = (Symbol *) *pc++; Again: switch (fscanf(fin, "%lf", &var->u.val)) { case EOF: if (moreinput()) goto Again; d.val = var->u.val = 0.0; break; case 0: execerror("non-number read into", var->name); break; default: d.val = 1.0; break; } var->type = VAR; push(d); }
Rune * getline(Rune *buf, long n, Biobufhdr *fin) { int i, c; i = 0; do { while (i < n-1 && (c=Bgetrune(fin)) != Beof) { buf[i++] = c; if (c == '\n') break; } if (c != Beof && c != '\n') while ((c=Bgetrune(fin)) != Beof && c != '\n') ; } while (c != Beof && moreinput(fin)); if (i == 0) return nil; else { buf[i-1] = '\0'; return buf; } }
int __pmtracegetPDU(int fd, int timeout, __pmTracePDU **result) { int need, len; char *handle; static int maxsize = TRACE_PDU_CHUNK; __pmTracePDU *pdubuf; __pmTracePDU *pdubuf_prev; __pmTracePDUHdr *php; /* * This stuff is a little tricky. What we try to do is read() * an amount of data equal to the largest PDU we have (or are * likely to have) seen thus far. In the majority of cases * this returns exactly one PDU's worth, i.e. read() returns * a length equal to php->len. * * For this to work, we have a special "mode" of -1 * to pduread() which means read, but return after the * first read(), rather than trying to read up to the request * length with multiple read()s, which would of course "hang" * after the first PDU arrived. * * We need to handle the following tricky cases: * 1. We get _more_ than we need for a single PDU -- happens * when PDU's arrive together. This requires "moreinput" * to handle leftovers here (it gets even uglier if we * have part, but not all of the second PDU). * 2. We get _less_ than we need for a single PDU -- this * requires at least another read(), and possibly acquiring * another pdubuf and doing a memcpy() for the partial PDU * from the earlier call. */ if (__pmtracemoreinput(fd)) { /* some leftover from last time ... handle -> start of PDU */ pdubuf = more[fd].pdubuf; len = more[fd].len; __pmtracenomoreinput(fd); } else { if ((pdubuf = __pmtracefindPDUbuf(maxsize)) == NULL) return -oserror(); len = pduread(fd, (void *)pdubuf, maxsize, -1, timeout); } php = (__pmTracePDUHdr *)pdubuf; if (len < (int)sizeof(__pmTracePDUHdr)) { if (len == -1) { if (oserror() == ECONNRESET|| oserror() == ETIMEDOUT || oserror() == ENETDOWN || oserror() == ENETUNREACH || oserror() == EHOSTDOWN || oserror() == EHOSTUNREACH || oserror() == ECONNREFUSED) /* * failed as a result of pmdatrace exiting and the * connection being reset, or as a result of the kernel * ripping down the connection (most likely because the * host at the other end just took a dive) * * treat this like end of file on input * * from irix/kern/fs/nfs/bds.c seems like all of the * following are peers here: * ECONNRESET (pmdatrace terminated?) * ETIMEDOUT ENETDOWN ENETUNREACH EHOSTDOWN EHOSTUNREACH * ECONNREFUSED * peers for bds but not here: * ENETRESET ENONET ESHUTDOWN (cache_fs only?) * ECONNABORTED (accept, user req only?) * ENOTCONN (udp?) * EPIPE EAGAIN (nfs, bds & ..., but not ip or tcp?) */ len = 0; else fprintf(stderr, "__pmtracegetPDU: fd=%d hdr: %s", fd, osstrerror()); } else if (len > 0) fprintf(stderr, "__pmtracegetPDU: fd=%d hdr: len=%d, not %d?", fd, len, (int)sizeof(__pmTracePDUHdr)); else if (len == PMTRACE_ERR_TIMEOUT) return PMTRACE_ERR_TIMEOUT; else if (len < 0) fprintf(stderr, "__pmtracegetPDU: fd=%d hdr: %s", fd, pmtraceerrstr(len)); return len ? PMTRACE_ERR_IPC : 0; } php->len = ntohl(php->len); if (php->len < 0) { fprintf(stderr, "__pmtracegetPDU: fd=%d illegal len=%d in hdr\n", fd, php->len); return PMTRACE_ERR_IPC; } if (len == php->len) /* return below */ ; else if (len > php->len) { /* * read more than we need for this one, save it up for next time */ handle = (char *)pdubuf; moreinput(fd, (__pmTracePDU *)&handle[php->len], len - php->len); } else { int tmpsize; /* * need to read more ... */ __pmtracepinPDUbuf(pdubuf); pdubuf_prev = pdubuf; if (php->len > maxsize) tmpsize = TRACE_PDU_CHUNK * ( 1 + php->len / TRACE_PDU_CHUNK); else tmpsize = maxsize; if ((pdubuf = __pmtracefindPDUbuf(tmpsize)) == NULL) { __pmtraceunpinPDUbuf(pdubuf_prev); return -oserror(); } if (php->len > maxsize) maxsize = tmpsize; memmove((void *)pdubuf, (void *)php, len); __pmtraceunpinPDUbuf(pdubuf_prev); php = (__pmTracePDUHdr *)pdubuf; need = php->len - len; handle = (char *)pdubuf; /* block until all of the PDU is received this time */ len = pduread(fd, (void *)&handle[len], need, 0, timeout); if (len != need) { if (len == PMTRACE_ERR_TIMEOUT) return PMTRACE_ERR_TIMEOUT; if (len < 0) fprintf(stderr, "__pmtracegetPDU: error (%d) fd=%d: %s\n", (int)oserror(), fd, osstrerror()); else fprintf(stderr, "__pmtracegetPDU: len=%d, not %d? (fd=%d)\n", len, need, fd); fprintf(stderr, "hdr: len=0x%08x type=0x%08x from=0x%08x\n", php->len, (int)ntohl(php->type), (int)ntohl(php->from)); return PMTRACE_ERR_IPC; } } *result = (__pmTracePDU *)php; php->type = ntohl(php->type); php->from = ntohl(php->from); #ifdef PMTRACE_DEBUG if (__pmstate & PMTRACE_STATE_PDU) { int j; int jend = (int)(php->len+(int)sizeof(__pmTracePDU)-1)/(int)sizeof(__pmTracePDU); char *p; /* for Purify ... */ p = (char *)*result + php->len; while (p < (char *)*result + jend*sizeof(__pmTracePDU)) *p++ = '~'; /* buffer end */ fprintf(stderr, "[%" FMT_PID "]__pmtracegetPDU: %s fd=%d len=%d from=%d", (pid_t)getpid(), pdutypestr(php->type), fd, php->len, php->from); for (j = 0; j < jend; j++) { if ((j % 8) == 0) fprintf(stderr, "\n%03d: ", j); fprintf(stderr, "%8x ", (*result)[j]); } putc('\n', stderr); } #endif return php->type; }