From 65c54a8986b3519c1949d280e58f46af2eceff85 Mon Sep 17 00:00:00 2001 From: exegete Date: Sat, 17 Oct 2020 16:40:23 +0300 Subject: float, constants, ets --- smack.c | 579 ---------------------------------------------------------------- 1 file changed, 579 deletions(-) delete mode 100644 smack.c (limited to 'smack.c') diff --git a/smack.c b/smack.c deleted file mode 100644 index f6f9f30..0000000 --- a/smack.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - Simple Macro Generator - created by exegete -*/ - -#include -#include -#include - -struct macro -{ - const char *lexem; - unsigned long long param_count; - const char *text; - struct macro *next; -}; - -struct macro_parameter -{ - char *lexem; - struct macro_parameter *next; -}; - -struct input_stream -{ - FILE *fd; - const struct macro *macro; - unsigned long long text_offset; - struct macro_parameter *param_list; - struct input_stream *next; -}; - -struct module -{ - const char *file_name; - struct module *next; -}; - -#define ERROR_STATUS_ARG 1 -#define ERROR_STATUS_OPEN 2 -#define ERROR_STATUS_CHDIR 3 -#define ERROR_STATUS_MALLOC 4 -#define ERROR_STATUS_EMPTY_STREAM_LIST 5 -#define ERROR_STATUS_INVALID_STREAM 6 -#define ERROR_STATUS_INVALID_MACRO 7 -#define ERROR_STATUS_INVALID_PARAMETER 8 -#define ERROR_STATUS_INVALID_CALL 9 -#define ERROR_STATUS_INVALID_INCLUDE 10 -#define ERROR_STATUS_INVALID_SHIELD 11 - -const char *error_msgs[] = -{ - "Please, specify input file", - "Unable to open file: ", - "Unable to change working directory: ", - "Unable to allocate memory", - "Input stream list is empty", - "Input stream is invalid", - "Macro definition is invalid", - "Macro parameter is invalid", - "Macro call is invalid", - "Invalid include/module argument", - "Invalid '#' argument" -}; - -void exit_error(int status, const char *msg) -{ - if(msg) - fprintf(stderr, "Error: %s%s\n", error_msgs[status - 1], msg); - else - fprintf(stderr, "Error: %s\n", error_msgs[status - 1]); - exit(status); -} - -void add_input_stream(struct input_stream **stream_list, - FILE *fd, const struct macro *macro) -{ - struct input_stream *head = *stream_list; - *stream_list = malloc(sizeof(struct input_stream)); - if(!*stream_list) - exit_error(ERROR_STATUS_MALLOC, NULL); - (*stream_list)->fd = fd; - (*stream_list)->macro = macro; - (*stream_list)->text_offset = 0; - (*stream_list)->param_list = NULL; - (*stream_list)->next = head; -} - -int delete_input_stream(struct input_stream **stream_list) -{ - struct input_stream *head = *stream_list; - if(!head) - exit_error(ERROR_STATUS_EMPTY_STREAM_LIST, NULL); - *stream_list = (*stream_list)->next; - if(head->fd) - fclose(head->fd); - while(head->param_list) - { - struct macro_parameter *param_head = head->param_list; - head->param_list = param_head->next; - free(param_head->lexem); - free(param_head); - } - free(head); - return *stream_list != NULL; -} - -void add_input_stream_parameter(struct input_stream *stream_list, char *lexem) -{ - struct macro_parameter **param = &stream_list->param_list; - while(*param) - param = &(*param)->next; - *param = malloc(sizeof(struct macro_parameter)); - if(!*param) - exit_error(ERROR_STATUS_MALLOC, NULL); - (*param)->lexem = lexem; - (*param)->next = NULL; -} - -const char *get_input_stream_parameter(struct input_stream *stream_list, - unsigned long long chosen) -{ - struct macro_parameter *param = stream_list->param_list; - if(!chosen) - return stream_list->macro->lexem; - chosen--; - for(; param && chosen > 0; chosen--) - param = param->next; - if(!param) - exit_error(ERROR_STATUS_INVALID_CALL, NULL); - return param->lexem; -} - -#define BUFFER_INITIAL_SIZE 4 - -int double_buffer(char **buffer, unsigned long long *buffer_size) -{ - char *tmp_pointer = *buffer; - unsigned long long tmp_size = *buffer_size; - - if(*buffer_size == 0) - *buffer_size = BUFFER_INITIAL_SIZE; - else - *buffer_size *= 2; - - *buffer = malloc(*buffer_size); - if(!*buffer) - return 0; - - for(; tmp_size > 0; tmp_size--) - (*buffer)[tmp_size - 1] = tmp_pointer[tmp_size - 1]; - - free(tmp_pointer); - return 1; -} - -int read_symb_from_text(struct input_stream *stream_list) -{ - char symb; - if(!stream_list->macro) - exit_error(ERROR_STATUS_INVALID_STREAM, NULL); - if(!stream_list->macro->text) - exit_error(ERROR_STATUS_INVALID_STREAM, NULL); - symb = stream_list->macro->text[stream_list->text_offset]; - if(!symb) - return EOF; - stream_list->text_offset++; - return symb; -} - -#define COMMENT_SYMB ';' - -int read_real_symb(struct input_stream *stream_list) -{ - int symb; - - if(!stream_list) - exit_error(ERROR_STATUS_EMPTY_STREAM_LIST, NULL); - - if(stream_list->fd) - symb = fgetc(stream_list->fd); - else - symb = read_symb_from_text(stream_list); - - if(symb == COMMENT_SYMB) - { - for(; symb != '\n' && symb != EOF; - symb = fgetc(stream_list->fd)) - {} - } - return symb; -} - -#define SHIELD_SYMB '\\' - -int read_symb(struct input_stream *stream_list, int *shield) -{ - int symb = read_real_symb(stream_list); - if(shield) - { - *shield = 0; - if(symb == SHIELD_SYMB) - { - symb = read_real_symb(stream_list); - *shield = 1; - } - } - return symb; -} - -int is_symb_hex(char symb) -{ - if(symb >= '0' && symb <= '9') - return symb - '0'; - else - if(symb >= 'A' && symb <= 'F') - return symb - 'A' + 10; - else - if(symb >= 'a' && symb <= 'f') - return symb - 'a' + 10; - else - return -1; -} - -int is_lexem_hex(const char *lexem, unsigned long long *dest) -{ - int sign = 0; - unsigned long long hex = 0; - if(*lexem == '-' && *(lexem + 1)) - { - sign = 1; - lexem++; - } - - for(; *lexem; lexem++) - { - int num = is_symb_hex(*lexem); - if(num != -1) - hex = (hex << 4) + num; - else - return 0; - } - hex = sign ? ~hex + 1 : hex; - if(dest) - *dest = hex; - return 1; -} - -int compare_lexems(const char *lexem_one, const char *lexem_two) -{ - for(; *lexem_one && *lexem_two; lexem_one++, lexem_two++) - if(*lexem_one != *lexem_two) - return 0; - return *lexem_one == *lexem_two; -} - -char *copy_lexem(const char *lexem) -{ - char *buffer = NULL; - unsigned long long buffer_size = 0; - unsigned long long index; - - for(index = 0;; index++) - { - if(index == buffer_size) - if(!double_buffer(&buffer, &buffer_size)) - exit_error(ERROR_STATUS_MALLOC, NULL); - buffer[index] = lexem[index]; - if(!lexem[index]) - break; - } - return buffer; -} - -#define EVAL_SYMB '%' - -unsigned long long get_eval_end(const char *lexem) -{ - unsigned long long counter = 0; - - for(; *lexem && *lexem != EVAL_SYMB; lexem++, counter++) - {} - if(!*lexem) - exit_error(ERROR_STATUS_INVALID_CALL, NULL); - return counter; -} - -char *param_eval(struct input_stream *stream_list, char *lexem) -{ - char *input_lexem = lexem; - char *buffer = NULL; - unsigned long long buffer_size = 0; - const char *param = NULL; - unsigned long long index = 0; - - for(;;) - { - char symb = param && *param ? *param : *lexem++; - param = !param || !*param ? NULL : param + 1; - if(symb == EVAL_SYMB) - { - unsigned long long param_offset = get_eval_end(lexem); - unsigned long long param_num; - *(lexem + param_offset) = 0; - if(!is_lexem_hex(lexem, ¶m_num)) - exit_error(ERROR_STATUS_INVALID_CALL, NULL); - lexem += param_offset + 1; - param = get_input_stream_parameter(stream_list, - param_num); - continue; - } - if(index == buffer_size) - if(!double_buffer(&buffer, &buffer_size)) - exit_error(ERROR_STATUS_MALLOC, NULL); - buffer[index] = symb; - if(!symb) - break; - index++; - } - free(input_lexem); - return buffer; -} - -int is_separator(int symb) -{ - return symb == ' ' || symb == '\n' || symb == '\t' || symb == '\r'; -} - -char *read_lexem(struct input_stream *stream_list) -{ - char *buffer = NULL; - unsigned long long buffer_size = 0; - int symb; - int shield; - unsigned long long index; - - for(;;) - { - symb = read_symb(stream_list, &shield); - if(is_separator(symb) && !shield) - continue; - if(symb == EOF) - return NULL; - break; - } - - for(index = 0;; index++) - { - if(index == buffer_size) - if(!double_buffer(&buffer, &buffer_size)) - exit_error(ERROR_STATUS_MALLOC, NULL); - if(symb == EOF || (is_separator(symb) && !shield)) - { - buffer[index] = 0; - break; - } - buffer[index] = symb; - symb = read_symb(stream_list, &shield); - } - buffer = param_eval(stream_list, buffer); - return buffer; -} - -#define MACRO_END_SYMB ']' - -const char *read_macro_text(struct input_stream *stream_list) -{ - char *buffer = NULL; - unsigned long long buffer_size = 0; - unsigned long long index; - - for(index = 0;; index++) - { - int shield; - int symb = read_symb(stream_list, &shield); - if(index == buffer_size) - if(!double_buffer(&buffer, &buffer_size)) - exit_error(ERROR_STATUS_MALLOC, NULL); - if(symb == EOF || (symb == MACRO_END_SYMB && !shield)) - { - buffer[index] = 0; - break; - } - buffer[index] = symb; - } - return buffer; -} - -void create_macro(struct input_stream *stream_list, struct macro **macro_list) -{ - char *param_count_lexem; - struct macro *head = *macro_list; - *macro_list = malloc(sizeof(struct macro)); - if(!*macro_list) - exit_error(ERROR_STATUS_MALLOC, NULL); - (*macro_list)->lexem = read_lexem(stream_list); - if(!(*macro_list)->lexem) - exit_error(ERROR_STATUS_INVALID_MACRO, NULL); - param_count_lexem = read_lexem(stream_list); - if(!param_count_lexem || !is_lexem_hex(param_count_lexem, - &(*macro_list)->param_count)) - exit_error(ERROR_STATUS_INVALID_MACRO, NULL); - free(param_count_lexem); - (*macro_list)->text = read_macro_text(stream_list); - (*macro_list)->next = head; -} - -int find_module(struct module *module_list, const char *file_name) -{ - for(; module_list; module_list = module_list->next) - if(compare_lexems(module_list->file_name, file_name)) - return 1; - return 0; -} - -void add_module(struct module **module_list, const char *file_name) -{ - struct module *head = *module_list; - *module_list = malloc(sizeof(struct module)); - if(!*module_list) - exit_error(ERROR_STATUS_MALLOC, NULL); - (*module_list)->file_name = file_name; - (*module_list)->next = head; -} - -void include_file(struct input_stream **stream_list, - struct module **module_list) -{ - char *file_name = read_lexem(*stream_list); - FILE *fd; - if(!file_name) - exit_error(ERROR_STATUS_INVALID_INCLUDE, NULL); - if(module_list && find_module(*module_list, file_name)) - { - free(file_name); - return; - } - fd = fopen(file_name, "r"); - if(!fd) - exit_error(ERROR_STATUS_OPEN, file_name); - if(module_list) - add_module(module_list, file_name); - else - free(file_name); - add_input_stream(stream_list, fd, NULL); -} - -void push_parameter(struct input_stream *input_stream, - struct input_stream *actual_stream) -{ - char *lexem = read_lexem(input_stream); - if(!lexem) - exit_error(ERROR_STATUS_INVALID_PARAMETER, NULL); - add_input_stream_parameter(actual_stream, lexem); -} - -int find_macro(struct input_stream **stream_list, struct macro *macro_list, - const char *lexem) -{ - for(; macro_list; macro_list = macro_list->next) - { - if(compare_lexems(macro_list->lexem, lexem)) - { - struct input_stream *old_stream = *stream_list; - unsigned long long param_count = - macro_list->param_count; - add_input_stream(stream_list, NULL, macro_list); - for(; param_count > 0; param_count--) - push_parameter(old_stream, *stream_list); - return 1; - } - } - return 0; -} - -#define DIRECTORY_SEPARATOR_SYMB '/' - -unsigned long long find_last_dir_separator_pos(const char *file_name) -{ - const char *orig_file_name = file_name; - unsigned long long pos = 0; - for(; *file_name; file_name++) - if(*file_name == DIRECTORY_SEPARATOR_SYMB) - pos = file_name - orig_file_name; - return pos; -} - -void initialize_stream(struct input_stream **stream_list, - const char *file_name) -{ - char *dir_path = copy_lexem(file_name); - unsigned long long dir_sep_pos = find_last_dir_separator_pos(dir_path); - FILE *fd = fopen(file_name, "r"); - if(!fd) - exit_error(ERROR_STATUS_OPEN, file_name); - add_input_stream(stream_list, fd, NULL); - if(dir_sep_pos) - { - dir_path[dir_sep_pos] = 0; - if(chdir(dir_path) == -1) - exit_error(ERROR_STATUS_CHDIR, NULL); - } - free(dir_path); -} - -void print_lexem(const char *lexem) -{ - printf("%s ", lexem); -} - -#define MACRO_SHIELD_LEXEM "#" -#define MACRO_START_LEXEM "[" -#define MACRO_INCLUDE_LEXEM "include" -#define MACRO_MODULE_LEXEM "module" -#define MACRO_LIT_LEXEM "literal" - -int main(int argc, char **argv) -{ - struct input_stream *stream_list = NULL; - struct macro *macro_list = NULL; - struct module *module_list = NULL; - char *lexem; - - if(argc <= 1) - exit_error(ERROR_STATUS_ARG, NULL); - else - initialize_stream(&stream_list, argv[1]); - - for(;; free(lexem)) - { - lexem = read_lexem(stream_list); - if(!lexem) - { - if(delete_input_stream(&stream_list)) - continue; - else - break; - } - if(compare_lexems(lexem, MACRO_SHIELD_LEXEM)) - { - free(lexem); - lexem = read_lexem(stream_list); - if(!lexem) - exit_error(ERROR_STATUS_INVALID_SHIELD, NULL); - print_lexem(lexem); - continue; - } - if(compare_lexems(lexem, MACRO_START_LEXEM)) - { - create_macro(stream_list, ¯o_list); - continue; - } - if(compare_lexems(lexem, MACRO_INCLUDE_LEXEM)) - { - include_file(&stream_list, NULL); - continue; - } - if(compare_lexems(lexem, MACRO_MODULE_LEXEM)) - { - include_file(&stream_list, &module_list); - continue; - } - if(is_lexem_hex(lexem, NULL)) - { - if(find_macro(&stream_list, macro_list, - MACRO_LIT_LEXEM)) - { - add_input_stream_parameter(stream_list, - copy_lexem(lexem)); - continue; - } - } - if(find_macro(&stream_list, macro_list, lexem)) - continue; - print_lexem(lexem); - } - - return 0; -} -- cgit v1.2.3