mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-22 10:41:43 +00:00
More cleanups
This commit is contained in:
parent
98b0e11890
commit
36378e341e
6 changed files with 66 additions and 72 deletions
5
error.c
5
error.c
|
@ -24,6 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include "gmqcc.h"
|
||||
|
||||
/*
|
||||
* Compiler error system, this handles the error printing, and managing
|
||||
|
@ -59,7 +60,7 @@ static const char *const error_list[] = {
|
|||
"Preprocessor Error:"
|
||||
};
|
||||
|
||||
int error(int status, const char *msg, ...) {
|
||||
int error(struct lex_file *file, int status, const char *msg, ...) {
|
||||
char bu[1024*4]; /* enough? */
|
||||
char fu[1024*4]; /* enough? */
|
||||
va_list va;
|
||||
|
@ -71,7 +72,7 @@ int error(int status, const char *msg, ...) {
|
|||
error_total ++;
|
||||
/* color */
|
||||
# ifndef WIN32
|
||||
sprintf (bu, "\033[0;%dm%s \033[0;%dm", error_color[status-SHRT_MAX], error_list[status-SHRT_MAX], error_color[(status-1)-SHRT_MAX]);
|
||||
sprintf (bu, "\033[0;%dm%s \033[0;%dm %s:%d ", error_color[status-SHRT_MAX], error_list[status-SHRT_MAX], error_color[(status-1)-SHRT_MAX], file->name, file->line);
|
||||
#else
|
||||
sprintf (bu, "%s ", error_list[status-SHRT_MAX]);
|
||||
#endif
|
||||
|
|
4
gmqcc.h
4
gmqcc.h
|
@ -90,7 +90,7 @@ struct lex_file *lex_open (FILE *);
|
|||
#define ERROR_INTERNAL (SHRT_MAX+2)
|
||||
#define ERROR_COMPILER (SHRT_MAX+3)
|
||||
#define ERROR_PREPRO (SHRT_MAX+4)
|
||||
int error(int, const char *, ...);
|
||||
int error(struct lex_file *, int, const char *, ...);
|
||||
|
||||
//===================================================================
|
||||
//========================== parse.c ================================
|
||||
|
@ -107,7 +107,7 @@ typedef struct typedef_node_t {
|
|||
void typedef_init();
|
||||
void typedef_clear();
|
||||
typedef_node *typedef_find(const char *);
|
||||
int typedef_add (const char *, const char *);
|
||||
int typedef_add (struct lex_file *file, const char *, const char *);
|
||||
|
||||
|
||||
//===================================================================
|
||||
|
|
12
lex.c
12
lex.c
|
@ -249,7 +249,7 @@ static int lex_skipcmt(struct lex_file *file) {
|
|||
lex_addch(ch, file);
|
||||
while ((ch = lex_getch(file)) != '*') {
|
||||
if (ch == EOF)
|
||||
return error(ERROR_LEX, "malformatted comment at line", "");
|
||||
return error(file, ERROR_LEX, "malformatted comment");
|
||||
else
|
||||
lex_addch(ch, file);
|
||||
}
|
||||
|
@ -344,19 +344,15 @@ void lex_reset(struct lex_file *file) {
|
|||
* recrusion.
|
||||
*/
|
||||
struct lex_file *lex_include(struct lex_file *lex, char *file) {
|
||||
char *find = util_strrq(file);
|
||||
/*
|
||||
* Dissallow recrusive include: this could easily cause some breakage
|
||||
* and instant OOM.
|
||||
*/
|
||||
util_strrq(file);
|
||||
if (strncmp(lex->name, file, strlen(lex->name)) == 0) {
|
||||
error(ERROR_LEX, "%s:%d Source file cannot include itself\n", lex->name, lex->line-1);
|
||||
error(lex, ERROR_LEX, "Source file cannot include itself\n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
FILE *fp = fopen(file, "r");
|
||||
if (!fp) {
|
||||
error(ERROR_LEX, "%s:%d Include file `%s` doesn't exist\n", lex->name, lex->line, file);
|
||||
error(lex, ERROR_LEX, "Include file `%s` doesn't exist\n", file);
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
|
|
3
main.c
3
main.c
|
@ -23,6 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include "gmqcc.h"
|
||||
int main(int argc, char **argv) {
|
||||
argc--;
|
||||
|
@ -33,7 +34,7 @@ int main(int argc, char **argv) {
|
|||
FILE *fp = fopen(ifile, "r");
|
||||
if (!fp) {
|
||||
fclose(fp);
|
||||
return error(ERROR_COMPILER, "Source file: %s not found\n", ifile);
|
||||
return printf("ERROR Source file %s %s\n", ifile, strerror(errno));
|
||||
} else {
|
||||
struct lex_file *lex = lex_open(fp);
|
||||
lex->name = util_strdup(ifile);
|
||||
|
|
108
parse.c
108
parse.c
|
@ -54,11 +54,7 @@ void compile_constant_debug() {
|
|||
*/
|
||||
int parse_gen(struct lex_file *file) {
|
||||
int token = 0;
|
||||
while ((token = lex_token(file)) != ERROR_LEX && \
|
||||
token != ERROR_COMPILER && \
|
||||
token != ERROR_INTERNAL && \
|
||||
token != ERROR_PARSE && \
|
||||
token != ERROR_PREPRO && file->length >= 0) {
|
||||
while ((token = lex_token(file)) != ERROR_LEX && file->length >= 0) {
|
||||
switch (token) {
|
||||
case TOKEN_TYPEDEF: {
|
||||
char *f; /* from */
|
||||
|
@ -69,7 +65,7 @@ int parse_gen(struct lex_file *file) {
|
|||
token = lex_token(file);
|
||||
token = lex_token(file); t = util_strdup(file->lastok);
|
||||
|
||||
typedef_add(f, t);
|
||||
typedef_add(file, f, t);
|
||||
mem_d(f);
|
||||
mem_d(t);
|
||||
|
||||
|
@ -78,7 +74,7 @@ int parse_gen(struct lex_file *file) {
|
|||
token = lex_token(file);
|
||||
|
||||
if (token != ';')
|
||||
error(ERROR_PARSE, "%s:%d Expected a `;` at end of typedef statement\n", file->name, file->line);
|
||||
error(file, ERROR_PARSE, "Expected a `;` at end of typedef statement");
|
||||
|
||||
token = lex_token(file);
|
||||
break;
|
||||
|
@ -120,12 +116,12 @@ int parse_gen(struct lex_file *file) {
|
|||
/* strings are in file->lastok */
|
||||
switch (type) {
|
||||
case TOKEN_VOID:
|
||||
return error(ERROR_PARSE, "%s:%d Cannot assign value to type void\n", file->name, file->line);
|
||||
error(file, ERROR_PARSE, "Cannot assign value to type void\n");
|
||||
|
||||
/* TODO: Validate (end quote), strip quotes for constant add, name constant */
|
||||
case TOKEN_STRING:
|
||||
if (*file->lastok != '"')
|
||||
error(ERROR_PARSE, "%s:%d Expected a '\"' (quote) for string constant\n", file->name, file->line);
|
||||
error(file, ERROR_PARSE, "Expected a '\"' (quote) for string constant\n");
|
||||
/* add the compile-time constant */
|
||||
compile_constants_add((constant){
|
||||
.name = util_strdup(name),
|
||||
|
@ -146,55 +142,55 @@ int parse_gen(struct lex_file *file) {
|
|||
char *compile_eval = compile_data;
|
||||
|
||||
if (token != '{')
|
||||
error(ERROR_PARSE, "%s:%d Expected initializer list `{`,`}` for vector constant\n", file->name, file->line);
|
||||
error(file, ERROR_PARSE, "Expected initializer list {} for vector constant\n");
|
||||
|
||||
/*
|
||||
* This parses a single vector element: x,y & z. This will handle all the
|
||||
* complicated mechanics of a vector, and can be extended as well. This
|
||||
* is a rather large macro, and is #undef'd after it's use below.
|
||||
*/
|
||||
#define PARSE_VEC_ELEMENT(NAME, BIT) \
|
||||
token = lex_token(file); \
|
||||
if (token == ' ') \
|
||||
token = lex_token(file); \
|
||||
if (token == '.') \
|
||||
compile_calc_d = 1; \
|
||||
if (!isdigit(token) && !compile_calc_d && token != '+' && token != '-') \
|
||||
error(ERROR_PARSE,"%s:%d Invalid constant initializer element %c for vector, must be numeric\n", file->name, file->line, NAME); \
|
||||
if (token == '+') \
|
||||
compile_calc_s = '+'; \
|
||||
if (token == '-' && !compile_calc_s) \
|
||||
compile_calc_s = '-'; \
|
||||
while (isdigit(token) || token == '.' || token == '+' || token == '-') { \
|
||||
*compile_eval++ = token; \
|
||||
token = lex_token(file); \
|
||||
if (token == '.' && compile_calc_d) { \
|
||||
error(ERROR_PARSE, "%s:%d Invalid constant initializer element %c for vector, must be numeric.\n", file->name, file->line, NAME); \
|
||||
token = lex_token(file); \
|
||||
} \
|
||||
if ((token == '-' || token == '+') && compile_calc_s) { \
|
||||
error(ERROR_PARSE, "%s:%d Invalid constant initializer sign for vector element %c\n", file->name, file->line, NAME); \
|
||||
token = lex_token(file); \
|
||||
} \
|
||||
else if (token == '.' && !compile_calc_d) \
|
||||
compile_calc_d = 1; \
|
||||
else if (token == '-' && !compile_calc_s) \
|
||||
compile_calc_s = '-'; \
|
||||
else if (token == '+' && !compile_calc_s) \
|
||||
compile_calc_s = '+'; \
|
||||
} \
|
||||
if (token == ' ') \
|
||||
token = lex_token(file); \
|
||||
if (NAME != 'z') { \
|
||||
if (token != ',' && token != ' ') \
|
||||
error(ERROR_PARSE, "%s:%d invalid constant initializer element %c for vector (missing spaces, or comma delimited list?)\n", file->name, file->line, NAME); \
|
||||
} else if (token != '}') { \
|
||||
error(ERROR_PARSE, "%s:%d Expected `}` on end of constant initialization for vector\n", file->name, file->line); \
|
||||
} \
|
||||
compile_calc_##BIT = atof(compile_data); \
|
||||
compile_calc_d = 0; \
|
||||
compile_calc_s = 0; \
|
||||
compile_eval = &compile_data[0]; \
|
||||
#define PARSE_VEC_ELEMENT(NAME, BIT) \
|
||||
token = lex_token(file); \
|
||||
if (token == ' ') \
|
||||
token = lex_token(file); \
|
||||
if (token == '.') \
|
||||
compile_calc_d = 1; \
|
||||
if (!isdigit(token) && !compile_calc_d && token != '+' && token != '-') \
|
||||
error(file, ERROR_PARSE,"Invalid constant initializer element %c for vector, must be numeric\n", NAME); \
|
||||
if (token == '+') \
|
||||
compile_calc_s = '+'; \
|
||||
if (token == '-' && !compile_calc_s) \
|
||||
compile_calc_s = '-'; \
|
||||
while (isdigit(token) || token == '.' || token == '+' || token == '-') { \
|
||||
*compile_eval++ = token; \
|
||||
token = lex_token(file); \
|
||||
if (token == '.' && compile_calc_d) { \
|
||||
error(file, ERROR_PARSE, "Invalid constant initializer element %c for vector, must be numeric.\n", NAME); \
|
||||
token = lex_token(file); \
|
||||
} \
|
||||
if ((token == '-' || token == '+') && compile_calc_s) { \
|
||||
error(file, ERROR_PARSE, "Invalid constant initializer sign for vector element %c\n", NAME); \
|
||||
token = lex_token(file); \
|
||||
} \
|
||||
else if (token == '.' && !compile_calc_d) \
|
||||
compile_calc_d = 1; \
|
||||
else if (token == '-' && !compile_calc_s) \
|
||||
compile_calc_s = '-'; \
|
||||
else if (token == '+' && !compile_calc_s) \
|
||||
compile_calc_s = '+'; \
|
||||
} \
|
||||
if (token == ' ') \
|
||||
token = lex_token(file); \
|
||||
if (NAME != 'z') { \
|
||||
if (token != ',' && token != ' ') \
|
||||
error(file, ERROR_PARSE, "invalid constant initializer element %c for vector (missing spaces, or comma delimited list?)\n", NAME); \
|
||||
} else if (token != '}') { \
|
||||
error(file, ERROR_PARSE, "Expected `}` on end of constant initialization for vector\n"); \
|
||||
} \
|
||||
compile_calc_##BIT = atof(compile_data); \
|
||||
compile_calc_d = 0; \
|
||||
compile_calc_s = 0; \
|
||||
compile_eval = &compile_data[0]; \
|
||||
memset(compile_data, 0, sizeof(compile_data))
|
||||
|
||||
/*
|
||||
|
@ -211,7 +207,7 @@ int parse_gen(struct lex_file *file) {
|
|||
if (token == ' ')
|
||||
token = lex_token(file);
|
||||
if (token != ';')
|
||||
error(ERROR_PARSE, "%s:%d Expected `;` on end of constant initialization for vector\n", file->name, file->line);
|
||||
error(file, ERROR_PARSE, "Expected `;` on end of constant initialization for vector\n");
|
||||
|
||||
/* add the compile-time constant */
|
||||
compile_constants_add((constant){
|
||||
|
@ -230,7 +226,7 @@ int parse_gen(struct lex_file *file) {
|
|||
case TOKEN_ENTITY:
|
||||
case TOKEN_FLOAT: /*TODO: validate, constant generation, name constant */
|
||||
if (!isdigit(token))
|
||||
error(ERROR_PARSE, "%s:%d Expected numeric constant for float constant\n");
|
||||
error(file, ERROR_PARSE, "Expected numeric constant for float constant\n");
|
||||
compile_constants_add((constant){
|
||||
.name = util_strdup(name),
|
||||
.type = TOKEN_FLOAT,
|
||||
|
@ -268,13 +264,13 @@ int parse_gen(struct lex_file *file) {
|
|||
while (*file->lastok != '"' && token != '\n')
|
||||
token = lex_token(file);
|
||||
if (token == '\n')
|
||||
return error(ERROR_PARSE, "%d: Invalid use of include preprocessor directive: wanted #include \"file.h\"\n", file->line-1);
|
||||
return error(file, ERROR_PARSE, "Invalid use of include preprocessor directive: wanted #include \"file.h\"\n");
|
||||
|
||||
char *copy = util_strdup(file->lastok);
|
||||
struct lex_file *next = lex_include(file, copy);
|
||||
|
||||
if (!next) {
|
||||
error(ERROR_INTERNAL, "Include subsystem failure\n");
|
||||
error(file, ERROR_INTERNAL, "Include subsystem failure\n");
|
||||
exit (-1);
|
||||
}
|
||||
compile_constants_add((constant) {
|
||||
|
|
|
@ -65,12 +65,12 @@ void typedef_clear() {
|
|||
}
|
||||
}
|
||||
|
||||
int typedef_add(const char *from, const char *to) {
|
||||
int typedef_add(struct lex_file *file, const char *from, const char *to) {
|
||||
unsigned int hash = typedef_hash(to);
|
||||
typedef_node *find = typedef_table[hash];
|
||||
|
||||
if (find)
|
||||
return error(ERROR_PARSE, "typedef for %s already exists or conflicts\n", to);
|
||||
return error(file, ERROR_PARSE, "typedef for %s already exists or conflicts\n", to);
|
||||
|
||||
/* check if the type exists first */
|
||||
if (strncmp(from, "float", sizeof("float")) == 0 ||
|
||||
|
@ -91,5 +91,5 @@ int typedef_add(const char *from, const char *to) {
|
|||
return -100;
|
||||
}
|
||||
}
|
||||
return error(ERROR_PARSE, "cannot typedef `%s` (not a type)\n", from);
|
||||
return error(file, ERROR_PARSE, "cannot typedef `%s` (not a type)\n", from);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue