int utag(BW *bw) { BW *pbw; pbw = wmkpw(bw->parent, joe_gettext(_("Tag search: ")), &taghist, dotag, NULL, NULL, tag_cmplt, NULL, NULL, locale_map, 0); if (pbw && joe_isalnum_(bw->b->o.charmap,brch(bw->cursor))) { P *p = pdup(bw->cursor, "utag"); P *q = pdup(p, "utag"); int c; while (joe_isalnum_(bw->b->o.charmap,(c = prgetc(p)))) /* do nothing */; if (c != NO_MORE_DATA) { pgetc(p); } pset(q, p); while (joe_isalnum_(bw->b->o.charmap,(c = pgetc(q)))) /* do nothing */; if (c != NO_MORE_DATA) { prgetc(q); } binsb(pbw->cursor, bcpy(p, q)); pset(pbw->cursor, pbw->b->eof); pbw->cursor->xcol = piscol(pbw->cursor); prm(p); prm(q); } if (pbw) { return 0; } else { return -1; } }
static uint64_t hybi10_getlength(FILE *in) { uint64_t len; int lenlen; unsigned char ch; ch = pgetc(in); if (!(ch & 0x80)) { DPRINTF("mask bit not set"); die(1); } ch &= ~0x80; /* Two or eight bytes of input length? */ switch (ch) { case 126: lenlen = 2; break; case 127: lenlen = 8; break; default: /* Small packet, length encoded directly. */ return (ch); } len = 0; while (lenlen-- > 0) len = len << 8 | pgetc(in); return (len); }
static void hybi10_decode(FILE *in, int outfd) { FILE *out; unsigned char ch, masks[4]; char inb[4]; size_t inblen = 0; uint64_t i, framelen; out = fdopen(outfd, "w"); if (out == NULL) { perror("fdopen"); die(1); } for (;;) { /* Frame header. */ ch = pgetc(in); if (ch != 0x81) { DPRINTF("unsupported packet received: %#hhx", ch); die(1); } /* Payload length. */ framelen = hybi10_getlength(in); hybi10_getmasks(in, masks); for (i = 0; i < framelen; i++) { ch = pgetc(in) ^ masks[i % 4]; if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '+' || ch == '/' || ch == '=')) { DPRINTF("non-Base64 character received"); die(1); } /* Base64 character. */ inb[inblen++] = ch; if (inblen == sizeof inb) putb64(out, inb, &inblen); } /* Frame trailer. */ putb64(out, inb, &inblen); if (fflush(out) == -1) { perror("fflush"); die(1); } } }
int ucenter(BW *bw) { P *p = bw->cursor, *q; long endcol, begcol, x; int c; p_goto_eol(p); while (joe_isblank(bw->b->o.charmap, (c = prgetc(p)))) /* do nothing */; if (c == '\n') { pgetc(p); goto done; } if (c == NO_MORE_DATA) goto done; pgetc(p); endcol = piscol(p); p_goto_bol(p); while (joe_isblank(bw->b->o.charmap, (c = pgetc(p)))) /* do nothing */; if (c == '\n') { prgetc(p); goto done; } if (c == NO_MORE_DATA) goto done; prgetc(p); begcol = piscol(p); if (endcol - begcol > bw->o.rmargin + bw->o.lmargin) goto done; q = pdup(p, USTR "ucenter"); p_goto_bol(q); bdel(q, p); prm(q); for (x = 0; x != (bw->o.lmargin + bw->o.rmargin) / 2 - (endcol - begcol) / 2; ++x) binsc(p, ' '); done: if (!pnextl(p)) { binsc(p, '\n'); pgetc(p); return -1; } else return 0; }
static long parserr(B *b) { P *p = pdup(b->bof, USTR "parserr"); P *q = pdup(p, USTR "parserr"); long nerrs = 0; if (b->scratch && b->name[0] == '*') { /* "* Build Log *", "* Grep Log *" */ b->changed = 0; } freeall(); if (errbuf != b) { if (errp != NULL) { prm(errp); errp = NULL; } errbuf = b; } do { unsigned char *s; pset(q, p); p_goto_eol(p); s = brvs(q, (int) (p->byte - q->byte)); if (s) { nerrs += parseit(b->o.charmap, s, q->line, (b->parseone ? b->parseone : parseone)); vsrm(s); } } while (pgetc(p) != NO_MORE_DATA); prm(p); prm(q); return nerrs; }
void process_pending(struct pipe *p) { struct pipes_res *res = NULL; switch(p->pending_cmd.command) { case PIPES_READ: res = pread((struct pipes_read *)&p->pending_cmd, p); break; case PIPES_SEEK: res = pseek((struct pipes_seek *)&p->pending_cmd, p, p->taskid2); break; case PIPES_GETS: res = pgets((struct pipes_gets *)&p->pending_cmd, p); break; case PIPES_GETC: res = pgetc((struct pipes_getc *)&p->pending_cmd, p); break; } if(res != NULL) { p->pending = 0; res->thr_id = p->pending_cmd.thr_id; res->command = p->pending_cmd.command; send_msg(p->taskid2, p->pending_cmd.ret_port, res); } }
static long prefix(BW *bw, P *p,int up) { long len; P *q = pdup(p, USTR "prefix"); p_goto_bol(q); while (cpara(bw, brch(q))) pgetc(q); while (!pisbol(q)) { /* int c; */ if (!joe_isblank(p->b->o.charmap, ( /* c = */ prgetc(q)))) { /* if (up && (c == '*' || c == '-')) { if (!pisbol(q)) { c = prgetc(q); pgetc(q); if (c == ' ' || c == '\t') goto skip; } else goto skip; } pgetc(q); */ break; /* skip:; */ } } len = piscol(q); prm(q); return len; }
static void hybi10_getmasks(FILE *in, unsigned char masks[4]) { int i; for (i = 0; i < 4; i++) masks[i] = pgetc(in); }
static void hixie76_decode(FILE *in, int outfd) { FILE *out; unsigned char ch; char inb[4]; size_t inblen = 0; out = fdopen(outfd, "w"); if (out == NULL) { perror("fdopen"); die(1); } for (;;) { /* Frame header. */ ch = pgetc(in); if (ch != 0x00) { DPRINTF("unsupported packet received: %#hhx", ch); die(1); } while ((ch = pgetc(in)) != 0xff) { if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '+' || ch == '/' || ch == '=')) { DPRINTF("non-Base64 character received"); die(1); } /* Base64 character. */ inb[inblen++] = ch; if (inblen == sizeof inb) putb64(out, inb, &inblen); } /* Frame trailer. */ putb64(out, inb, &inblen); if (fflush(out) == -1) { perror("fflush"); die(1); } } }
int pgetc2() { int c; do { c = pgetc(); } while (c == PEOA); return c; }
static long nindent(BW *bw, P *p, int first) { P *q = pdup(p, USTR "nindent"); long col; int c; p_goto_bol(q); do { col = q->col; } while (cpara(bw, (c = pgetc(q)))); if (first && (c == '-' || c == '*')) { c = pgetc(q); if (c == ' ') { col = q->col; } } prm(q); return col; }
/* * megetv() gets n bits from the read stream and returns it. * */ int buf_getv(int n){ int p,rv; n--; p = n - read_position; while(p > 0){ if (read_position>23){/* If byte buffer contains almost entire word */ rv = (current_read_byte << p); /* Manipulate buffer */ current_read_byte = pgetc(); /* Change read bytes */ rv |= (current_read_byte >> (8 - p)); read_position = 7 - p; return(rv & lmask[n]); /* Can return pending residual val */ } current_read_byte = (current_read_byte << 8) | pgetc(); read_position += 8; /* else shift in new information */ p -= 8; }
/* * buf_getb() gets a bit from the read stream. */ int buf_getb() { if (read_position < 0){ current_read_byte = pgetc(); read_position=7; } if (current_read_byte & bit_set_mask[read_position--]){ return(1); } return(0); }
static int pisnpara(BW *bw, P *p) { P *q; int c; q = pdup(p, USTR "pisnpara"); p_goto_bol(q); while (cpara(bw, c = pgetc(q))) /* do nothing */; prm(q); if (c == '.' || c == '\r' || c == '\n') return 1; else return 0; }
int input(void) /* get next lexical input character */ { int c; extern char *lexprog; if (yysptr > yysbuf) c = (uschar)*--yysptr; else if (lexprog != NULL) { /* awk '...' */ if ((c = (uschar)*lexprog) != 0) lexprog++; } else /* awk -f ... */ c = pgetc(); if (c == '\n') lineno++; else if (c == EOF) c = 0; if (ep >= ebuf + sizeof ebuf) ep = ebuf; return *ep++ = c; }
STATIC void parseheredoc() { struct heredoc *here; union node *n; while (heredoclist) { here = heredoclist; heredoclist = here->next; if (needprompt) { putprompt(ps2val()); needprompt = 0; } readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, here->eofmark, here->striptabs); n = (union node *)stalloc(sizeof (struct narg)); n->narg.type = NARG; n->narg.next = NULL; n->narg.text = wordtext; n->narg.backquote = backquotelist; here->here->nhere.doc = n; } }
static void eat_flash_magic(void) { static const char flash_magic[] = "<policy-file-request/>"; size_t i; char ch; for (i = 0; i < sizeof flash_magic - 1; i++) { ch = pgetc(stdin); /* Not a Flash applet. Roll back. */ if (ch != flash_magic[i]) { ungetc(ch, stdin); while (i-- > 0) ungetc(flash_magic[i], stdin); return; } } printf("<cross-domain-policy>" "<allow-access-from domain=\"*\" to-ports=\"*\"/>" "</cross-domain-policy>\n"); exit(0); }
static int jump_to_error(BW *bw, ERROR *new_errptr) { W *w; if (new_errptr == NULL) { msgnw(bw->parent, joe_gettext(_("No more errors"))); return -1; } errptr = new_errptr; /* This moves the cursor to the beginning of line errptr->src, * and it also scrolls the window. */ setline(errbuf, errptr->src); /* Set errp to the beginning of line in errbuf. */ w = maint->curwin; do { if (w->watom->what == TYPETW) { BW *bw2 = w->object; if (bw2->b == errbuf) { if (errp != NULL) { pset(errp, bw2->cursor); } else { errp = pdup(bw2->cursor, USTR "errp"); } pgetc(errp); /* Move to next char to let the user type above. */ if (piseol(errp)) /* Undo the move for empty lines. */ p_goto_bol(errp); break; } } } while ((w = w->link.next) != maint->curwin); if (bw->b == errbuf) { uprevvw((BASE *)bw); bw = (BW*) maint->curwin->object; } return jump_to_file_line(bw,errptr->file,errptr->line,NULL /* errptr->msg */); }
swexp_list_node *parse_s_expr(parser *p, char opening_brace) { char c; swexp_list_node fakehead, *tail = &fakehead; fakehead.next = NULL; fakehead.content = NULL; fakehead.type = UNDEFINED; char closing_brace = brace_pair(opening_brace); while ((c = pgetc(p)) != EOF && !is_closing_brace(c)) { // if we encounter a comment in any state, strip it out IGNORE_COMMENTS() switch (p->state) { case SKIP_SPACE: if (is_space(c) || is_newline(c)) { // do nothing if it is space or newline } else if (is_opening_brace(c)) { // parse the parenthesized s expression into a list // and append it to the thing swexp_list_node *list = malloc(sizeof(swexp_list_node)); list->type = LIST; list->next = NULL; list->location = NULL; list->content = parse_s_expr(p, c); tail->next = list; tail = list; } else { // step back and start collecting the atom prewind(p, c); begin_atom(p); } break; case COLLECTING_ATOM: if (is_space(c) || is_newline(c)) { prewind(p, c); tail->next = close_atom(p); tail = tail->next; } else if (is_opening_brace(c)) { swexp_list_node *node = close_atom(p); node->next = parse_s_expr(p, c); tail->next = listof(node); tail = chain_tail(tail); } else { build_atom(p, c); } break; default: printf("unexpected state %d in parse_s_expr", p->state); exit(1); } } if (is_closing_brace(c) && c != closing_brace) { printf("mismatched braces in s expression\n"); exit(1); } if (p->state == COLLECTING_ATOM) { tail->next = close_atom(p); } if (c == EOF) { printf("unexpected EOF while parsing s expression\n"); exit(1); } p->state = SKIP_SPACE; return fakehead.next; }
static int preadbuffer(void) { char *q; int more; #ifdef USE_LINENOISE int something; #endif char savec; if (unlikely(parsefile->strpush)) { if ( parsefile->nleft == -1 && parsefile->strpush->ap && parsefile->nextc[-1] != ' ' && parsefile->nextc[-1] != '\t' ) { return PEOA; } popstring(); return pgetc(); } if (unlikely(parsefile->nleft == EOF_NLEFT || parsefile->buf == NULL)) return PEOF; flushall(); more = parsefile->lleft; if (more <= 0) { again: if ((more = preadfd()) <= 0) { parsefile->lleft = parsefile->nleft = EOF_NLEFT; return PEOF; } } q = parsefile->nextc; /* delete nul characters */ #ifdef USE_LINENOISE something = 0; #endif for (;;) { int c; more--; c = *q; if (!c) memmove(q, q + 1, more); else { q++; if (c == '\n') { parsefile->nleft = q - parsefile->nextc - 1; break; } #ifdef USE_LINENOISE switch (c) { default: something = 1; /* fall through */ case '\t': case ' ': break; } #endif } if (more <= 0) { parsefile->nleft = q - parsefile->nextc - 1; if (parsefile->nleft < 0) goto again; break; } } parsefile->lleft = more; savec = *q; *q = '\0'; #ifdef USE_LINENOISE if (parsefile->fd == 0 && iflag && something) { // linenoise doesn't expect the command terminator at the end of the history // entry. char command_terminator = q[-1]; q[-1] = '\0'; addtohistory(parsefile->nextc, strlen(parsefile->nextc)); // Restore the command terminator. q[-1] = command_terminator; } #endif if (vflag) { out2str(parsefile->nextc); #ifdef FLUSHERR flushout(out2); #endif } *q = savec; return (signed char)*parsefile->nextc++; }
static int peek(struct parser *p) { return pgetc(&p->source, 1); }
static int next(struct parser *p) { p->ch = pgetc(&p->source, 0); return p->ch; }
int uformat(BW *bw) { long indent; unsigned char *indents; B *buf; P *b; long curoff; int c; P *p, *q; p = pdup(bw->cursor, USTR "uformat"); p_goto_bol(p); /* Do nothing if we're not on a paragraph line */ if (pisnpara(bw, p)) { prm(p); return 0; } /* Move p to beginning of paragraph, bw->cursor to end of paragraph and * set curoff to original cursor offset within the paragraph */ pbop(bw, p); curoff = bw->cursor->byte - p->byte; pset(bw->cursor, p); peop(bw, bw->cursor); /* Ensure that paragraph ends on a beginning of a line */ if (!pisbol(bw->cursor)) binsc(bw->cursor, '\n'), pgetc(bw->cursor); /* Record indentation of second line of paragraph, of first line if there * is only one line */ q = pdup(p, USTR "uformat"); pnextl(q); if (q->line != bw->cursor->line) { P *r = pdup(q, USTR "uformat"); indent = nindent(bw, q, 0); pcol(r, indent); indents = brs(q, r->byte - q->byte); prm(r); } else { P *r = pdup(p, USTR "uformat"); int x, y; indent = nindent(bw, p, 1); /* allowing * and - here */ pcol(r, indent); indents = brs(p, r->byte - p->byte); prm(r); if (!bw->o.autoindent) { /* Don't indent second line of single-line paragraphs if autoindent is off */ int x = zlen(indents); while (x && (indents[x - 1] == ' ' || indents[x - 1] == '\t')) indents[--x] = 0; if (x) { indents[x++] = ' '; indents[x] = 0; } indent = txtwidth1(bw->o.charmap, bw->o.tab, indents, x); } for (x = 0; indents[x] && (indents[x] == ' ' || indents[x] == '\t'); ++x); y = zlen(indents); while (y && (indents[y - 1] == ' ' || indents[y - 1] == '\t')) --y; /* Don't duplicate if it looks like a bullet */ /* if (y && (indents[y - 1] == '*' || indents[y - 1] == '-') && (y == 1 || indents[y - 2] == ' ' || indents[y - 2] == '\t')) indents[y - 1] = ' '; */ /* Fix C comment */ if (indents[x] == '/' && indents[x + 1] == '*') indents[x] = ' '; } prm(q); /* But if the left margin is greater, we use that instead */ if (bw->o.lmargin > indent) { int x; for (x = 0; indents[x] == ' ' || indents[x] == '\t'; ++x); if (!indents[x]) { joe_free(indents); indent = bw->o.lmargin; indents = joe_malloc(indent+1); for (x = 0; x != indent; ++x) indents[x] = ' '; indents[x] = 0; } } /* Cut paragraph into new buffer */ /* New buffer needs to inherit UTF-8 and CR-LF options */ buf = bcpy(p, bw->cursor); buf->o.crlf = p->b->o.crlf; buf->o.charmap = p->b->o.charmap; bdel(p, bw->cursor); /* text is in buffer. insert it at cursor */ /* Do first line */ b = pdup(buf->bof, USTR "uformat"); while (!piseof(b)) { /* Set cursor position if we're at original offset */ if (b->byte == curoff) pset(bw->cursor, p); /* Get character from buffer */ c = pgetc(b); /* Stop if we found end of line */ if (c == '\n') { prgetc(b); break; } /* Stop if we found white-space followed by end of line */ if (joe_isblank(b->b->o.charmap, c) && piseolblank(b)) { prgetc(b); break; } /* Insert character, advance pointer */ binsc(p, c); pgetc(p); /* Do word wrap if we reach right margin */ if (piscol(p) > bw->o.rmargin && !joe_isblank(p->b->o.charmap,c)) { wrapword(bw, p, indent, bw->o.french, 1, indents); break; } } /* Do rest */ while (!piseof(b)) { c = brch(b); if (joe_isblank(b->b->o.charmap,c) || c == '\n') { int f = 0; P *d; int g; /* Set f if there are two spaces after . ? or ! instead of one */ /* (What is c was '\n'?) */ d=pdup(b, USTR "uformat"); g=prgetc(d); if (g=='.' || g=='?' || g=='!') { f = 1; /* pset(d,b); pgetc(d); if (c == '\n' || piseol(d) || joe_isspace(bw->b->o.charmap,brch(d))) { f = 1; } */ } prm(d); /* Skip past the whitespace. Skip over indentations */ loop: c = brch(b); if (c == '\n') { if (b->byte == curoff) pset(bw->cursor, p); pgetc(b); while (cpara(bw, (c=brch(b)))) { if (b->byte == curoff) pset(bw->cursor, p); pgetc(b); } } if (joe_isblank(b->b->o.charmap,c)) { if(b->byte == curoff) pset(bw->cursor, p); pgetc(b); goto loop; } /* Insert proper amount of whitespace */ if (!piseof(b)) { if (f && !bw->o.french) binsc(p, ' '), pgetc(p); binsc(p, ' '); pgetc(p); } } else { /* Insert characters of word and wrap if necessary */ if (b->byte == curoff) pset(bw->cursor, p); binsc(p, pgetc(b)); pgetc(p); if (piscol(p) > bw->o.rmargin) wrapword(bw, p, indent, bw->o.french, 1, indents); } } binsc(p, '\n'); prm(p); brm(buf); joe_free(indents); return 0; }
void wrapword(BW *bw, P *p, long int indent, int french, int no_over, unsigned char *indents) { P *q; P *r; P *s; int rmf = 0; int c; long to = p->byte; int my_indents = 0; /* autoindent when called by utype */ if (!indents) { /* Get indentation prefix from beginning of line */ s = pdup(p, USTR "wrapword"); p_goto_bol(s); pbop(bw, s); /* Record indentation of second line of paragraph, of first * line if there is only one line */ q = pdup(s, USTR "wrapword"); pnextl(q); if (q->line < p->line) { /* Second line */ P *r = pdup(q, USTR "wrapword"); indent = nindent(bw, q, 0); pcol(r, indent); indents = brs(q, r->byte - q->byte); prm(r); } else { /* First line */ P *r = pdup(s, USTR "uformat"); int x, y; indent = nindent(bw, s, 1); pcol(r, indent); indents = brs(s, r->byte - s->byte); prm(r); if (!bw->o.autoindent) { /* Don't indent second line of single-line paragraphs if autoindent is off */ int x = zlen(indents); while (x && (indents[x - 1] == ' ' || indents[x - 1] == '\t')) indents[--x] = 0; if (x) { indents[x++] = ' '; indents[x] = 0; } indent = txtwidth1(bw->o.charmap, bw->o.tab, indents, x); } for (x = 0; indents[x] && (indents[x] == ' ' || indents[x] == '\t'); ++x); y = zlen(indents); while (y && (indents[y - 1] == ' ' || indents[y - 1] == '\t')) --y; /* Don't duplicate bullet */ /* if (y && (indents[y - 1] == '*' || indents[y - 1] == '-') && (y == 1 || indents[y - 2] == ' ' || indents[y - 2] == '\t')) indents[y - 1] = ' '; */ /* Fix C comment */ if (indents[x] == '/' && indents[x + 1] == '*') indents[x] = ' '; } if (bw->o.lmargin > indent) { int x; for (x = 0; indents[x] == ' ' || indents[x] == '\t'; ++x); if (!indents[x]) { joe_free(indents); indent = bw->o.lmargin; indents = joe_malloc(indent+1); for (x = 0; x != indent; ++x) indents[x] = ' '; indents[x] = 0; } } my_indents = 1; prm(q); prm(s); } /* if(!indents) { int f = 0; P *r = pdup(p); p_goto_bol(r); q = pdup(r); while(cpara(c = brc(q))) { if(!joe_isblank(c)) f = 1; pgetc(q); } if(f) { indents = brs(r, q->byte-r->byte); rmf = 1; if(indents[0] == '/' && indents[1] == '*') indents[0] = ' '; } prm(r); prm(q); } */ /* Get to beginning of word */ while (!pisbol(p) && piscol(p) > indent && !joe_isblank(p->b->o.charmap, prgetc(p))) /* do nothing */; /* If we found the beginning of a word... */ if (!pisbol(p) && piscol(p) > indent) { /* Move q to two (or one if 'french' is set) spaces after end of previous word */ q = pdup(p, USTR "wrapword"); while (!pisbol(q)) if (!joe_isblank(p->b->o.charmap, (c = prgetc(q)))) { pgetc(q); if ((c == '.' || c == '?' || c == '!') && q->byte != p->byte && !french) pgetc(q); break; } pgetc(p); /* Delete space between start of word and end of previous word */ to -= p->byte - q->byte; bdel(q, p); prm(q); if (bw->o.flowed) { binsc(p, ' '); pgetc(p); ++to; } /* Move word to beginning of next line */ binsc(p, '\n'); /* When overtype is on, do not insert lines */ if (!no_over && p->b->o.overtype){ /* delete the next line break which is unnecessary */ r = pdup(p, USTR "wrapword"); /* p_goto_eol(r); */ pgetc(r); p_goto_eol(r); s = pdup(r, USTR "wrapword"); pgetc(r); bdel(s,r); binsc(r, ' '); /* Now we got to take care that all subsequent lines are not longer than the right margin */ /* Move cursor to right margin */ pfwrd(r, r->b->o.rmargin - r->col); /* Make a copy of the cursor and move the copied cursor to the end of the line */ prm(s); s = pdup(r, USTR "wrapword"); p_goto_eol(s); /* If s is located behind r then the line goes beyond the right margin and we need to call wordwrap() for that line. */ /* if (r->byte < s->byte){ wrapword(bw, r, indent, french, 1, indents); } */ prm(r); prm(s); } ++to; if (p->b->o.crlf) ++to; pgetc(p); /* Indent to left margin */ if (indents) { binss(p, indents); to += zlen(indents); } else while (indent--) { binsc(p, ' '); ++to; } if (rmf) joe_free(indents); } /* Move cursor back to original position */ pfwrd(p, to - p->byte); if (my_indents) joe_free(indents); }
swexp_list_node *parse_block(parser *p) { // parses a block of lines with the same indentation into a chain // (not a list) char c; swexp_list_node fakehead, *tail; fakehead.next = NULL; fakehead.content = NULL; fakehead.type = UNDEFINED; tail = &fakehead; // get initial indentation by consuming characters until we find some unsigned int current_indentation; for (current_indentation = p->indentation; is_space(pgetc(p)); current_indentation++) { } prewind(p, '\0'); while ((c = pgetc(p)) != EOF) { // if we encounter a comment in any state, strip it out IGNORE_COMMENTS() switch (p->state) { case COUNTING_INDENTATION: if (is_space(c)) { p->indentation++; } else if (is_newline(c)) { p->indentation = 0; } else { // this is a start of an atom. // parse as appropriate based on indent prewind(p, c); if (p->indentation > current_indentation) { if (tail->type == ATOM) { // make the tail a list before appending swexp_list_node *tailcont = malloc(sizeof(swexp_list_node)); tailcont->type = ATOM; tailcont->next = NULL; tailcont->content = tail->content; tailcont->location = NULL; tail->type = LIST; tail->content = tailcont; if (tail->location != NULL) { free(tail->location); tail->location = NULL; } } // append it to the list that is the last // element list_tail(tail)->next = parse_block(p); } else if (p->indentation == current_indentation) { tail->next = parse_line(p); p->state = COUNTING_INDENTATION; tail = tail->next; } else { goto clean_and_return; } } break; default: printf("unexpected state in parse_line\n"); exit(1); } } clean_and_return: return fakehead.next; }
STATIC int xxreadtoken(void) { int c; if (tokpushback) { tokpushback = 0; return lasttoken; } if (needprompt) { setprompt(2); needprompt = 0; } startlinno = plinno; for (;;) { /* until token or start of word found */ c = pgetc_macro(); if (c == ' ' || c == '\t') continue; /* quick check for white space first */ switch (c) { case ' ': case '\t': continue; case '#': while ((c = pgetc()) != '\n' && c != PEOF); pungetc(); continue; case '\\': if (pgetc() == '\n') { startlinno = ++plinno; if (doprompt) setprompt(2); else setprompt(0); continue; } pungetc(); goto breakloop; case '\n': plinno++; needprompt = doprompt; RETURN(TNL); case PEOF: RETURN(TEOF); case '&': if (pgetc() == '&') RETURN(TAND); pungetc(); RETURN(TBACKGND); case '|': if (pgetc() == '|') RETURN(TOR); pungetc(); RETURN(TPIPE); case ';': if (pgetc() == ';') RETURN(TENDCASE); pungetc(); RETURN(TSEMI); case '(': RETURN(TLP); case ')': RETURN(TRP); default: goto breakloop; } } breakloop: return readtoken1(c, BASESYNTAX, (char *)NULL, 0); #undef RETURN }
STATIC int readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs) { int c = firstc; char *out; int len; char line[EOFMARKLEN + 1]; struct nodelist *bqlist; int quotef; int dblquote; int varnest; /* levels of variables expansion */ int arinest; /* levels of arithmetic expansion */ int parenlevel; /* levels of parens in arithmetic */ int oldstyle; char const *prevsyntax; /* syntax before arithmetic */ int synentry; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &out; (void) "ef; (void) &dblquote; (void) &varnest; (void) &arinest; (void) &parenlevel; (void) &oldstyle; (void) &prevsyntax; (void) &syntax; (void) &synentry; #endif startlinno = plinno; dblquote = 0; if (syntax == DQSYNTAX) dblquote = 1; quotef = 0; bqlist = NULL; varnest = 0; arinest = 0; parenlevel = 0; STARTSTACKSTR(out); loop: { /* for each line, until end of word */ CHECKEND(); /* set c to PEOF if at end of here document */ for (;;) { /* until end of line or end of word */ CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ synentry = syntax[c]; switch(synentry) { case CNL: /* '\n' */ if (syntax == BASESYNTAX) goto endword; /* exit outer loop */ USTPUTC(c, out); plinno++; if (doprompt) setprompt(2); else setprompt(0); c = pgetc(); goto loop; /* continue outer loop */ case CWORD: USTPUTC(c, out); break; case CCTL: if (eofmark == NULL || dblquote) USTPUTC(CTLESC, out); USTPUTC(c, out); break; case CBACK: /* backslash */ c = pgetc(); if (c == PEOF) { USTPUTC('\\', out); pungetc(); } else if (c == '\n') { if (doprompt) setprompt(2); else setprompt(0); } else { if (dblquote && c != '\\' && c != '`' && c != '$' && (c != '"' || eofmark != NULL)) USTPUTC('\\', out); if (SQSYNTAX[c] == CCTL) USTPUTC(CTLESC, out); else if (eofmark == NULL) USTPUTC(CTLQUOTEMARK, out); USTPUTC(c, out); quotef++; } break; case CSQUOTE: if (eofmark == NULL) USTPUTC(CTLQUOTEMARK, out); syntax = SQSYNTAX; break; case CDQUOTE: if (eofmark == NULL) USTPUTC(CTLQUOTEMARK, out); syntax = DQSYNTAX; dblquote = 1; break; case CENDQUOTE: if (eofmark != NULL && arinest == 0 && varnest == 0) { USTPUTC(c, out); } else { if (arinest) { syntax = ARISYNTAX; dblquote = 0; } else if (eofmark == NULL) { syntax = BASESYNTAX; dblquote = 0; } quotef++; } break; case CVAR: /* '$' */ PARSESUB(); /* parse substitution */ break; case CENDVAR: /* '}' */ if (varnest > 0) { varnest--; USTPUTC(CTLENDVAR, out); } else { USTPUTC(c, out); } break; case CLP: /* '(' in arithmetic */ parenlevel++; USTPUTC(c, out); break; case CRP: /* ')' in arithmetic */ if (parenlevel > 0) { USTPUTC(c, out); --parenlevel; } else { if (pgetc() == ')') { if (--arinest == 0) { USTPUTC(CTLENDARI, out); syntax = prevsyntax; if (syntax == DQSYNTAX) dblquote = 1; else dblquote = 0; } else USTPUTC(')', out); } else { /* * unbalanced parens * (don't 2nd guess - no error) */ pungetc(); USTPUTC(')', out); } } break; case CBQUOTE: /* '`' */ PARSEBACKQOLD(); break; case CEOF: goto endword; /* exit outer loop */ default: if (varnest == 0) goto endword; /* exit outer loop */ USTPUTC(c, out); } c = pgetc_macro(); } } endword: if (syntax == ARISYNTAX) synerror("Missing '))'"); if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL) synerror("Unterminated quoted string"); if (varnest != 0) { startlinno = plinno; synerror("Missing '}'"); } USTPUTC('\0', out); len = out - stackblock(); out = stackblock(); if (eofmark == NULL) { if ((c == '>' || c == '<') && quotef == 0 && len <= 2 && (*out == '\0' || is_digit(*out))) { PARSEREDIR(); return lasttoken = TREDIR; } else { pungetc(); } } quoteflag = quotef; backquotelist = bqlist; grabstackblock(len); wordtext = out; return lasttoken = TWORD; /* end of readtoken routine */ /* * Check to see whether we are at the end of the here document. When this * is called, c is set to the first character of the next input line. If * we are at the end of the here document, this routine sets the c to PEOF. */ checkend: { if (eofmark) { if (striptabs) { while (c == '\t') c = pgetc(); } if (c == *eofmark) { if (pfgets(line, sizeof line) != NULL) { char *p, *q; p = line; for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); if (*p == '\n' && *q == '\0') { c = PEOF; plinno++; needprompt = doprompt; } else { pushstring(line, strlen(line), NULL); } } } } goto checkend_return; } /* * Parse a redirection operator. The variable "out" points to a string * specifying the fd to be redirected. The variable "c" contains the * first character of the redirection operator. */ parseredir: { char fd = *out; union node *np; np = (union node *)stalloc(sizeof (struct nfile)); if (c == '>') { np->nfile.fd = 1; c = pgetc(); if (c == '>') np->type = NAPPEND; else if (c == '&') np->type = NTOFD; else if (c == '|') np->type = NCLOBBER; else { np->type = NTO; pungetc(); } } else { /* c == '<' */ np->nfile.fd = 0; c = pgetc(); if (c == '<') { if (sizeof (struct nfile) != sizeof (struct nhere)) { np = (union node *)stalloc(sizeof (struct nhere)); np->nfile.fd = 0; } np->type = NHERE; heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc)); heredoc->here = np; if ((c = pgetc()) == '-') { heredoc->striptabs = 1; } else { heredoc->striptabs = 0; pungetc(); } } else if (c == '&') np->type = NFROMFD; else if (c == '>') np->type = NFROMTO; else { np->type = NFROM; pungetc(); } } if (fd != '\0') np->nfile.fd = digit_val(fd); redirnode = np; goto parseredir_return; } /* * Parse a substitution. At this point, we have read the dollar sign * and nothing else. */ parsesub: { int subtype; int typeloc; int flags; char *p; #ifndef GDB_HACK static const char types[] = "}-+?="; #endif int bracketed_name = 0; /* used to handle ${[0-9]*} variables */ c = pgetc(); if (c != '(' && c != '{' && !is_name(c) && !is_special(c)) { USTPUTC('$', out); pungetc(); } else if (c == '(') { /* $(command) or $((arith)) */ if (pgetc() == '(') { PARSEARITH(); } else { pungetc(); PARSEBACKQNEW(); } } else { USTPUTC(CTLVAR, out); typeloc = out - stackblock(); USTPUTC(VSNORMAL, out); subtype = VSNORMAL; if (c == '{') { bracketed_name = 1; c = pgetc(); if (c == '#') { if ((c = pgetc()) == '}') c = '#'; else subtype = VSLENGTH; } else subtype = 0; } if (is_name(c)) { do { STPUTC(c, out); c = pgetc(); } while (is_in_name(c)); } else if (is_digit(c)) { if (bracketed_name) { do { STPUTC(c, out); c = pgetc(); } while (is_digit(c)); } else { STPUTC(c, out); c = pgetc(); } } else { if (! is_special(c)) badsub: synerror("Bad substitution"); USTPUTC(c, out); c = pgetc(); } STPUTC('=', out); flags = 0; if (subtype == 0) { switch (c) { case ':': flags = VSNUL; c = pgetc(); /*FALLTHROUGH*/ default: p = strchr(types, c); if (p == NULL) goto badsub; subtype = p - types + VSNORMAL; break; case '%': case '#': { int cc = c; subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT; c = pgetc(); if (c == cc) subtype++; else pungetc(); break; } } } else { pungetc(); } if (subtype != VSLENGTH && (dblquote || arinest)) flags |= VSQUOTE; *(stackblock() + typeloc) = subtype | flags; if (subtype != VSNORMAL) varnest++; } goto parsesub_return; } /* * Called to parse command substitutions. Newstyle is set if the command * is enclosed inside $(...); nlpp is a pointer to the head of the linked * list of commands (passed by reference), and savelen is the number of * characters on the top of the stack which must be preserved. */ parsebackq: { struct nodelist **nlpp; int savepbq; union node *n; char *volatile str; struct jmploc jmploc; struct jmploc *volatile savehandler; int savelen; int saveprompt; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &saveprompt; #endif savepbq = parsebackquote; if (setjmp(jmploc.loc)) { if (str) ckfree(str); parsebackquote = 0; handler = savehandler; longjmp(handler->loc, 1); } INTOFF; str = NULL; savelen = out - stackblock(); if (savelen > 0) { str = ckmalloc(savelen); memcpy(str, stackblock(), savelen); } savehandler = handler; handler = &jmploc; INTON; if (oldstyle) { /* We must read until the closing backquote, giving special treatment to some slashes, and then push the string and reread it as input, interpreting it normally. */ char *out; int c; int savelen; char *str; STARTSTACKSTR(out); for (;;) { if (needprompt) { setprompt(2); needprompt = 0; } switch (c = pgetc()) { case '`': goto done; case '\\': if ((c = pgetc()) == '\n') { plinno++; if (doprompt) setprompt(2); else setprompt(0); /* * If eating a newline, avoid putting * the newline into the new character * stream (via the STPUTC after the * switch). */ continue; } if (c != '\\' && c != '`' && c != '$' && (!dblquote || c != '"')) STPUTC('\\', out); break; case '\n': plinno++; needprompt = doprompt; break; case PEOF: startlinno = plinno; synerror("EOF in backquote substitution"); break; default: break; } STPUTC(c, out); } done: STPUTC('\0', out); savelen = out - stackblock(); if (savelen > 0) { str = ckmalloc(savelen); memcpy(str, stackblock(), savelen); setinputstring(str, 1); } } nlpp = &bqlist; while (*nlpp) nlpp = &(*nlpp)->next; *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); (*nlpp)->next = NULL; parsebackquote = oldstyle; if (oldstyle) { saveprompt = doprompt; doprompt = 0; } n = list(0); if (oldstyle) doprompt = saveprompt; else { if (readtoken() != TRP) synexpect(TRP); } (*nlpp)->n = n; if (oldstyle) { /* * Start reading from old file again, ignoring any pushed back * tokens left from the backquote parsing */ popfile(); tokpushback = 0; } while (stackblocksize() <= savelen) growstackblock(); STARTSTACKSTR(out); if (str) { memcpy(out, str, savelen); STADJUST(savelen, out); INTOFF; ckfree(str); str = NULL; INTON; } parsebackquote = savepbq; handler = savehandler; if (arinest || dblquote) USTPUTC(CTLBACKQ | CTLQUOTE, out); else USTPUTC(CTLBACKQ, out); if (oldstyle) goto parsebackq_oldreturn; else goto parsebackq_newreturn; } /* * Parse an arithmetic expansion (indicate start of one and set state) */ parsearith: { if (++arinest == 1) { prevsyntax = syntax; syntax = ARISYNTAX; USTPUTC(CTLARI, out); if (dblquote) USTPUTC('"',out); else USTPUTC(' ',out); } else { /* * we collapse embedded arithmetic expansion to * parenthesis, which should be equivalent */ USTPUTC('(', out); } goto parsearith_return; } } /* end of readtoken */
void process_pipes_cmd(struct pipes_cmd *pcmd, int task) { struct pipes_res *res= NULL; struct pipe *p = NULL; // check for open if(pcmd->command == PIPES_OPENSHARED) { // create a new shared pipe struct pipe *p = (struct pipe*)malloc(sizeof(struct pipe)); p->id = get_new_pipeid(); p->type = PIPES_SHAREDPIPE; p->taskid = ((struct pipes_openshared*)pcmd)->task1; p->taskid2 = ((struct pipes_openshared*)pcmd)->task2; p->pf = NULL; p->creating_task = task; p->pending = 0; p->task1_closed = 0; p->task2_closed = 0; p->buffer = (struct pipe_buffer*)malloc(sizeof(struct pipe_buffer)); p->buffer->rcursor = p->buffer->wcursor = p->buffer->size = 0; init(&p->buffer->blocks); avl_insert(&pipes, p, p->id); res = build_response_msg(PIPESERR_OK); ((struct pipes_open_res*)res)->pipeid = p->id; } else if(pcmd->command == PIPES_OPENFILE) { // create a new file pipe struct pipe *p = (struct pipe*)malloc(sizeof(struct pipe)); char *filepath = get_string(((struct pipes_openfile*)pcmd)->path_smo); p->id = get_new_pipeid(); p->type = PIPES_FILEPIPE; p->taskid = ((struct pipes_openshared*)pcmd)->task1; p->taskid2 = -1; p->pf = fopen(filepath, (char*)((struct pipes_openfile*)pcmd)->open_mode); p->creating_task = task; p->buffer = NULL; p->pending = 0; if(p->pf != NULL) { avl_insert(&pipes, p, p->id); res = build_response_msg(PIPESERR_OK); ((struct pipes_open_res*)res)->pipeid = p->id; } else { res = build_response_msg(PIPESERR_FSERROR); free(p); } free(filepath); } else { p = (struct pipe*)avl_getvalue(pipes, ((struct pipes_close*)pcmd)->pipeid); if(p != NULL) { /* Check permissions */ switch(pcmd->command) { case PIPES_CLOSE: // a shared pipe must be closed on both ends or by the creating task if(p->type == PIPES_SHAREDPIPE) { if(task != p->taskid && task != p->taskid2 && task != p->creating_task) { res = build_response_msg(PIPESERR_ERR); } else if((task == p->taskid && p->task1_closed) || (task == p->taskid2 && p->task2_closed)) { res = build_response_msg(PIPESERR_PIPECLOSED); } } else if(p->type == PIPES_FILEPIPE && task != p->taskid) { res = build_response_msg(PIPESERR_ERR); } break; case PIPES_SEEK: case PIPES_TELL: break; case PIPES_WRITE: case PIPES_PUTS: case PIPES_PUTC: if(p->type == PIPES_SHAREDPIPE && task != p->taskid) { res = build_response_msg(PIPESERR_ERR); } break; case PIPES_READ: case PIPES_GETS: case PIPES_GETC: if(p->type == PIPES_SHAREDPIPE && task != p->taskid2) { res = build_response_msg(PIPESERR_ERR); } break; default: res = build_response_msg(PIPESERR_ERR); } if(res != NULL) { res->thr_id = pcmd->thr_id; res->command = pcmd->command; send_msg(task, pcmd->ret_port, res); return; } /* Process pipe command */ switch(pcmd->command) { case PIPES_CLOSE: res = pclose((struct pipes_close *)pcmd, p, task); if(res->ret == PIPESERR_OK) p = NULL; break; case PIPES_READ: res = pread((struct pipes_read *)pcmd, p); break; case PIPES_WRITE: res = pwrite((struct pipes_write *)pcmd, p); break; case PIPES_SEEK: res = pseek((struct pipes_seek *)pcmd, p, task); break; case PIPES_TELL: res = ptell((struct pipes_tell *)pcmd, p, task); break; case PIPES_PUTS: res = pputs((struct pipes_puts *)pcmd, p); break; case PIPES_PUTC: res = pputc((struct pipes_putc *)pcmd, p); break; case PIPES_GETS: res = pgets((struct pipes_gets *)pcmd, p); break; case PIPES_GETC: res = pgetc((struct pipes_getc *)pcmd, p); break; default: res = build_response_msg(PIPESERR_ERR); } } else { res = build_response_msg(PIPESERR_PIPECLOSED); } } if(p == NULL || (p != NULL && !(p->pending && (pcmd->command == PIPES_READ || (pcmd->command == PIPES_SEEK && task == p->taskid2) || pcmd->command == PIPES_GETS || pcmd->command == PIPES_GETC)))) { if(res == NULL) { res = build_response_msg(PIPESERR_ERR); } res->thr_id = pcmd->thr_id; res->command = pcmd->command; send_msg(task, pcmd->ret_port, res); if(res != NULL) free(res); } else { // check pending read if(p != NULL && p->pending && (pcmd->command == PIPES_WRITE || (pcmd->command == PIPES_SEEK && task == p->taskid2) || pcmd->command == PIPES_READ || pcmd->command == PIPES_PUTS || pcmd->command == PIPES_PUTC)) { // process the pending message process_pending(p); } send_msg(task, pcmd->ret_port, res); if(res != NULL) free(res); } }
swexp_list_node *parse_line(parser *p) { // parses a line of text, starting at a non-whitespace char char c; // build a list of expressions started by this // list head on the stack. swexp_list_node head, *tail; head.next = NULL; head.content = NULL; head.type = UNDEFINED; tail = &head; p->state = SKIP_SPACE; while ((c = pgetc(p)) != EOF && !is_newline(c) && !is_closing_brace(c)) { // if we encounter a comment in any state, strip it out IGNORE_COMMENTS() switch (p->state) { case COLLECTING_ATOM: if (is_space(c)) { // end atom tail->next = close_atom(p); tail = tail->next; prewind(p, c); } else if (is_opening_brace(c)) { swexp_list_node *bracehead = close_atom(p); swexp_list_node *bracecontent = parse_s_expr(p, c); bracehead->next = bracecontent; tail->next = listof(bracehead); tail = chain_tail(tail); } else { // continue to build item build_atom(p, c); } break; case SKIP_SPACE: if (is_opening_brace(c)) { swexp_list_node *brace = parse_s_expr(p, c); tail->next = brace; tail = chain_tail(tail); } else if (!is_space(c)) { begin_atom(p); prewind(p, c); } break; default: printf("unexpected state %d in parse_line\n", p->state); exit(1); } } if (is_newline(c)) { p->indentation = 0; } if (is_closing_brace(c)) { printf("encountered unmatched closing brace\n"); exit(1); } // close ongoing capture if (p->state == COLLECTING_ATOM) { tail->next = close_atom(p); } // if the number of collected atoms is more than one, // make it a list and return it if (chain_len(head.next) > 1) { swexp_list_node *listhead = malloc(sizeof(swexp_list_node)); listhead->type = LIST; listhead->next = NULL; listhead->content = head.next; listhead->location = NULL; return listhead; } else { return head.next; } }