Skip to content

Commit

Permalink
Read code from a file instead of argv[1]
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Aug 20, 2019
1 parent 9a810d6 commit 6a62177
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 5 deletions.
3 changes: 3 additions & 0 deletions chibicc.h
@@ -1,8 +1,10 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Expand Down Expand Up @@ -48,6 +50,7 @@ bool at_eof();
Token *new_token(TokenKind kind, Token *cur, char *str, int len);
Token *tokenize();

extern char *filename;
extern char *user_input;
extern Token *token;

Expand Down
23 changes: 22 additions & 1 deletion main.c
@@ -1,5 +1,25 @@
#include "chibicc.h"

// Returns the contents of a given file.
char *read_file(char *path) {
// Open and read the file.
FILE *fp = fopen(path, "r");
if (!fp)
error("cannot open %s: %s", path, strerror(errno));

int filemax = 10 * 1024 * 1024;
char *buf = malloc(filemax);
int size = fread(buf, 1, filemax - 2, fp);
if (!feof(fp))
error("%s: file too large");

// Make sure that the string ends with "\n\0".
if (size == 0 || buf[size - 1] != '\n')
buf[size++] = '\n';
buf[size] = '\0';
return buf;
}

int align_to(int n, int align) {
return (n + align - 1) & ~(align - 1);
}
Expand All @@ -9,7 +29,8 @@ int main(int argc, char **argv) {
error("%s: invalid number of arguments", argv[0]);

// Tokenize and parse.
user_input = argv[1];
filename = argv[1];
user_input = read_file(argv[1]);
token = tokenize();
Program *prog = program();
add_type(prog);
Expand Down
2 changes: 1 addition & 1 deletion test.sh
Expand Up @@ -14,7 +14,7 @@ assert() {
expected="$1"
input="$2"

./chibicc "$input" > tmp.s
./chibicc <(echo "$input") > tmp.s
gcc -static -o tmp tmp.s tmp2.o
./tmp
actual="$?"
Expand Down
29 changes: 26 additions & 3 deletions tokenize.c
@@ -1,5 +1,6 @@
#include "chibicc.h"

char *filename;
char *user_input;
Token *token;

Expand All @@ -12,10 +13,32 @@ void error(char *fmt, ...) {
exit(1);
}

// Reports an error location and exit.
// Reports an error message in the following format and exit.
//
// foo.c:10: x = y + 1;
// ^ <error message here>
void verror_at(char *loc, char *fmt, va_list ap) {
int pos = loc - user_input;
fprintf(stderr, "%s\n", user_input);
// Find a line containing `loc`.
char *line = loc;
while (user_input < line && line[-1] != '\n')
line--;

char *end = loc;
while (*end != '\n')
end++;

// Get a line number.
int line_num = 1;
for (char *p = user_input; p < line; p++)
if (*p == '\n')
line_num++;

// Print out the line.
int indent = fprintf(stderr, "%s:%d: ", filename, line_num);
fprintf(stderr, "%.*s\n", (int)(end - line), line);

// Show the error message.
int pos = loc - line + indent;
fprintf(stderr, "%*s", pos, ""); // print pos spaces.
fprintf(stderr, "^ ");
vfprintf(stderr, fmt, ap);
Expand Down

0 comments on commit 6a62177

Please sign in to comment.