Ejemplo n.º 1
0
int
split_on(const char *line, char delim, strlist_t *sl)
{
    custr_t *cu = NULL;
    int error = 0;
    const char *c = line;

    if (custr_alloc(&cu) != 0) {
        error = errno;
        goto out;
    }

    for (;;) {
        char cc = *c++;

        if (cc == '\0') {
            if (custr_len(cu) > 0 && strlist_set_tail(sl,
                    custr_cstr(cu)) != 0) {
                error = errno;
            }
            goto out;
        } else if (cc == delim) {
            if (strlist_set_tail(sl, custr_cstr(cu)) != 0) {
                error = errno;
                goto out;
            }
            custr_reset(cu);
        } else {
            if (custr_appendc(cu, cc) != 0) {
                error = errno;
                goto out;
            }
        }
    }

out:
    custr_free(cu);
    errno = error;
    return (error == 0 ? 0 : -1);
}
Ejemplo n.º 2
0
static void
mkprog(struct sym_test *st)
{
	char *s = NULL;

	custr_reset(st_custr);

	for (int i = 0; i < MAXHDR && st->st_hdrs[i] != NULL; i++) {
		addprogfmt("#include <%s>\n", st->st_hdrs[i]);
	}

	if (st->st_rtype != NULL) {
		for (s = st->st_rtype; *s; s++) {
			addprogch(*s);
			if (*s == '(') {
				s++;
				addprogch(*s);
				s++;
				break;
			}
		}
		addprogch(' ');
	}

	/* for function pointers, s is closing suffix, otherwise empty */

	switch (st->st_type) {
	case SYM_TYPE:
		addprogstr("test_type;");
		break;

	case SYM_VALUE:
		addprogfmt("test_value%s;\n", s);	/* s usually empty */
		addprogstr("void\ntest_func(void)\n{\n");
		addprogfmt("\ttest_value = %s;\n}", st->st_name);
		break;

	case SYM_DEFINE:
		addprogfmt("#if !defined(%s)", st->st_name);
		if (st->st_defval != NULL)
			addprogfmt("|| %s != %s", st->st_name, st->st_defval);
		addprogfmt("\n#error %s is not defined or has the wrong value",
		    st->st_name);
		addprogfmt("\n#endif\n");
		break;

	case SYM_FUNC:
		addprogstr("\ntest_func(");
		for (int i = 0; st->st_atypes[i] != NULL && i < MAXARG; i++) {
			int didname = 0;
			if (i > 0) {
				addprogstr(", ");
			}
			if (strcmp(st->st_atypes[i], "void") == 0) {
				didname = 1;
			}
			if (strcmp(st->st_atypes[i], "") == 0) {
				didname = 1;
				addprogstr("void");
			}

			/* print the argument list */
			for (char *a = st->st_atypes[i]; *a; a++) {
				if (*a == '(' && a[1] == '*' && !didname) {
					addprogfmt("(*a%d", i);
					didname = 1;
					a++;
				} else if (*a == '[' && !didname) {
					addprogfmt("a%d[", i);
					didname = 1;
				} else {
					addprogch(*a);
				}
			}
			if (!didname) {
				addprogfmt(" a%d", i);
			}
		}

		if (st->st_atypes[0] == NULL) {
			addprogstr("void");
		}

		/*
		 * Close argument list, and closing ")" for func ptrs.
		 * Note that for non-function pointers, s will be empty
		 * below, otherwise it points to the trailing argument
		 * list.
		 */
		addprogfmt(")%s\n{\n\t", s);

		if (strcmp(st->st_rtype, "") != 0 &&
		    strcmp(st->st_rtype, "void") != 0) {
			addprogstr("return ");
		}

		/* add the function call */
		addprogfmt("%s(", st->st_name);
		for (int i = 0; st->st_atypes[i] != NULL && i < MAXARG; i++) {
			if (strcmp(st->st_atypes[i], "") != 0 &&
			    strcmp(st->st_atypes[i], "void") != 0) {
				addprogfmt("%sa%d", i > 0 ? ", " : "", i);
			}
		}

		addprogstr(");\n}");
		break;
	}

	addprogch('\n');

	st->st_prog = custr_cstr(st_custr);
}
Ejemplo n.º 3
0
int
parse_line(const char *line, strlist_t *sl)
{
    custr_t *cu = NULL;
    state_t state = ST_WHITESPACE;
    const char *c = line;
    int error = 0;

    if (custr_alloc(&cu) != 0) {
        error = errno;
        goto out;
    }

    for (;;) {
        char cc = *c;
        lextype_t lextype;

        /*
         * Determine which class of character this is:
         */
        switch (cc) {
        case '\0':
        case '#':
        case '\n':
        case '\r':
            lextype = LEX_ENDL;
            break;

        case ' ':
        case '\t':
            lextype = LEX_WHITESPACE;
            break;

        default:
            lextype = LEX_OTHER;
            break;
        }

        /*
         * Determine what to do with this character based on the class
         * and our current state:
         */
        switch (state) {
        case ST_WHITESPACE: {
            switch (lextype) {
            case LEX_ENDL:
                goto out;

            case LEX_WHITESPACE:
                c++;
                break;

            case LEX_OTHER:
                state = ST_TOKEN;
                break;

            default:
                (void) printf("ST_WHITESPACE: unknown "
                              "lextype: %d\n", lextype);
                abort();
            }
            break;
        }

        case ST_TOKEN: {
            switch (lextype) {
            case LEX_ENDL:
                if (strlist_set_tail(sl, custr_cstr(cu)) != 0) {
                    error = errno;
                    goto out;
                }
                goto out;

            case LEX_WHITESPACE:
                if (strlist_set_tail(sl, custr_cstr(cu)) != 0) {
                    error = errno;
                    goto out;
                }
                custr_reset(cu);
                state = ST_WHITESPACE;
                break;

            case LEX_OTHER:
                if (custr_appendc(cu, cc) != 0) {
                    error = errno;
                    goto out;
                }
                c++;
                break;

            default:
                (void) printf("ST_TOKEN: unknown lextype: %d\n",
                              lextype);
                abort();
            }
            break;
        }

        default:
            (void) printf("unknown state: %d\n", state);
            abort();
        }
    }

out:
    custr_free(cu);
    errno = error;
    return (error == 0 ? 0 : -1);
}