Ejemplo n.º 1
0
ussval_t* builtin_load(ussenv_t* e, ussval_t* a) {
    UASSERT_NUM("load", a, 1);
    UASSERT_TYPE("load", a, 0, UVAL_STR);

    /* Parse File given by string name */
    mpc_result_t r;
    parser_t *parser = parser_toplevel();

    if (mpc_parse_contents(a->cell[0]->str, parser->uss, &r)) {
        fprintf(stderr, "DEBUG: loading: %s\n", a->cell[0]->str);
        ussenv_put(e, ussval_new_sym("file-path"), a->cell[0]);
        ussenv_put(e, ussval_new_sym("file-dir"), ussval_new_str(dirname(a->cell[0]->str)));

        /* Read contents */
        ussval_t *expr = ussval_read(r.output);
        mpc_ast_delete(r.output);

        /* Evaluate each Expression */
        while (expr->count) {
            ussval_t *x = ussval_eval(e, ussval_pop(expr, 0));
            /* If Evaluation leads to error print it */
            if (x->type == UVAL_ERR) {
                ussval_println(x);
            }
            ussval_del(x);
        }

        /* Delete expressions and arguments */
        ussval_del(expr);
        ussval_del(a);

        parser_cleanup(parser);

        //lenv_put(e, lval_sym("file-path"), LVAL_NIL);
        //lenv_put(e, lval_sym("file-dir"), LVAL_NIL);

        /* Return empty list */
        return ussval_new_sexpr();

    } else {
        /* Get Parse Error as String */
        char *err_msg = mpc_err_string(r.error);
        mpc_err_delete(r.error);

        /* Create new error message using it */
        ussval_t *err = ussval_new_err("Could not load Library %s", err_msg);
        free(err_msg);
        ussval_del(a);

        parser_cleanup(parser);
        /* Cleanup and return error */
        return err;
    }
}
Ejemplo n.º 2
0
Archivo: uss.c Proyecto: aktowns/USS
int main(int argc, char** argv) {
    GC_INIT();
    ussenv_t *e = ussenv_new();
    ussenv_common_builtins(e);

    char *prelude_path = join_path(STDLIB_PATH, true, "prelude.uss");

    ussval_t *prelude = ussval_eval_from_file(e, prelude_path);

    /* If the result is an error be sure to print it */
    if (prelude->type == UVAL_ERR) { ussval_println(prelude); }
    ussval_del(prelude);

    fprintf(stderr, "argv[0]=%s argv[1]=%s\n", argv[0], argv[1]);

    if (argc >= 2) {
        /* loop over each supplied filename (starting from 1) */
        for (int i = 1; i < argc; i++) {
            ussval_t *x = ussval_eval_from_file(e, argv[i]);

            /* If the result is an error be sure to print it */
            if (x->type == UVAL_ERR) {
                ussval_println(x);
            }

            ussval_del(x);
        }
    } else {
        char buf[4096];

        parser_t *parser = parser_toplevel();
        mpc_result_t r;

        ussval_t *x = UVAL_NIL;
        while(fgets(buf, sizeof(buf), stdin)) {
            if (mpc_parse("<stdin>", buf, parser->uss, &r)) {
                // mpc_ast_print(r.output);
                x = ussval_eval(e, ussval_read(r.output));
                mpc_ast_delete(r.output);
            } else {
                mpc_err_print(r.error);
                mpc_err_delete(r.error);
            }
        }

        ussval_println(x);
        parser_cleanup(parser);
    }

    ussenv_del(e);
    return 0;
}
Ejemplo n.º 3
0
int main(int argc, char** argv) {
    // Initialization
    parser_init();
    lenv* env = lenv_new();
    builtins_init(env);

    if (argc >= 2) {
        // Loop over file names
        for (int i = 1; i < argc; i++) {
            lval* args   = lval_add(lval_sexpr(), lval_str(argv[i]));
            lval* result = builtin_load(env, args);

            if (result->type == LVAL_ERR) {
                lval_println(env, result);
            }
            lval_del(result);
        }
    } else {
        // Welcome message
        puts("MLisp Version 0.1dev");
        puts("Enter 'quit' to exit\n");

        while (1) {
            char* input = read_input();
            add_history(input);

            if (input == NULL || strstr(input, "exit") || strstr(input, "quit")) {
                puts("Bye!");
                if (input != NULL) {
                    xfree(input);
                }
                break;
            }

            lval* result = NULL;
            mpc_err_t* parser_error = NULL;

            if (parse("<stdin>", input, env, &result, &parser_error)) {
                if (!(result->type == LVAL_SEXPR && result->count == 0)) {
                    char* repr = lval_repr(env, result);
                    printf("%s\n", repr);
                    xfree(repr);
                }

                lval_del(result);
            } else {
                mpc_err_print(parser_error);
                mpc_err_delete(parser_error);
            }

            xfree(input);
        }
    }

    lenv_del(env);

    // Undefine and delete our parsers
    parser_cleanup();

    return 0;
}
Ejemplo n.º 4
0
void parser_free(parser_t *self) {
    // opposite of parser_init
    parser_cleanup(self);
    free(self);
}
Ejemplo n.º 5
0
int parser_init(parser_t *self) {
    int sz;

    /*
      Initialize data buffers
    */

    self->stream = NULL;
    self->words = NULL;
    self->word_starts = NULL;
    self->line_start = NULL;
    self->line_fields = NULL;

    // token stream
    self->stream = (char*) malloc(STREAM_INIT_SIZE * sizeof(char));
    if (self->stream == NULL) {
        return PARSER_OUT_OF_MEMORY;
    }
    self->stream_cap = STREAM_INIT_SIZE;
    self->stream_len = 0;

    // word pointers and metadata
    sz = STREAM_INIT_SIZE / 10;
    sz = sz? sz : 1;
    self->words = (char**) malloc(sz * sizeof(char*));
    self->word_starts = (int*) malloc(sz * sizeof(int));
    self->words_cap = sz;
    self->words_len = 0;

    // line pointers and metadata
    self->line_start = (int*) malloc(sz * sizeof(int));

    self->line_fields = (int*) malloc(sz * sizeof(int));

    self->lines_cap = sz;
    self->lines = 0;
    self->file_lines = 0;

    if (self->stream == NULL || self->words == NULL ||
        self->word_starts == NULL || self->line_start == NULL ||
        self->line_fields == NULL) {

        parser_cleanup(self);

        return PARSER_OUT_OF_MEMORY;
    }

    /* amount of bytes buffered */
    self->datalen = 0;
    self->datapos = 0;

    self->line_start[0] = 0;
    self->line_fields[0] = 0;

    self->pword_start = self->stream;
    self->word_start = 0;

    self->state = START_RECORD;

    self->error_msg = NULL;
    self->warn_msg = NULL;

    self->commentchar = '\0';

    return 0;
}
Ejemplo n.º 6
0
/**
 * mnt_table_parse_stream:
 * @tb: tab pointer
 * @f: file stream
 * @filename: filename used for debug and error messages
 *
 * Returns: 0 on success, negative number in case of error.
 */
int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename)
{
	int rc = -1;
	int flags = 0;
	pid_t tid = -1;
	struct libmnt_fs *fs = NULL;
	struct libmnt_parser pa = { .line = 0 };

	assert(tb);
	assert(f);
	assert(filename);

	DBG(TAB, ul_debugobj(tb, "%s: start parsing [entries=%d, filter=%s]",
				filename, mnt_table_get_nents(tb),
				tb->fltrcb ? "yes" : "not"));

	pa.filename = filename;
	pa.f = f;

	/* necessary for /proc/mounts only, the /proc/self/mountinfo
	 * parser sets the flag properly
	 */
	if (filename && strcmp(filename, _PATH_PROC_MOUNTS) == 0)
		flags = MNT_FS_KERNEL;

	while (!feof(f)) {
		if (!fs) {
			fs = mnt_new_fs();
			if (!fs)
				goto err;
		}

		rc = mnt_table_parse_next(&pa, tb, fs);

		if (!rc && tb->fltrcb && tb->fltrcb(fs, tb->fltrcb_data))
			rc = 1;	/* filtered out by callback... */

		if (!rc) {
			rc = mnt_table_add_fs(tb, fs);
			fs->flags |= flags;

			if (rc == 0 && tb->fmt == MNT_FMT_MOUNTINFO) {
				rc = kernel_fs_postparse(tb, fs, &tid, filename);
				if (rc)
					mnt_table_remove_fs(tb, fs);
			}
		}

		if (rc) {
			if (rc > 0) {
				mnt_reset_fs(fs);
				assert(fs->refcount == 1);
				continue;	/* recoverable error, reuse fs*/
			}

			mnt_unref_fs(fs);
			if (feof(f))
				break;
			goto err;		/* fatal error */
		}
		mnt_unref_fs(fs);
		fs = NULL;
	}

	DBG(TAB, ul_debugobj(tb, "%s: stop parsing (%d entries)",
				filename, mnt_table_get_nents(tb)));
	parser_cleanup(&pa);
	return 0;
err:
	DBG(TAB, ul_debugobj(tb, "%s: parse error (rc=%d)", filename, rc));
	parser_cleanup(&pa);
	return rc;
}

/**
 * mnt_table_parse_file:
 * @tb: tab pointer
 * @filename: file
 *
 * Parses the whole table (e.g. /etc/fstab) and appends new records to the @tab.
 *
 * The libmount parser ignores broken (syntax error) lines, these lines are
 * reported to the caller by the errcb() function (see mnt_table_set_parser_errcb()).
 *
 * Returns: 0 on success, negative number in case of error.
 */
int mnt_table_parse_file(struct libmnt_table *tb, const char *filename)
{
	FILE *f;
	int rc;

	if (!filename || !tb)
		return -EINVAL;

	f = fopen(filename, "r" UL_CLOEXECSTR);
	if (f) {
		rc = mnt_table_parse_stream(tb, f, filename);
		fclose(f);
	} else
		rc = -errno;

	DBG(TAB, ul_debugobj(tb, "parsing done [filename=%s, rc=%d]", filename, rc));
	return rc;
}