#define _POSIX_C_SOURCE 200809L #include #include #include #include "aplwc_repl.h" int main(int argc, char *argv[]) { struct aplwc *aplwc; struct aplwc_line *line; struct aplwc_value *value; uint8_t *data; char *input, *src; int ret, exit_code, line_number; size_t memsize, input_size, src_size, i; int opt, xflag, input_file; long tmp; FILE *f; input = NULL; line = NULL; value = NULL; xflag = 0; input_file = 0; exit_code = 0; line_number = 0; while((opt = getopt(argc, argv, "x")) != -1){ switch(opt){ case 'x': xflag = 1; break; default: usage: fprintf(stderr, "Usage: %s [-x] [file]\n", argv[0]); return 1; } } if((optind+1) == argc){ input_file = 1; f = fopen(argv[optind], "r"); if(f == NULL){ fprintf(stderr, "Could not open file: %s: %s\n", argv[optind], strerror(errno)); return 1; } }else if(optind == argc) f = stdin; else goto usage; memsize = getenv_ulong("APLWC_MEM", APLWC_MIN_MEM); data = malloc(memsize); if(data == NULL){ fprintf(stderr, "Couldn't allocate memory\n"); return 1; } ret = aplwc_new(&aplwc, data, memsize); if(ret){ fprintf(stderr, "Couldn't create new aplwc instance: %s\n", aplwc_errstr_rc(ret)); free(data); return 1; } if(input_file){ if(fseek(f, 0, SEEK_END)){ file_size: fprintf(stderr, "Failed to determine file size\n"); return 1; } tmp = ftell(f); if(tmp < 0) goto file_size; input_size = tmp; rewind(f); input = malloc(input_size); if(input == NULL){ fprintf(stderr, "Failed to allocate space for file contents\n"); return 1; } if(fread(input, 1, input_size, f) < input_size){ fprintf(stderr, "Failed to read file contents\n"); return 1; } fclose(f); src = input; src_size = input_size; if((input_size > 2) && (input[0] == '#') && (input[1] == '!')){ for(i = 0; i < input_size; i++){ if(input[i] == '\n'){ src += i; src_size -= i; xflag = 1; break; } } } ret = aplwc_load_module(aplwc, "Main", src, src_size); if(ret){ fprintf(stderr, "Couldn't load Main module from file %s: %s\n", argv[optind], aplwc_errstr_rc(ret)); return 1; } free(input); input = NULL; } if(xflag) goto exit; for(;;){ if(input) free(input); if(line) aplwc_free_line(line); if(value) aplwc_free_value(value); input = NULL; if(getline(&input, &input_size, stdin) < 0){ free(input); break; }else{ line_number++; line = aplwc_read(aplwc, input); if(line == NULL){ line_error: fprintf(stderr, "error on line %d: %s: %s\n", line_number, aplwc_errstr(aplwc), input); if(input_file){ exit_code = 1; goto exit; } continue; } value = aplwc_eval(line); if(value == NULL) goto line_error; fprintf(stdout, "%s\n", aplwc_value_string(value)); } } exit: if(input) free(input); if(line) aplwc_free_line(line); if(value) aplwc_free_value(value); aplwc_destroy(aplwc); free(data); return exit_code; }