272 lines
9.7 KiB
C
Executable File
272 lines
9.7 KiB
C
Executable File
/// __ ___ __ ___ ___ ___ ___ ___ ___ _ __
|
|
/// \ \/ / '__/ _ \ / __/ _ \/ __/ __|/ _ \| '__|
|
|
/// > <| | | (_) | (_| __/\__ \__ \ (_) | |
|
|
/// /_/\_\_| \___/ \___\___||___/___/\___/|_|
|
|
///
|
|
/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
|
|
///
|
|
/// xolatile@chud.cyou - xrocessor - Probably the most minimalistic general preprocessor aimed at EAXHLA language syntax.
|
|
///
|
|
/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
|
|
/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
|
|
///
|
|
/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
|
|
/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
|
|
/// for more details, if you dare, it is a lot of text that nobody wants to read...
|
|
|
|
static natural processor_parse_comment (character * buffer);
|
|
static natural processor_parse_include (character * buffer);
|
|
static natural processor_parse_use (character * buffer);
|
|
static natural processor_parse_alias (character * buffer);
|
|
static natural processor_parse_macro (character * buffer);
|
|
static natural processor_parse_scope (character * buffer);
|
|
static natural processor_parse_unscope (character * buffer);
|
|
static natural processor_parse_default (character * buffer);
|
|
|
|
static procedure processor_parse_buffer (character * buffer, natural limit);
|
|
|
|
typedef enum {
|
|
processor_token_comment, processor_token_include, processor_token_use, processor_token_alias,
|
|
processor_token_macro, processor_token_scope, processor_token_unscope, processor_token_default,
|
|
processor_token_count
|
|
} processor_token_enumeration;
|
|
|
|
static character * processor_token_key [processor_token_count - 1] = {
|
|
"---", "include ", "use ", "alias ", "macro ", "scope ", "unscope "
|
|
};
|
|
|
|
static natural (* processor_parse_key [processor_token_count]) (character * buffer) = {
|
|
processor_parse_comment, processor_parse_include, processor_parse_use, processor_parse_alias,
|
|
processor_parse_macro, processor_parse_scope, processor_parse_unscope, processor_parse_default
|
|
};
|
|
|
|
typedef struct {
|
|
natural count;
|
|
natural limit;
|
|
character * * token_array_data;
|
|
natural * token_array_size;
|
|
natural * token_array_type;
|
|
} processor_structure;
|
|
|
|
static natural processor_parse_default (character * buffer) {
|
|
for (natural select = 0; select < token_count; ++select) {
|
|
if (string_compare_limit (buffer, token_array [select]->data, token_array [select]->size) == true) {
|
|
if (token_array [select]->type == token_alias) {
|
|
if (character_is_separator (buffer [-1]) == false) continue;
|
|
if (character_is_separator (buffer [token_array [select]->size]) == false) continue;
|
|
|
|
output (token_value [select]->data, token_value [select]->size);
|
|
|
|
return (token_array [select]->size);
|
|
}
|
|
|
|
if (token_array [select]->type == token_macro) {
|
|
if (character_is_separator (buffer [-1]) == false) continue;
|
|
if (character_is_separator (buffer [token_array [select]->size]) == false) continue;
|
|
|
|
processor_parse_buffer (token_value [select]->data, token_value [select]->size);
|
|
|
|
return (token_array [select]->size);
|
|
}
|
|
}
|
|
}
|
|
|
|
output (buffer, 1);
|
|
|
|
return (1);
|
|
}
|
|
|
|
static natural processor_parse_comment (character * buffer) {
|
|
for (natural offset = 3; buffer [offset] != '\0'; ++offset) {
|
|
if (buffer [offset] == '\n') break;
|
|
}
|
|
|
|
return (offset + 1);
|
|
}
|
|
|
|
static natural processor_parse_use (character * buffer) {
|
|
natural length = 0;
|
|
|
|
for (natural offset = 4; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
++token_count;
|
|
|
|
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
|
|
|
|
token_array [token_count - 1]->data = & buffer [offset];
|
|
token_array [token_count - 1]->type = token_use;
|
|
|
|
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
|
|
|
|
token_array [token_count - 1]->size = length;
|
|
|
|
return (offset + length + 1);
|
|
}
|
|
|
|
static natural processor_parse_include (character * buffer) {
|
|
natural length = 0;
|
|
natural offset = 0;
|
|
character * data = null;
|
|
|
|
for (offset = 8; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
fatal_failure (buffer [offset] != '"', "processor_parse_include: Not a string.");
|
|
|
|
++token_count;
|
|
|
|
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
|
|
|
|
token_array [token_count - 1]->data = & buffer [offset + 1];
|
|
token_array [token_count - 1]->type = token_include;
|
|
|
|
for (length = 1; (buffer [offset + length] != '\0') && (buffer [offset + length] != '"'); ++length);
|
|
|
|
token_array [token_count - 1]->size = length - 1;
|
|
|
|
data = arena_add_file (token_array [token_count - 1]->data, token_array [token_count - 1]->size);
|
|
|
|
processor_parse_buffer (data, -1);
|
|
|
|
return (offset + length + 1);
|
|
}
|
|
|
|
static natural processor_parse_alias (character * buffer) {
|
|
natural offset = 0;
|
|
natural length = 0;
|
|
|
|
for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
++token_count;
|
|
|
|
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
|
|
token_value [token_count - 1] = arena_add (sizeof (* * token_value));
|
|
|
|
token_array [token_count - 1]->data = & buffer [offset];
|
|
token_array [token_count - 1]->type = token_alias;
|
|
|
|
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
|
|
|
|
token_array [token_count - 1]->size = length;
|
|
|
|
for (offset += length; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
token_value [token_count - 1]->data = & buffer [offset];
|
|
token_value [token_count - 1]->type = token_alias;
|
|
|
|
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
|
|
|
|
token_value [token_count - 1]->size = length;
|
|
|
|
return (offset + length + 1);
|
|
}
|
|
|
|
static natural processor_parse_macro (character * buffer) {
|
|
natural offset = 0;
|
|
natural length = 0;
|
|
|
|
for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
++token_count;
|
|
|
|
token_array [token_count - 1] = arena_add (sizeof (* * token_array));
|
|
token_value [token_count - 1] = arena_add (sizeof (* * token_value));
|
|
|
|
token_array [token_count - 1]->data = & buffer [offset];
|
|
token_array [token_count - 1]->type = token_macro;
|
|
|
|
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
|
|
|
|
token_array [token_count - 1]->size = length;
|
|
|
|
for (offset += length; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
token_value [token_count - 1]->data = & buffer [offset];
|
|
token_value [token_count - 1]->type = token_macro;
|
|
|
|
for (length = 0; buffer [offset + length] != '\0'; ++length) {
|
|
if (string_compare_limit (& buffer [offset + length], "end macro", 9) == true) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
token_value [token_count - 1]->size = length;
|
|
|
|
return (offset + length + 9 + 1);
|
|
}
|
|
|
|
static natural processor_parse_scope (character * buffer) {
|
|
natural offset = 0;
|
|
natural length = 0;
|
|
natural select = 0;
|
|
|
|
for (offset = 6; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
|
|
|
|
for (select = 0; select < token_count; ++select) {
|
|
if ((string_compare_limit (token_array [select]->data, & buffer [offset], length) == true) && (token_array [select]->type == token_use)) {
|
|
for (; buffer [offset + length] != '\0'; ++length) {
|
|
if (string_compare_limit (& buffer [offset + length], "end scope", 9) == true) {
|
|
return (offset + length + 9 + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return (offset + length + 1);
|
|
}
|
|
|
|
static natural processor_parse_unscope (character * buffer) {
|
|
natural offset = 0;
|
|
natural length = 0;
|
|
natural select = 0;
|
|
|
|
for (offset = 8; (buffer [offset] != '\0') && (character_is_blank (buffer [offset]) == true); ++offset);
|
|
|
|
for (length = 0; (buffer [offset + length] != '\0') && (character_is_blank (buffer [offset + length]) == false); ++length);
|
|
|
|
for (select = 0; select < token_count; ++select) {
|
|
if ((string_compare_limit (token_array [select]->data, & buffer [offset], length) == true) && (token_array [select]->type == token_use)) {
|
|
return (offset + length + 1);
|
|
}
|
|
}
|
|
|
|
for (; buffer [offset + length] != '\0'; ++length) {
|
|
if (string_compare_limit (& buffer [offset + length], "end unscope", 11) == true) {
|
|
return (offset + length + 11 + 1);
|
|
}
|
|
}
|
|
|
|
return (offset + length + 1);
|
|
}
|
|
|
|
static procedure processor_parse_buffer (character * buffer, natural limit) {
|
|
for (natural length = 0, offset = 0; (buffer [offset] != '\0') && (offset != limit); offset += length) {
|
|
natural select = 0;
|
|
|
|
for (select = 0; select < token_default; ++select) {
|
|
length = string_length (token_key [select]);
|
|
if (string_compare_limit (& buffer [offset], token_key [select], length) == true) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (string_compare_limit (& buffer [offset], "end macro", 9) == true) {
|
|
length = 9;
|
|
continue;
|
|
}
|
|
|
|
if (string_compare_limit (& buffer [offset], "end scope", 9) == true) {
|
|
length = 9;
|
|
continue;
|
|
}
|
|
|
|
if (string_compare_limit (& buffer [offset], "end unscope", 11) == true) {
|
|
length = 11;
|
|
continue;
|
|
}
|
|
|
|
length = processor_parse_key [select] (& buffer [offset]);
|
|
}
|
|
}
|