예제 #1
0
파일: utag.c 프로젝트: lpereira/joe-editor
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;
	}
}
예제 #2
0
파일: kumina.c 프로젝트: Mirey/websockify
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);
}
예제 #3
0
파일: kumina.c 프로젝트: Mirey/websockify
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);
		}
	}
}
예제 #4
0
파일: uformat.c 프로젝트: Distrotech/joe
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;
}
예제 #5
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;
}
예제 #6
0
파일: commands.c 프로젝트: ahamid/sartoris
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);
	}
}
예제 #7
0
파일: uformat.c 프로젝트: Distrotech/joe
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;
}
예제 #8
0
파일: kumina.c 프로젝트: Mirey/websockify
static void
hybi10_getmasks(FILE *in, unsigned char masks[4])
{
	int i;

	for (i = 0; i < 4; i++)
		masks[i] = pgetc(in);
}
예제 #9
0
파일: kumina.c 프로젝트: Mirey/websockify
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);
		}
	}
}
예제 #10
0
파일: input.c 프로젝트: saltstar/smartnix
int
pgetc2()
{
	int c;
	do {
		c = pgetc();
	} while (c == PEOA);
	return c;
}
예제 #11
0
파일: uformat.c 프로젝트: Distrotech/joe
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;
}
예제 #12
0
/*
 * 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;
    }
예제 #13
0
/*
 * 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);
}
예제 #14
0
파일: uformat.c 프로젝트: Distrotech/joe
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;
}
예제 #15
0
파일: lex.c 프로젝트: djbclark/bb10qnx
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;
}
예제 #16
0
파일: parser.c 프로젝트: hakan-akan/cor
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;
      }
}
예제 #17
0
파일: kumina.c 프로젝트: Mirey/websockify
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);
}
예제 #18
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 */);
}
예제 #19
0
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;
}
예제 #20
0
파일: input.c 프로젝트: saltstar/smartnix
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++;
}
예제 #21
0
파일: parser.c 프로젝트: HarryR/sanos
static int peek(struct parser *p) {
  return pgetc(&p->source, 1);
}
예제 #22
0
파일: parser.c 프로젝트: HarryR/sanos
static int next(struct parser *p) {
  p->ch = pgetc(&p->source, 0);
  return p->ch;
}
예제 #23
0
파일: uformat.c 프로젝트: Distrotech/joe
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;
}
예제 #24
0
파일: uformat.c 프로젝트: Distrotech/joe
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);
}
예제 #25
0
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;
}
예제 #26
0
파일: parser.c 프로젝트: 7shi/minix-tools
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
}
예제 #27
0
파일: parser.c 프로젝트: 7shi/minix-tools
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) &quotef;
	(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 */
예제 #28
0
파일: pipes_srv.c 프로젝트: ahamid/sartoris
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);
    }
}
예제 #29
0
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;
  }
}