Esempio n. 1
0
/* Simplified tokenizer: comments and preproc directives removed,
   identifiers are a token, others are single char tokens. */
static struct token *tokenize(const void *ctx, const char *code)
{
	unsigned int i, len, tok_start = -1;
	bool start_of_line = true;
	struct token *toks = tal_arr(ctx, struct token, 0);

	for (i = 0; code[i]; i += len) {
		if (code[i] == '#' && start_of_line) {
			/* Preprocessor line. */
			len = strcspn(code+i, "\n");
		} else if (code[i] == '/' && code[i+1] == '/') {
			/* One line comment. */
			len = strcspn(code+i, "\n");
			if (tok_start != -1U) {
				add_token(&toks, code+tok_start, i - tok_start);
				tok_start = -1U;
			}
		} else if (code[i] == '/' && code[i+1] == '*') {
			/* Multi-line comment. */
			const char *end = strstr(code+i+2, "*/");
			len = (end + 2) - (code + i);
			if (!end)
				len = strlen(code + i);
			if (tok_start != -1U) {
				add_token(&toks, code+tok_start, i - tok_start);
				tok_start = -1U;
			}
		} else if (cisalnum(code[i]) || code[i] == '_') {
			/* Identifier or part thereof */
			if (tok_start == -1U)
				tok_start = i;
			len = 1;
		} else if (!cisspace(code[i])) {
			/* Punctuation: treat as single char token. */
			if (tok_start != -1U) {
				add_token(&toks, code+tok_start, i - tok_start);
				tok_start = -1U;
			}
			add_token(&toks, code+i, 1);
			len = 1;
		} else {
			/* Whitespace. */
			if (tok_start != -1U) {
				add_token(&toks, code+tok_start, i - tok_start);
				tok_start = -1U;
			}
			len = 1;
		}
		if (code[i] == '\n')
			start_of_line = true;
		else if (!cisspace(code[i]))
			start_of_line = false;
	}

	/* Add terminating NULL. */
	tal_resizez(&toks, tal_count(toks) + 1);
	return toks;
}
Esempio n. 2
0
static bool looks_internal(char **lines, char **why)
{
	unsigned int i;
	bool last_ended = true; /* Did last line finish a statement? */

	for (i = 0; lines[i]; i++) {
		/* Skip leading whitespace. */
		const char *line = lines[i] + strspn(lines[i], " \t");
		unsigned len = strspn(line, IDENT_CHARS);

		if (!line[0] || cisspace(line[0]) || strstarts(line, "//")
		    || strstarts(line, "#line"))
			continue;

		assert(line[strlen(line)-1] != '\n');

		/* The winners. */
		if (strstarts(line, "if") && len == 2) {
			*why = cast_const(char *, "starts with if");
			return true;
		}
		if (strstarts(line, "for") && len == 3) {
			*why = cast_const(char *, "starts with for");
			return true;
		}
Esempio n. 3
0
void
trig_parse_ci(const char *file, trig_parse_cicb *interest,
              trig_parse_cicb *activate, void *user)
{
	FILE *f;
	char linebuf[MAXTRIGDIRECTIVE], *cmd, *spc, *eol;
	int l;

	f = fopen(file, "r");
	if (!f) {
		if (errno == ENOENT)
			return; /* No file is just like an empty one. */
		ohshite(_("unable to open triggers ci file `%.250s'"), file);
	}
	push_cleanup(cu_closestream, ~0, NULL, 0, 1, f);

	while ((l = fgets_checked(linebuf, sizeof(linebuf), f, file)) >= 0) {
		for (cmd = linebuf; cisspace(*cmd); cmd++);
		if (*cmd == '#')
			continue;
		for (eol = linebuf + l; eol > cmd && cisspace(eol[-1]); eol--);
		if (eol == cmd)
			continue;
		*eol = '\0';

		for (spc = cmd; *spc && !cisspace(*spc); spc++);
		if (!*spc)
			ohshit(_("triggers ci file contains unknown directive syntax"));
		*spc++ = '\0';
		while (cisspace(*spc))
			spc++;
		if (!strcmp(cmd, "interest")) {
			parse_ci_call(file, cmd, interest, spc, user, trig_await);
		} else if (!strcmp(cmd, "interest-noawait")) {
			parse_ci_call(file, cmd, interest, spc, user, trig_noawait);
		} else if (!strcmp(cmd, "activate")) {
			parse_ci_call(file, cmd, activate, spc, user, trig_await);
		} else if (!strcmp(cmd, "activate-noawait")) {
			parse_ci_call(file, cmd, activate, spc, user, trig_noawait);
		} else {
			ohshit(_("triggers ci file contains unknown directive `%.250s'"),
			       cmd);
		}
	}
	pop_cleanup(ehflag_normaltidy); /* fclose() */
}
Esempio n. 4
0
/* We only handle simple function definitions here. */
static char *add_func(char *others, const char *line)
{
	const char *p, *end = strchr(line, '(') - 1;
	while (cisspace(*end)) {
		end--;
		if (end == line)
			return others;
	}

	for (p = end; cisalnum(*p) || *p == '_'; p--) {
		if (p == line)
			return others;
	}

	return talloc_asprintf_append(others, "printf(\"%%p\", %.*s);\n",
				      (unsigned)(end - p), p+1);
}
Esempio n. 5
0
/* We only handle simple function definitions here. */
static char *add_func(const tal_t *ctx, char *others, const char *line)
{
	const char *p, *end = strchr(line, '(') - 1;
	char *use;

	while (cisspace(*end)) {
		end--;
		if (end == line)
			return others;
	}

	for (p = end; cisalnum(*p) || *p == '_'; p--) {
		if (p == line)
			return others;
	}

	use = tal_fmt(ctx, "printf(\"%%p\", %.*s);\n",
		      (unsigned)(end - p), p+1);
	if (others)
		use = tal_strcat(ctx, take(others), take(use));

	return use;
}
Esempio n. 6
0
static bool spacestart(const struct pattern *p, size_t off)
{
	return cisspace(p->text[p->part[off].off]);
}
Esempio n. 7
0
/* We want "finished in100 seconds to match "finished in  5 seconds". */
struct pattern *get_pattern(const char *line, struct values **vals)
{
	enum pattern_type state = LITERAL;
	size_t len, i, max_parts = 3;
	struct pattern_part part;
	struct pattern *p;

	*vals = malloc(valsize(max_parts));
	p = malloc(partsize(max_parts));
	p->text = line;
	p->num_parts = 0;

	for (i = len = 0; state != TERM; i++, len++) {
		enum pattern_type old_state = state;
		bool starts_num;
		union val v;

		starts_num = (line[i] == '-' && cisdigit(line[i+1]))
			|| cisdigit(line[i]);

		switch (state) {
		case LITERAL:
			if (starts_num) {
				state = INTEGER;
				break;
			} else if (cisspace(line[i])) {
				state = PRESPACES;
				break;
			}
			break;
		case PRESPACES:
			if (starts_num) {
				state = INTEGER;
				break;
			} else if (!cisspace(line[i])) {
				state = LITERAL;
			}
			break;
		case INTEGER:
			if (line[i] == '.') {
				if (cisdigit(line[i+1])) {
					/* Was float all along... */
					state = old_state = FLOAT;
				} else
					state = LITERAL;
				break;
			}
			/* fall thru */
		case FLOAT:
			if (cisspace(line[i])) {
				state = PRESPACES;
				break;
			} else if (!cisdigit(line[i])) {
				state = LITERAL;
				break;
			}
			break;
		case TERM:
			abort();
		}

		if (!line[i])
			state = TERM;

		if (state == old_state)
			continue;

		part.type = old_state;
		part.len = len;
		part.off = i - len;
		/* Make sure identical values memcmp in find_literal_numbers  */
		memset(&v, 0, sizeof(v));
		if (old_state == FLOAT) {
			char *end;
			v.dval = strtod(line + part.off, &end);
			if (end != line + i) {
				warnx("Could not parse float '%.*s'",
				      (int)len, line + i - len);
			} else {
				add_part(&p, vals, &part, &v, &max_parts);
			}
			len = 0;
		} else if (old_state == INTEGER) {
			char *end;
			v.ival = strtoll(line + part.off, &end, 10);
			if (end != line + i) {
				warnx("Could not parse integer '%.*s'",
				      (int)len, line + i - len);
			} else {
				add_part(&p, vals, &part, &v, &max_parts);
			}
			len = 0;
		} else if (old_state == LITERAL && len > 0) {
			/* Since we can go to PRESPACES and back, we can
			 * have successive literals.  Collapse them. */
			if (p->num_parts > 0
			    && p->part[p->num_parts-1].type == LITERAL) {
				p->part[p->num_parts-1].len += len;
				len = 0;
				continue;
			}
			add_part(&p, vals, &part, &v, &max_parts);
			len = 0;
		}
	}
	return p;
}