⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heredoc.c

📁 早期freebsd实现
💻 C
字号:
/* heredoc.c: heredoc slurping is done here */#include "rc.h"struct Hq {	Node *doc;	char *name;	Hq *n;	bool quoted;} *hq;static bool dead = FALSE;/* * read in a heredocument. A clever trick: skip over any partially matched end-of-file * marker storing only the number of characters matched. If the whole marker is matched, * return from readheredoc(). If only part of the marker is matched, copy that part into * the heredocument. * * BUG: if the eof string contains a newline, the state can get confused, and the * heredoc may continue past where it should.  on the other hand, /bin/sh seems to * never get out of its readheredoc() when the heredoc string contains a newline */static char *readheredoc(char *eof) {	int c;	char *t, *buf, *bufend;	unsigned char *s;	size_t bufsize;	t = buf = nalloc(bufsize = 512);	bufend = &buf[bufsize];	dead = FALSE;#define	RESIZE(extra) { \		char *nbuf; \		bufsize = bufsize * 2 + extra; \		nbuf = nalloc(bufsize); \		memcpy(nbuf, buf, (size_t) (t - buf)); \		t = nbuf + (t - buf); \		buf = nbuf; \		bufend = &buf[bufsize]; \	}	for (;;) {		print_prompt2();		for (s = (unsigned char *) eof; (c = gchar()) == *s; s++)			;		if (*s == '\0' && (c == '\n' || c == EOF)) {			*t++ = '\0';			return buf;		}		if (s != (unsigned char *) eof) {			size_t len = s - (unsigned char *) eof;			if (t + len >= bufend)				RESIZE(len);			memcpy(t, eof, len);			t += len;		}		for (;; c = gchar()) {			if (c == EOF) {				yyerror("heredoc incomplete");				dead = TRUE;				return NULL;			}			if (t + 1 >= bufend)				RESIZE(0);			*t++ = c;			if (c == '\n')				break;		}	}}/* parseheredoc -- turn a heredoc with variable references into a node chain */static Node *parseheredoc(char *s) {	int c = *s;	Node *result = NULL;	while (TRUE) {		Node *node;		switch (c) {		default: {			char *begin = s;			while ((c = *s++) != '\0' && c != '$')				;			*--s = '\0';			node = mk(nQword, begin, NULL);			break;		}		case '$': {			char *begin = ++s, *var;			c = *s++;			if (c == '$') {				node = mk(nQword, "$", NULL);				c = *s;			} else {				size_t len = 0;				do					len++;				while (!dnw[c = *(unsigned char *) s++]);				if (c == '^')					c = *s;				else					s--;				var = nalloc(len + 1);				var[len] = '\0';				memcpy(var, begin, len);				node = mk(nFlat, mk(nWord, var, NULL));			}			break;		}		case '\0':			return result;		}		result = (result == NULL) ? node : mk(nConcat, result, node);	}}/* read in heredocs when yyparse hits a newline. called from yyparse */extern int heredoc(int end) {	Hq *here;	if ((here = hq) != NULL) {		hq = NULL;		if (end) {			yyerror("heredoc incomplete");			return FALSE;		}		do {			Node *n = here->doc;			char *s = readheredoc(here->name);			if (dead)				return FALSE;			n->u[2].p = here->quoted ? mk(nQword, s, NULL) : parseheredoc(s);			n->u[0].i = rHerestring;		} while ((here = here->n) != NULL);	}	return TRUE;}/* queue pending heredocs into a queue. called from yyparse */extern int qdoc(Node *name, Node *n) {	Hq *new, **prev;	if (name->type != nWord && name->type != nQword) {		yyerror("eof-marker not a single literal word");		flushu();		return FALSE;	}	for (prev = &hq; (new = *prev) != NULL; prev = &new->n)		;	*prev = new = nnew(Hq);	new->name = name->u[0].s;	new->quoted = (name->type == nQword);	new->doc = n;	new->n = NULL;	return TRUE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -