a couple of bux fixes

This commit is contained in:
cozis
2022-05-12 23:05:47 +02:00
parent 71d944b0d9
commit c49557963b
+38 -28
View File
@@ -63,24 +63,19 @@ typedef struct {
static bool isoperat(char c) static bool isoperat(char c)
{ {
return c == '+' return c == '+' || c == '-'
|| c == '-' || c == '*' || c == '/'
|| c == '*' || c == '%' || c == '='
|| c == '/'
|| c == '%'
|| c == '='
|| c == '!' || c == '!'
|| c == '<' || c == '<' || c == '>'
|| c == '>' || c == '|' || c == '&';
|| c == '|'
|| c == '&';
} }
static bool iskword(const char *str, long len) static bool iskword(const char *str, long len)
{ {
static const struct { static const struct {
int len; int len;
char str[9]; // Maximum length of a keyword. char str[8]; // Maximum length of a keyword.
} keywords[] = { } keywords[] = {
#define KWORD(lit) { sizeof(lit)-1, lit } #define KWORD(lit) { sizeof(lit)-1, lit }
KWORD("auto"), KWORD("break"), KWORD("case"), KWORD("auto"), KWORD("break"), KWORD("case"),
@@ -100,8 +95,8 @@ static bool iskword(const char *str, long len)
const int num_keywords = sizeof(keywords)/sizeof(keywords[0]); const int num_keywords = sizeof(keywords)/sizeof(keywords[0]);
for(int i = 0; i < num_keywords; i += 1) for(int i = 0; i < num_keywords; i += 1)
if(keywords[i].len == len && !strncmp(keywords[i].str, str, len)) if(keywords[i].len == len && !strncmp(keywords[i].str, str, len))
return 1; return true;
return 0; return false;
} }
static Token *tokenize(const char *str, long len) static Token *tokenize(const char *str, long len)
@@ -113,8 +108,8 @@ static Token *tokenize(const char *str, long len)
Token T; Token T;
long curly_bracket_depth = 0; long curly_bracket_depth = 0;
bool only_spaces_since_line_start = 1; bool only_spaces_since_line_start = true;
bool prev_nonspace_was_directive = 0; bool prev_nonspace_was_directive = false;
do { do {
if(i == len) { if(i == len) {
@@ -124,19 +119,26 @@ static Token *tokenize(const char *str, long len)
} else if(i+1 < len && str[i] == '/' && str[i+1] == '/') { } else if(i+1 < len && str[i] == '/' && str[i+1] == '/') {
T.kind = T_COMMENT; T.kind = T_COMMENT;
T.off = i; T.off = i;
while(i < len && str[i] != '\n') while(i < len && str[i] != '\n') // What about backslashes??
i += 1; i += 1;
T.len = i - T.off; T.len = i - T.off;
} else if(i+1 < len && str[i] == '/' && str[i+1] == '*') { } else if(i+1 < len && str[i] == '/' && str[i+1] == '*') {
T.kind = T_COMMENT; T.kind = T_COMMENT;
T.off = i; T.off = i;
while(1) { while(1) {
while(i < len && str[i] != '*') while(i < len && str[i] != '*')
i += 1; i += 1;
if(i == len) if(i == len)
break; break;
assert(str[i] == '*'); assert(str[i] == '*');
i += 1; i += 1;
if(i == len)
break;
if(str[i] == '/') { if(str[i] == '/') {
i += 1; i += 1;
break; break;
@@ -219,8 +221,10 @@ static Token *tokenize(const char *str, long len)
} else if(isalpha(str[i]) || str[i] == '_') { } else if(isalpha(str[i]) || str[i] == '_') {
T.off = i; T.off = i;
while(isalpha(str[i]) || isdigit(str[i]) || str[i] == '_') do
i += 1; i += 1;
while(isalpha(str[i]) ||
isdigit(str[i]) || str[i] == '_');
T.len = i - T.off; T.len = i - T.off;
/* It may either be an identifier or a /* It may either be an identifier or a
@@ -232,7 +236,7 @@ static Token *tokenize(const char *str, long len)
else { else {
/* If the identifier is followed by a '(' and /* If the identifier is followed by a '(' and
* it's in the global scope, then it's in a * it's in the global scope, then it's for a
* function definiton. If it's not in the global * function definiton. If it's not in the global
* scope then it's a function call. * scope then it's a function call.
* Between the identifier and the '(' there may * Between the identifier and the '(' there may
@@ -242,17 +246,17 @@ static Token *tokenize(const char *str, long len)
* right after the identifier. * right after the identifier.
*/ */
bool followed_by_parenthesis = 0; bool followed_by_parenthesis = false;
bool yes_and_immediately = 0; bool yes_and_immediately = false;
{ {
long k = i; long k = i;
while(k < len && (str[k] == ' ' || str[k] == '\t')) while(k < len && (str[k] == ' ' || str[k] == '\t'))
k += 1; k += 1;
if(k < len && str[k] == '(') { if(k < len && str[k] == '(') {
followed_by_parenthesis = 1; followed_by_parenthesis = true;
if(k == i) if(k == i)
yes_and_immediately = 1; yes_and_immediately = true;
} }
} }
@@ -340,16 +344,16 @@ static Token *tokenize(const char *str, long len)
} }
if(T.kind == T_NEWL) if(T.kind == T_NEWL)
only_spaces_since_line_start = 1; only_spaces_since_line_start = true;
else else
if(T.kind != T_TAB && T.kind != T_SPACE) if(T.kind != T_TAB && T.kind != T_SPACE)
only_spaces_since_line_start = 0; only_spaces_since_line_start = false;
if(T.kind == T_DIRECTIVE) if(T.kind == T_DIRECTIVE)
prev_nonspace_was_directive = 1; prev_nonspace_was_directive = true;
else else
if(T.kind != T_TAB && T.kind != T_SPACE) if(T.kind != T_TAB && T.kind != T_SPACE)
prev_nonspace_was_directive = 0; prev_nonspace_was_directive = false;
if(count == capacity) { if(count == capacity) {
int new_capacity; int new_capacity;
@@ -480,7 +484,7 @@ static void print_escaped(buff_t *buff, const char *str, long len)
switch(str[j]) { switch(str[j]) {
case '<': buff_printf(buff, "&lt;"); break; case '<': buff_printf(buff, "&lt;"); break;
case '>': buff_printf(buff, "&gt;"); break; case '>': buff_printf(buff, "&gt;"); break;
default: assert(0); default: assert(0); break;
} }
j += 1; j += 1;
@@ -499,6 +503,13 @@ char *c2html(const char *str, long len, const char *prefix,
if(prefix == NULL) if(prefix == NULL)
prefix = ""; prefix = "";
Token *tokens = tokenize(str, len);
if(tokens == NULL) {
if(error != NULL)
*error = "Out of memory";
return NULL;
}
buff_t buff; buff_t buff;
buff_init(&buff); buff_init(&buff);
long lineno = 1; long lineno = 1;
@@ -510,7 +521,6 @@ char *c2html(const char *str, long len, const char *prefix,
" <tr><td>1</td><td>", " <tr><td>1</td><td>",
prefix, prefix); prefix, prefix);
Token *tokens = tokenize(str, len);
for(int i = 0; tokens[i].kind != T_DONE; i += 1) { for(int i = 0; tokens[i].kind != T_DONE; i += 1) {
switch(tokens[i].kind) { switch(tokens[i].kind) {