diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d535e3a..0000000 --- a/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.out -*~ -*.swp -*.o -*.a -*.so -*.class -*.log -*.core -minimake/minimake diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index d5e33a8..0000000 --- a/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -guillem.george - -Special thanks to - -- Timothée Battefort for the parser -- Amadéo Heaulme for the error handling diff --git a/Makefile b/Makefile deleted file mode 100644 index db29234..0000000 --- a/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -CC = gcc -CFLAGS = -std=c99 -pedantic -Werror -Wall -Wextra -Wvla -LDFLAGS= - -DBG_CFLAGS = -fsanitize=address -g -DBG_LDFLAGS= -fsanitize=address - - -SRC_DIR = src -LIB_SRCS = lines/lines.c hash_maps/hash_maps.c lists/lists.c files/files.c -MAIN_SRCS = main.c minimake.c - -# SRCS = $(patsubst %,$(SRC_DIR)/%, $(MAIN_SRCS)) -SRCS = $(MAIN_SRCS:%=$(SRC_DIR)/%) $(LIB_SRCS:%=$(SRC_DIR)/%) -OBJS = $(SRCS:.c=.o) - -TARGET= minimake -# DBG_TARGET = minimake-dbg - -$(TARGET): $(OBJS) - $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) - @echo $(OBJS) - -debug: CFLAGS += $(DBG_CFLAGS) -debug: LDFLAGS += $(DBG_LDFLAGS) -debug: $(OBJS) - $(CC) -o $(TARGET) $^ $(LDFLAGS) $(LDLIBS) - -check: - dash ./tests/run.sh - -clean: - $(RM) $(TARGET) - $(RM) $(OBJS) diff --git a/README.md b/README.md deleted file mode 100644 index 7cc185b..0000000 --- a/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# Minimake - -Minimake is a small project written in about a week in C99. Its goal was to reproduce the main features of the well known GNU Make utility. - -> **Note** This is a school project, therefore it probably won't interest you if you are looking for something useful. - -## Build - -```sh -make -``` -or even better -```sh -minimake -``` - -## How it works - -If you're not familiar with Make, what it does is that it reads a file named -`Makefile` in the current directory which contains instructions to build a -project in the form of recipes. It includes support for variables, dependencies -, implicit rules and more. - -Then depending on the user input it automatically executes a recipe with its dependencies. - - -Here is what a basic one can look like -```make -BENCH_FLAGS = --all - -test_and_bench: - bash ./runtests.sh - bash ./runbenchs.sh $(BENCH_FLAGS) -``` - -But it will more realisticly look like that - -```make -CC = gcc -CFLAGS = -std=c99 -pedantic -Werror -Wall -Wextra -Wvla -LDFLAGS= - -DBG_CFLAGS = -fsanitize=address -g -DBG_LDFLAGS= -fsanitize=address - - -SRC_DIR = src -LIB_SRCS = lines/lines.c hash_maps/hash_maps.c lists/lists.c files/files.c -MAIN_SRCS = main.c minimake.c - -SRCS = $(MAIN_SRCS:%=$(SRC_DIR)/%) $(LIB_SRCS:%=$(SRC_DIR)/%) -OBJS = $(SRCS:.c=.o) - -TARGET= minimake -DBG_TARGET = minimake-dbg - -$(TARGET): $(OBJS) - $(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS) - @echo $(OBJS) - -debug: CFLAGS += $(DBG_CFLAGS) -debug: LDFLAGS += $(DBG_LDFLAGS) -debug: $(OBJS) - $(CC) -o $(DBG_TARGET) $^ $(LDFLAGS) $(LDLIBS) - -check: - dash ./tests/run.sh - -clean: - $(RM) $(TARGET) - $(RM) $(OBJS) - -``` diff --git a/microshell/a.out b/microshell/a.out new file mode 100755 index 0000000..a27d743 Binary files /dev/null and b/microshell/a.out differ diff --git a/microshell/microshell.c b/microshell/microshell.c new file mode 100644 index 0000000..72dbf99 --- /dev/null +++ b/microshell/microshell.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + if (argc < 2) + errx(1, "Not enough args"); + + int id = fork(); + if (id < 0) + errx(1, "Cannot fork"); + + if (id == 0) + { + int res = 0; + wait(&res); + return res; + } + else + { + int res = execl("/bin/sh", "supershell", "-c", argv[1], NULL); + exit(res); + } +} diff --git a/src/files/files.c b/src/files/files.c deleted file mode 100644 index b27627d..0000000 --- a/src/files/files.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "files.h" - -#include -#include -#include -#include -#include - -// #include "../lines/lines.h" - -char *get_makefile(struct list *files) -{ - struct list *file = files; - int found = 0; - - // Test file presence - while (file != NULL && !found) - { - FILE *test = fopen(file->data, "r"); - if (test != NULL) - { - fclose(test); - found = 1; - } - else - { - file = file->next; - } - } - - char *res = NULL; - if (found) - res = file->data; - - return res; -} - -ssize_t get_file_lastmodiftime(char *filename) -{ - struct stat stat; - if (lstat(filename, &stat) == -1) - return -1; - return stat.st_mtime; -} - -// Calls a shell that will run the given command -// It will first print the command to run unless the it starts with '@' -// Returns the return code o the command or -1 if a syscall fails -int run_command(char *command) -{ - if (command[0] == '@') - command++; - else - { - puts(command); - } - - // Just in case - fflush(stdout); - fflush(stderr); - - int id = fork(); - if (id < 0) - { - perror("fork"); - return -1; - } - - if (id == 0) - { - int res = execl("/bin/sh", "(make)", "-c", command, NULL); - exit(res); - } - else - { - int res = 0; - wait(&res); - return res; - } -} - -// Returns 1 if file exists (and is readable), 0 otherwise -int file_exists(char *filename) -{ - if (filename == NULL) - return 0; - - FILE *test = fopen(filename, "r"); - if (test == NULL) - return 0; - - fclose(test); - return 1; -} diff --git a/src/files/files.h b/src/files/files.h deleted file mode 100644 index d4893c3..0000000 --- a/src/files/files.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef FILES_H -#define FILES_H - -#define _XOPEN_SOURCE 500 - -#include - -#include "../lists/lists.h" - -char *get_makefile(struct list *files); -ssize_t get_file_lastmodiftime(char *filename); -int run_command(char *command); -int file_exists(char *filename); - -#endif // FILES_H diff --git a/src/hash_maps/hash_maps.c b/src/hash_maps/hash_maps.c deleted file mode 100644 index 405a0f9..0000000 --- a/src/hash_maps/hash_maps.c +++ /dev/null @@ -1,177 +0,0 @@ -#include "hash_maps.h" - -#include -#include -#include -#include -#include - -/* -** Hash the key using FNV-1a 32 bits hash algorithm. -*/ -size_t hash(const char *key) -{ - if (!key) - return 0; - - uint32_t hash = 2166136261; // FNV offset basis - uint32_t prime = 16777619; // FNV prime - - while (*key) - { - hash ^= *key; - hash *= prime; - key++; - } - - return hash; -} - -struct hash_map *hashmap_init(size_t size) -{ - struct pair_list **data = calloc(size, sizeof(struct pair_list)); - struct hash_map *map = malloc(sizeof(struct hash_map)); - map->data = data; - map->size = size; - return map; -} - -bool hashmap_insert(struct hash_map *hash_map, char *key, void *value, - bool *updated) -{ - if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0) - { - if (updated) - *updated = false; - return false; - } - - // Insert into hashmap (head) - - size_t entry_hash = hash(key) % hash_map->size; - // Search if key is already present - struct pair_list *elt = hash_map->data[entry_hash]; - while (elt != NULL) - { - if (strcmp(elt->key, key) == 0) - { - elt->value = value; - if (updated) - *updated = true; - return true; - } - elt = elt->next; - } - - // Create entry - struct pair_list *new_entry = malloc(sizeof(struct pair_list)); - if (new_entry == NULL) - return false; - new_entry->key = key; - new_entry->value = value; - - new_entry->next = hash_map->data[entry_hash]; - hash_map->data[entry_hash] = new_entry; - - if (updated) - *updated = false; - - return true; -} - -void hashmap_free(struct hash_map *hash_map) -{ - if (hash_map == NULL) - return; - if (hash_map->data == NULL) - return; - - for (size_t i = 0; i < hash_map->size; i++) - { - struct pair_list *entry = hash_map->data[i]; - while (entry != NULL) - { - struct pair_list *next = entry->next; - free(entry); - entry = next; - } - } - free(hash_map->data); - free(hash_map); -} - -// WARNING -// Will only work with string values -// DO NOT attempt to call it with anything else -void hashmap_dump(struct hash_map *hash_map) -{ - for (size_t i = 0; i < hash_map->size; i++) - { - struct pair_list *entry = hash_map->data[i]; - bool is_null = true; - if (entry != NULL) - { - is_null = false; - char *val = entry->value; - printf("%s: %s", entry->key, val); - entry = entry->next; - } - while (entry != NULL) - { - char *val = entry->value; - printf(", %s: %s", entry->key, val); - entry = entry->next; - } - if (!is_null) - putchar('\n'); - } -} - -void *hashmap_get(const struct hash_map *hash_map, char *key) -{ - if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0) - return NULL; - - size_t entry_hash = hash(key) % hash_map->size; - struct pair_list *entry = hash_map->data[entry_hash]; - while (entry != NULL && strcmp(entry->key, key) != 0) - { - entry = entry->next; - } - if (entry == NULL) - return NULL; - - return entry->value; -} - -bool hashmap_remove(struct hash_map *hash_map, char *key) -{ - if (hash_map == NULL || hash_map->size == 0 || hash_map->data == NULL) - return false; - - size_t entry_hash = hash(key) % hash_map->size; - struct pair_list *entry = hash_map->data[entry_hash]; - - if (entry == NULL) - return false; - if (strcmp(entry->key, key) == 0) - { - hash_map->data[entry_hash] = entry->next; - free(entry); - return true; - } - - if (entry->next == NULL) - return false; - while (strcmp(entry->next->key, key) != 0) - { - entry = entry->next; - if (entry->next == NULL) - return false; - } - - struct pair_list *elt_to_free = entry->next; - entry->next = entry->next->next; - free(elt_to_free); - return true; -} diff --git a/src/hash_maps/hash_maps.h b/src/hash_maps/hash_maps.h deleted file mode 100644 index 634c993..0000000 --- a/src/hash_maps/hash_maps.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HASH_MAPS_H -#define HASH_MAPS_H - -#include -#include - -// WARNING I made the choice to discard the const qualifier of the key argument -// To add the possibility to free it. -// Note that key should *NEVER* be changed once it has been added to the hashmap - -struct pair_list -{ - char *key; - void *value; - struct pair_list *next; -}; - -struct hash_map -{ - struct pair_list **data; - size_t size; -}; - -size_t hash(const char *str); -struct hash_map *hashmap_init(size_t size); -bool hashmap_insert(struct hash_map *hash_map, char *key, void *value, - bool *updated); -void hashmap_free(struct hash_map *hash_map); -void hashmap_dump(struct hash_map *hash_map); -void *hashmap_get(const struct hash_map *hash_map, char *key); -bool hashmap_remove(struct hash_map *hash_map, char *key); - -#endif /* ! HASH_MAPS_H */ diff --git a/src/lines/lines.c b/src/lines/lines.c deleted file mode 100644 index 238b576..0000000 --- a/src/lines/lines.c +++ /dev/null @@ -1,263 +0,0 @@ -#include "lines.h" - -#include -#include -#include -#include -#include -#include - -#include "../minimake.h" - -// Helps to match a string (excludes blanks and special characters) -int ischar(char c) -{ - return c != '\0' && !isblank(c) && c != ':' && c != '=' && c != '#' - && c != '\n'; -} - -int skipblanks(char *buf, size_t buf_len) -{ - size_t i = 0; - while (i < buf_len && (isblank(buf[i]) || buf[i] == '\n')) - i++; - return i; -} - -// Returns 1 if line is blank -int isblankline(struct line *l) -{ - size_t line_size = l->length; - char *buf = l->buffer; - - size_t i = 0; - while (i < line_size) - { - if (!isblank(buf[i]) && buf[i] != '\n') - return 0; - if (buf[i] == '#') // Comments - return 1; - i++; - } - return 1; -} - -// Returns the next word from buf until buf_len, -// and the numbers of read characters in *read_chars -// WARNING allocates the result on the heap -size_t readword(char *buf, size_t buf_len, char **word) -{ - size_t i = 0; - size_t res_size = STRING_BUFFER_SIZE; - char *res = malloc(sizeof(char) * res_size); - while (i < buf_len && ischar(buf[i])) - { - // Reallocate more space if necessary - resize_buf(&res, res_size, i); - - res[i] = buf[i]; - i++; - } - res[i] = '\0'; - - if (i == 0) - { - free(res); - *word = NULL; - return i; - } - - *word = res; - return i; -} - -// Resizes buf if index is greater or equal than buf_size-1 -// Returns new buffer size -size_t resize_buf(char **buf, size_t buf_size, size_t index) -{ - if (index >= buf_size - 1) - { - buf_size += BUFFER_SIZE; - *buf = realloc(*buf, buf_size); - if (buf == NULL) - drop(2, "Could not realloc"); - } - return buf_size; -} - -// Inserts str into base at index and returns the resulting string -// WARNING allocates the result on the heap, do not forget to free it -char *insert_str(char *base, char *str, size_t index) -{ - size_t res_size = BUFFER_SIZE; - char *res = malloc(res_size * sizeof(char)); - if (res == NULL) - drop(GENERIC_ERR, "Could not allocate more memory"); - - // Copy until index - size_t i = 0; - while (i < index) - { - // Reallocate more space if necessary - res_size = resize_buf(&res, res_size, i); - - res[i] = base[i]; - i++; - } - - // Copy str - size_t str_i = 0; - while (str[str_i] != '\0') - { - // Reallocate more space if necessary - res_size = resize_buf(&res, res_size, i); - - res[i] = str[str_i]; - i++; - str_i++; - } - - // Copy rest - while (base[i] != '\0') - { - // Reallocate more space if necessary - res_size = resize_buf(&res, res_size, i); - - res[i] = base[i]; - i++; - } - - res[i] = '\0'; - return res; -} - -// Appends str into base at index and stores the resulting string in *result -// Returns the size of the resulting buffer -// WARNING allocates the result on the heap, do not forget to free it -size_t append_str(char *base, char *str, size_t index, char **result) -{ - size_t res_size = BUFFER_SIZE; - char *res = malloc(res_size * sizeof(char)); - if (res == NULL) - drop(GENERIC_ERR, "Could not allocate more memory"); - - // Copy until index - size_t i = 0; - while (i < index) - { - // Reallocate more space if necessary - res_size = resize_buf(&res, res_size, i); - - res[i] = base[i]; - i++; - } - - // Copy str - size_t str_i = 0; - while (str[str_i] != '\0') - { - // Reallocate more space if necessary - res_size = resize_buf(&res, res_size, i); - - res[i] = str[str_i]; - i++; - str_i++; - } - res[i] = '\0'; - - *result = res; - return res_size; -} - -// Read word until ':', '=' and blanks and expands variable if any is found -// Returns the number of skipped chars and stores the resulting string in word -size_t read_declaration(struct line *line, size_t index, char **word) -{ - size_t i = index; - size_t buf_len = line->length; - char *buf = line->buffer; - - size_t res_size = STRING_BUFFER_SIZE; - char *res = malloc(sizeof(char) * res_size); - if (res == NULL) - drop(GENERIC_ERR, "Could not allocate more memory"); - - size_t res_i = 0; - while (i < buf_len && ischar(buf[i])) - { - // Reallocate more space if necessary - res_size = resize_buf(&res, res_size, i); - - // Expand variable - if (buf[i] == '$') - { - char *expanded_var; - char *tmp_res_buf; - i += expand_variable(line, i + 1, &expanded_var); - res_size = append_str(res, expanded_var, i, &tmp_res_buf); - // Replace res with res + expanded_variable - res_i = strlen(tmp_res_buf); - free(res); - // free(expanded_var); - res = tmp_res_buf; - continue; - } - - res[res_i] = buf[i]; - i++; - res_i++; - } - res[res_i] = '\0'; - - if (i == index) - { - free(res); - *word = NULL; - return i - index; - } - - *word = res; - return i - index; -} - -// Takes a string, expands its variables and returns the resulting buffer -// WARNING allocates the result on the heap, free result after use -char *expand_str(char *str) -{ - size_t str_i = 0; - size_t buf_i = 0; - size_t buf_size = BUFFER_SIZE; - char *buf = malloc(BUFFER_SIZE * sizeof(char)); - while (str[str_i] != '\0') - { - // Reallocate more space if necessary - resize_buf(&buf, buf_size, buf_i); - - // Expand variable - if (buf[buf_i] == '$') - { - // Temporary variables - char *expanded_var; - char *tmp_res_buf; - struct line false_line = { - .buffer = buf, .file_stream = NULL, .length = 0, .number = 0 - }; - str_i += expand_variable(&false_line, str_i + 1, &expanded_var); - buf_size = append_str(buf, expanded_var, buf_i, &tmp_res_buf); - // Replace buf with buf + expanded_variable - buf_i = strlen(tmp_res_buf); - free(buf); - // free(expanded_var); - buf = tmp_res_buf; - continue; - } - - buf[buf_i] = str[str_i]; - buf_i++; - str_i++; - } - - buf[buf_i] = '\0'; - - return buf; -} diff --git a/src/lines/lines.h b/src/lines/lines.h deleted file mode 100644 index 5782327..0000000 --- a/src/lines/lines.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LINES_H -#define LINES_H - -#define STRING_BUFFER_SIZE 32 - -#include -#include -#include - -// Holds line information -// Exists only because of EPITA's annoying 4 parameters limit -// WARNING buffer must be freed after use -struct line -{ - char *buffer; // Line content - ssize_t length; // Line length - size_t number; // Line number in file - FILE *file_stream; // Full file stream -}; - -int ischar(char c); -int isblankline(struct line *l); -int skipblanks(char *buf, size_t buf_len); -size_t readword(char *buf, size_t buf_len, char **word); -size_t resize_buf(char **buf, size_t buf_size, size_t index); -char *insert_str(char *base, char *str, size_t index); -size_t read_declaration(struct line *line, size_t index, char **word); -size_t append_str(char *base, char *str, size_t index, char **res); - -#endif // LINES_H diff --git a/src/lists/lists.c b/src/lists/lists.c deleted file mode 100644 index e8a681b..0000000 --- a/src/lists/lists.c +++ /dev/null @@ -1,346 +0,0 @@ -#include "lists.h" - -#include -#include -#include - -struct list *list_prepend(struct list *list, void *value) -{ - struct list *new_elt = malloc(sizeof(struct list)); - if (new_elt == NULL) - { - return NULL; - } - new_elt->next = list; - new_elt->data = value; - - return new_elt; -} - -size_t list_length(struct list *list) -{ - size_t len = 0; - while (list != NULL) - { - len++; - list = list->next; - } - return len; -} - -// void list_print(struct list *list) -// { -// if (list == NULL) -// { -// return; -// } - -// while (list != NULL) -// { -// if (list->next != NULL) -// { -// printf("%p ", list->data); -// } -// else -// { -// printf("%p\n", list->data); -// } -// list = list->next; -// } -// } - -void list_destroy(struct list *list) -{ - struct list *elt = list; - struct list *next_elt; - while (elt != NULL) - { - next_elt = elt->next; - free(elt); - elt = next_elt; - } -} - -struct list *list_append(struct list *list, void *value) -{ - if (list == NULL) - { - struct list *new_elt = malloc(sizeof(struct list)); - new_elt->data = value; - new_elt->next = NULL; - return new_elt; - } - - struct list *elt = list; - - while (elt->next != NULL) - { - elt = elt->next; - } - - struct list *new_elt = malloc(sizeof(struct list)); - new_elt->data = value; - new_elt->next = NULL; - elt->next = new_elt; - - return list; -} - -/* - * - ******************* - * Advanced * - ******************* - * - */ - -struct list *list_insert(struct list *list, void *value, size_t index) -{ - if (list == NULL || index == 0) - { - struct list *new_elt = malloc(sizeof(struct list)); - new_elt->data = value; - new_elt->next = list; - return new_elt; - } - - struct list *elt = list; - - for (size_t i = 0; i < index - 1; i++) - { - if (elt->next == NULL) - { - break; - } - elt = elt->next; - } - - struct list *new_elt = malloc(sizeof(struct list)); - new_elt->data = value; - new_elt->next = elt->next; - elt->next = new_elt; - - return list; -} - -struct list *list_remove(struct list *list, size_t index) -{ - struct list *elt = list; - struct list *prev_elt; - - if (index == 0) - { - struct list *res = elt->next; - free(elt); - return res; - } - - for (size_t i = 0; i < index; i++) - { - if (elt == NULL) - { - return list; - } - prev_elt = elt; - elt = elt->next; - } - if (elt == NULL) - { - return list; - } - - prev_elt->next = elt->next; - free(elt); - - return list; -} - -int list_find(struct list *list, void *value) -{ - if (list == NULL) - { - return -1; - } - - int res = 0; - while (list->data != value) - { - list = list->next; - res++; - if (list == NULL) - { - return -1; - } - } - return res; -} - -struct list *list_concat(struct list *list, struct list *list2) -{ - if (list == NULL) - { - return list2; - } - struct list *elt = list; - while (elt->next != NULL) - { - elt = elt->next; - } - elt->next = list2; - return list; -} - -/* - * - ****************** - * Ultimate * - ****************** - * - */ - -static void swap_next(struct list *elt) -{ - void *c = elt->next->data; - elt->next->data = elt->data; - elt->data = c; -} -struct list *list_sort(struct list *list) -{ - // Bubble sort go ! - if (list == NULL) - { - return list; - } - struct list *elt = list; - int len = 0; - while (elt->next != NULL) - { - if (elt->data > elt->next->data) - { - swap_next(elt); - } - elt = elt->next; - len++; - } - - for (int i = 1; i < len; i++) - { - elt = list; - while (elt->next != NULL) - { - if (elt->data > elt->next->data) - { - swap_next(elt); - } - elt = elt->next; - } - } - - return list; -} - -// Old proto -// WARNING no malloc/free allowed (moulinette issue) -struct list *list_reverse(struct list *list) -{ - if (list == NULL) - { - return list; - } - - // Get len - struct list *elt = list; - int len = 0; - while (elt->next != NULL) - { - len++; - elt = elt->next; - } - elt = list; - - // Bring each elt to end - for (int i = 0; i < len; i++) - { - elt = list; - for (int j = 0; j < len - i; j++) - { - swap_next(elt); - elt = elt->next; - } - } - - return list; -} - -// Doesn't work neither -// struct list *list_reverse(struct list *list) -// { -// struct list *new_list = NULL; -// struct list *elt = list; -// while (elt != NULL) -// { -// struct list *new_elt = malloc(sizeof(struct list)); -// if (new_elt == NULL) -// { -// return NULL; -// } -// new_elt->data = elt->data; -// new_elt->next = new_list; - -// struct list *next_elt = elt->next; -// free(elt); -// elt = next_elt; -// } -// return new_list; -// } - -// Moulinette issue -// struct list *list_reverse(struct list *list) -// { -// if (list == NULL) -// { -// return list; -// } - -// struct list *new_list = NULL; -// while (list != NULL) -// { -// new_list = list_prepend(new_list, list->data); -// list = list_remove(list, 0); -// } - -// return new_list; -// } - -struct list *list_split(struct list *list, size_t index) -{ - struct list *elt = list; - for (size_t i = 0; i < index; i++) - { - if (elt == NULL) - { - return NULL; - } - elt = elt->next; - } - if (elt == NULL) - { - return NULL; - } - struct list *res = elt->next; - elt->next = NULL; - return res; -} - -void list_deep_destroy(struct list *l) -{ - struct list *elt = l; - struct list *next_elt; - while (elt != NULL) - { - next_elt = elt->next; - free(elt->data); - free(elt); - elt = next_elt; - } -} diff --git a/src/lists/lists.h b/src/lists/lists.h deleted file mode 100644 index 116bd1f..0000000 --- a/src/lists/lists.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef LISTS_H -#define LISTS_H - -#include - -struct list -{ - void *data; - struct list *next; -}; - -/* -** Insert a node containing `value` at the beginning of the list. -** Return `NULL` if an error occured. -*/ -struct list *list_prepend(struct list *list, void *value); - -/* -** Return the lenght of the list. -** Return `0` if the list is empty. -*/ -size_t list_length(struct list *list); - -/* -** Display the list contents on `stdout`. -** Nothing is displayed if the list is empty. -*/ -void list_print(struct list *list); - -/* -** Release the memory used by the list. -** Does nothing if `list` is `NULL`. -*/ -void list_destroy(struct list *list); - -/* -** Release the memory used by the list and its content -** Does nothing if `list` is `NULL`. -*/ -void list_deep_destroy(struct list *l); - -/* -** Append a node containing `value` at the end of the list. -** Return `NULL` if an error occured. -*/ -// START PROTO list_append -struct list *list_append(struct list *list, void *value); -// END PROTO list_append - -/* -** Insert a node containing `value` at the index `index` in the list. -** If the index is greater than the length of the list, the behaviour is the -** same as `list_append`. -** Return `NULL` if an error occured. -*/ -// START PROTO list_insert -struct list *list_insert(struct list *list, void *value, size_t index); -// END PROTO list_insert - -/* -** Remove the element at the index `index`. -** Return `NULL` if an error occured. -*/ -// START PROTO list_remove -struct list *list_remove(struct list *list, size_t index); -// END PROTO list_remove - -/* -** Return the position of the first node containing `value`. -** Return `-1` if nothing is found. -*/ -// START PROTO list_find -int list_find(struct list *list, void *value); -// END PROTO list_find - -/* -** Concatenate the list `list2` at the end of the list `list`. -** Return `list2` if `list` is `NULL`. -*/ -// START PROTO list_concat -// struct list *list_concat(struct list *list, struct list *list2); -// END PROTO list_concat - -/* -** Sort the elements of the list in ascending order. -** Return the new list. -*/ -// START PROTO list_sort -// struct list *list_sort(struct list *list); -// END PROTO list_sort - -/* -** Invert the order of the elements of the list. -** Return the new list. -*/ -// START PROTO list_reverse -// struct list *list_reverse(struct list *list); -// END PROTO list_reverse - -/* -** Split the list at index `index`. -** First part goes in `list` and contains the element at `index`. -** Second part is returned. -** Return `NULL` if `list` is `NULL` or `index` is invalid. -*/ -// START PROTO list_split -// struct list *list_split(struct list *list, size_t index); -// END PROTO list_split - -#endif /* ! LISTS_H */ diff --git a/src/main.c b/src/main.c deleted file mode 100644 index ec0473f..0000000 --- a/src/main.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -// #include -#include -#include - -#include "files/files.h" -#include "lists/lists.h" -#include "minimake.h" - -// TODO: -// Look at perror for stdlib functions -// Create an enum for error handling - -static void print_help(char *program_name) -{ - printf("Usage: %s [options] [target]... ", program_name); - puts("Options:"); - puts(" -f FILE Reads FILE as a makefile"); - puts(" -h Prints this message and exit"); - puts(" -p Prints minimake's internal database"); - puts(""); - puts("Pas mal non ? C'est français"); -} - -static int handle_args(int argc, char **argv, struct list **minimake_files, - struct list **minimake_rules) -{ - int flags = 0; - struct list *files = NULL; - struct list *rules = NULL; - for (int i = 1; i < argc; i++) - { - // Options - if (argv[i][0] == '-') - { - // No opt - if (strcmp(argv[i], "--") == 0) - { - // Treat as rules - for (int j = i; j < argc; j++) - { - rules = list_append(rules, argv[i]); - } - *minimake_files = files; - *minimake_rules = rules; - return flags; - } - // Help - else if (strcmp(argv[i], "-h") == 0) - { - print_help(argv[0]); - list_destroy(files); - list_destroy(rules); - exit(0); - } - // Custom file - else if (strcmp(argv[i], "-f") == 0) - { - flags |= FLAGS_CUSTOM_FILE; - i++; - - if (i == argc || argv[i][0] == '-') - errx(INVALID_ARG, "No file specified after '-f'"); - - files = list_prepend(files, argv[i]); - } - // Print - else if (strcmp(argv[i], "-p") == 0) - { - flags |= FLAGS_PRINT; - } - // Unknown option - else - { - printf("Unknown option '%s'", argv[i]); - print_help(argv[0]); - list_destroy(files); - list_destroy(rules); - exit(INVALID_ARG); - } - } - else // Rules - { - rules = list_append(rules, argv[i]); - } - } - - files = list_append(files, DEFAULT_MAKEFILE); - files = list_append(files, DEFAULT_MAKEFILE_2); - - *minimake_files = files; - *minimake_rules = rules; - return flags; -} - -int main(int argc, char **argv) -{ - struct list *files; - struct list *rules; - int flags = handle_args(argc, argv, &files, &rules); - - char *filename = get_makefile(files); - if (filename == NULL) - errx(GENERIC_ERR, "No Makefile found"); - - int res = make(filename, rules, argv[0], flags); - list_destroy(files); - list_destroy(rules); - return res; -} diff --git a/src/minimake.c b/src/minimake.c deleted file mode 100644 index 4368296..0000000 --- a/src/minimake.c +++ /dev/null @@ -1,674 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include "minimake.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "files/files.h" -#include "hash_maps/hash_maps.h" -#include "lines/lines.h" -#include "lists/lists.h" - -// Static variables - -static char *program_name; - -static struct hash_map *variables = NULL; -static struct hash_map *rules = NULL; - -// Keeps track of variables and rules order -static struct list *variables_list = NULL; -static struct list *rules_list = NULL; - -// ==== Misc ==== - -static void hashmap_deep_free(struct hash_map *hash_map) -{ - if (hash_map == NULL) - return; - if (hash_map->data == NULL) - return; - - for (size_t i = 0; i < hash_map->size; i++) - { - struct pair_list *entry = hash_map->data[i]; - while (entry != NULL) - { - struct pair_list *next = entry->next; - // Ok c moche mais eh, ça fonctionne - if (hash_map == rules) - { - struct rule *r = entry->value; - free(r->name); - list_deep_destroy(r->dependencies); - list_deep_destroy(r->recipe); - free(r); - } - else if (hash_map == variables) - { - // printf("Att to free: %s\n", entry->key); - free(entry->key); - free(entry->value); - } - else - { - printf("DEBUG: attempting to free a generic hashmap\n"); - free(entry->key); - free(entry->value); - } - - free(entry); - entry = next; - } - } - free(hash_map->data); - free(hash_map); -} - -static void free_all(void) -{ - list_destroy(rules_list); - list_destroy(variables_list); - hashmap_deep_free(rules); - hashmap_deep_free(variables); -} - -// ==== Parsing ==== - -// Registers a new rule in the hashmap -// WARNING Allocates memory on the heap, -// the rules hashmap should be freed before exit -static void register_rule(char *name, struct list *dependencies, - struct list *recipe) -{ - struct rule *rule = malloc(sizeof(struct rule)); - rule->name = name; - rule->dependencies = dependencies; - rule->recipe = recipe; - - int err = hashmap_insert(rules, name, rule, NULL); - if (!err) - { - drop(GENERIC_ERR, - "Internal Error: Couln't add entry for '%s' in the hashmap", name); - } - - rules_list = list_append(rules_list, name); -} - -// Registers a new variable in the hashmap -// WARNING Allocates memory on the heap, -// the variables hashmap should be freed before exit -static void register_variable(char *name, char *value) -{ - int err = hashmap_insert(variables, name, value, NULL); - if (!err) - { - drop(GENERIC_ERR, - "Internal Error: Couln't add entry for '%s' in the hashmap", name); - } - - variables_list = list_append(variables_list, name); -} - -// Parse dependencies from buf and returns them inside a chained list -static struct list *read_deps(struct line *l, size_t offset) -{ - size_t i = offset; - size_t buf_size = l->length; - char *buf = l->buffer; - struct list *res = NULL; - - while (i < buf_size) - { - i += skipblanks(buf + i, buf_size - i); - - // Read word - char *dep_name; - i += readword(buf + i, buf_size - i, &dep_name); - if (dep_name != NULL) - // Add to list - res = list_append(res, dep_name); - - // Comments - if (buf[i] == '#') - return res; - - // Unknown chars - if (!ischar(buf[i]) && !isblank(buf[i]) && buf[i] != '\0' - && buf[i] != '\n') - { - drop(GENERIC_ERR, - "Unexpected character '%c' after rule declaration at %lu:%lu", - buf[i], l->number, i); - } - } - - return res; -} - -// Searches the following lines for recipes and returns them in the form of a -// list -// WARNING begins to read the following line -static struct list *read_recipe(struct line *l) -{ - FILE *stream = l->file_stream; - char *buf = l->buffer; - size_t buf_size = BUFFER_SIZE; - - struct list *res = NULL; - - // Getline - while ((l->length = getline(&buf, &buf_size, stream)) != -1) - { - l->number++; - - // Skip blank lines and comments - if (isblankline(l)) - continue; - else if (buf[0] != '\t') // Not a recipe - { - l->buffer = buf; // Update buffer ! - return res; - } - else // Add recipe to list - { - size_t offset = 1 + skipblanks(buf + 1, l->length - 1); - - char *command = strdup(buf + offset); - if (command == NULL) - { - drop(GENERIC_ERR, - "Internal error: couldn't duplicate string (%lu:1)", - l->number); - } - - command[l->length - offset - 1] = '\0'; - res = list_append(res, command); - } - } - - l->buffer = buf; - return res; -} - -// === Variable Expansion === - -// Reads the value after a variable declaration -static char *read_variable_value(char *buf, size_t buf_len) -{ - size_t i = 0; - size_t str_buf_size = STRING_BUFFER_SIZE; - char *str_buf = malloc(sizeof(char) * str_buf_size); - - while (i < buf_len && buf[i] != '\n' && buf[i] != '#' && buf[i] != '\0') - { - // Reallocate more space if necessary - if (i >= str_buf_size - 1) - { - str_buf_size += STRING_BUFFER_SIZE; - str_buf = realloc(str_buf, str_buf_size); - if (str_buf == NULL) - drop(GENERIC_ERR, "Could not realloc"); - } - - str_buf[i] = buf[i]; - i++; - } - - str_buf[i] = '\0'; - - return str_buf; -} - -// Reads variable name from buf until ')' and stores it into *result -// Returns its length on success and -1 on fail -// WARNING allocates memory on the heap, free *result after use -static size_t read_variable_name(struct line *line, size_t index, char **result) -{ - size_t i = index; - char *buf = line->buffer; - - // Alloc var_buf - size_t var_buf_size = STRING_BUFFER_SIZE; - char *var_buf = malloc(sizeof(char) * var_buf_size); - if (var_buf == NULL) - drop(GENERIC_ERR, "Could not allocate more memory"); - - size_t var_i = 0; - while (buf[i] != '\n' && buf[i] != '\0' && buf[i] != '#' && buf[i] != ')') - { - // Reallocate more space if necessary - var_buf_size = resize_buf(&var_buf, var_buf_size, i); - - // Copy - var_buf[var_i] = buf[i]; - i++; - var_i++; - } - var_buf[var_i] = '\0'; - - // Mismatched parenthesis - if (buf[i] != ')') - { - free(var_buf); - *result = NULL; - return 0; - } - - i += 2; - *result = var_buf; - return i - index; -} - -// Searches for variable in database and returns its value -// if no value is found, it drops an error and exit the program -// WARNING variable must be allocated on the heap as this function may attempt -// to free it -// NOTE Takes line_number to print an helpful error message -static char *get_variable_value(char *variable_name, size_t line_number) -{ - char *value = hashmap_get(variables, variable_name); - if (value == NULL) - { - // Adds tmp_buf to the list of items to free - variables_list = list_append(variables_list, variable_name); - drop(GENERIC_ERR, "Could not find specified variable '%s' at line %lu", - variable_name, line_number); - } - - free(variable_name); - return value; -} - -// Gets the corresponding value of the variable and stores it in *value -// Returns the number of skipped characters -size_t expand_variable(struct line *line, size_t index, char **value) -{ - size_t i = index; - char *buf = line->buffer; - - // Name in parenthesis - if (buf[i] == '(') - { - // Read variable - char *var_name; - i++; - i += read_variable_name(line, i, &var_name); - if (var_name == NULL) - drop(GENERIC_ERR, "Mismatched parenthesis at %lu:%lu", i, - line->number); - - // Get corresponding value - *value = get_variable_value(var_name, line->number); - - // Return - return i - index; - } - else // Single char variable - { - // '$ ' - if (isblank(buf[i]) || isspace(buf[i])) - drop(2, "Unauthorized character '%c' at %lu:%lu", buf[i], - line->number, i); - else - { - // Allocate temporary buffer to hold variable name - char *var_name = malloc(2 * sizeof(char)); - if (var_name == NULL) - // Seriously, not even two bytes - drop(GENERIC_ERR, "Could not allocate memory"); - - var_name[0] = buf[i]; - var_name[1] = '\0'; - - // Escape '$$' - if (buf[i] == '$') - { - *value = var_name; - return 2; - } - - // Get corresponding value - *value = get_variable_value(var_name, line->number); - free(var_name); - } - - return 2; - } -} - -// ================= - -// Takes a buffer containing the line to parse and it length -// As well as the line number in the file for error handling -static void parse_line(struct line *current_line) -{ - char *buf = current_line->buffer; - size_t line_size = current_line->length; - - size_t i = 0; - - i += skipblanks(buf + i, line_size - i); - - // Read name - char *name; - // i += readword(buf + i, line_size - i, &name); - i += read_declaration(current_line, i, &name); - // if (name == NULL) - // errx(1, "Il s'est passé quoi là ? \nUnexpected character at %lu:%lu", - // current_line->number, i); - - i += skipblanks(buf + i, line_size - i); - - // Potential elements - struct list *dependencies; - struct list *recipe; - char *value; - - // Definition type - switch (buf[i]) - { - // Variable - case '=': - i += skipblanks(buf + i + 1, line_size - i) + 1; - value = read_variable_value(buf + i, line_size - i); - register_variable(name, value); - break; - - // Rule - case ':': - dependencies = read_deps(current_line, i + 1); - recipe = read_recipe(current_line); - register_rule(name, dependencies, recipe); - - // Check for EOF - if (current_line->length == -1) - return; - - parse_line(current_line); - // TODO: check for loooooops - - break; - - // Blank line - case '\0': - case '#': - if (name != NULL) - { - drop(GENERIC_ERR, - "Unexpected character '%c' after declaration '%s' at line %lu", - buf[i], name, current_line->number); - } - break; - - default: - drop(GENERIC_ERR, - "Unexpected character '%c' after declaration '%s' at line %lu", - buf[i], name, current_line->number); - } - - // free(name); -} - -void make_parse(char *path) -{ - // Open file - FILE *stream = fopen(path, "r"); - if (stream == 0) - errx(2, "Could not open file: %s", path); - - // Init hash maps - variables = hashmap_init(HASHMAP_SIZE); - rules = hashmap_init(HASHMAP_SIZE); - if (variables == NULL || rules == NULL) - errx(1, "Internal error: Failed to initiate hash maps"); - - // Allocate line buffer - size_t buf_size = BUFFER_SIZE; - char *buf = malloc(sizeof(char) * buf_size); - if (buf == NULL) - drop(GENERIC_ERR, "Could not allocate more memory"); - - // Parse line by line - ssize_t nread; - struct line current_line; - current_line.number = 1; - current_line.file_stream = stream; - while ((nread = getline(&buf, &buf_size, stream)) != -1) - { - if (nread == -1) - drop(GENERIC_ERR, "Could not get line %lu", current_line.number); - - current_line.buffer = buf; - current_line.length = nread; - - parse_line(¤t_line); - - current_line.number += 1; - } - - free(buf); - fclose(stream); - return; -} - -// ==== Runtime ==== - -// Return 1 if rule is up to date, 0 otherwise -static int uptodate(struct rule *rule) -{ - struct stat path_stat; - - if (lstat(rule->name, &path_stat) != 0) // target doesn't exists - return 0; - - struct list *dependencies = rule->dependencies; - while (dependencies != NULL) - { - char *depname = dependencies->data; - if (lstat(depname, &path_stat) != 0) // Dependecy doesn't exists - return 0; - } - return 1; -} - -// Expands and run a specified rule -static int run_rule(struct rule *rule) -{ - // Check if p to date - if (uptodate(rule)) - { - printf("%s: '%s' is up to date.", program_name, rule->name); - return 0; - } - - struct list *commands = rule->recipe; - struct list *dependencies = rule->dependencies; - - // Build dependencies - while (dependencies != NULL) - { - // Expand variable - // TODO - - // Check file existence - if (!file_exists(dependencies->data)) - { - // Check rule existence instead - struct rule *dep_rule = hashmap_get(rules, dependencies->data); - if (dep_rule != NULL) - { - int res = run_rule(dep_rule); - if (res != 0) // Exit on error - return res; - } - else - { - drop(GENERIC_ERR, "No rule to make target '%s'", - dependencies->data); - } - } - - dependencies = dependencies->next; - } - - // Empty recipe - if (commands == NULL) - { - printf("%s: Nothing to be done for '%s'.\n", program_name, rule->name); - return 0; - } - - while (commands != NULL) - { - // Expand command variables - // TODO - - // Run - int res = run_command(commands->data); - if (res != 0) // Exit on error - return res; - - commands = commands->next; - } - - return 0; -} - -// Run the given rules after parsing -int make_run(struct list *given_rules) -{ - if (given_rules == NULL) - { - // No rule specified => run first rule found in the Makefile - if (rules_list == NULL) - drop(GENERIC_ERR, "No targets"); - - struct rule *full_rule = hashmap_get(rules, rules_list->data); - if (full_rule == NULL) - drop(GENERIC_ERR, - "Internal error: Could not retrieve target '%s' in database", - rules_list->data); - - return run_rule(full_rule); - } - else - { - while (given_rules != NULL) - { - struct rule *full_rule = hashmap_get(rules, given_rules->data); - if (full_rule == NULL) - drop(GENERIC_ERR, "No rule to make target '%s'", - given_rules->data); - - int res = run_rule(full_rule); - if (res != 0) - return res; - - given_rules = given_rules->next; - } - return 0; - } -} - -// ==== MAKE ==== - -int make(char *path, struct list *rules, char *exec_name, int flags) -{ - program_name = exec_name; - - make_parse(path); - - // Print - if (flags & FLAGS_PRINT) - { - dump_database(); - free_all(); - return 0; - } - - // Run - int status = make_run(rules); - free_all(); - return status; -} - -// Prints an error message before exiting gracefully (by freeing all variables) -void drop(int status, char *format, ...) -{ - // Print - va_list args; - va_start(args, format); - fprintf(stderr, "%s: *** ", program_name); - vfprintf(stderr, format, args); - fprintf(stderr, ". Stop.\n"); - va_end(args); - - free_all(); - exit(status); -} - -void dump_database(void) -{ - struct list *elt; - - // Dump variables - elt = variables_list; - puts("# variables"); - while (elt != NULL) - { - // Get var - char *val = hashmap_get(variables, elt->data); - if (val == NULL) - drop(GENERIC_ERR, "Could not get variable '%s' in database", - elt->data); - - // Print - char *key = elt->data; - printf("'%s' = '%s'\n", key, val); - - elt = elt->next; - } - // Dump rules - elt = rules_list; - puts("# rules"); - while (elt != NULL) - { - // Get rule - struct rule *rule = hashmap_get(rules, elt->data); - if (rule == NULL) - drop(GENERIC_ERR, "Could not get rule '%s' in database", elt->data); - - // Print name - printf("(%s):", rule->name); - - // Print dependencies - struct list *dep = rule->dependencies; - while (dep != NULL) - { - char *dep_str = dep->data; - printf(" [%s]", dep_str); - dep = dep->next; - } - putchar('\n'); - - // Print recipe - struct list *rcp = rule->recipe; - while (rcp != NULL) - { - char *rcp_str = rcp->data; - printf("\t'%s'\n", rcp_str); - rcp = rcp->next; - } - - elt = elt->next; - } -} diff --git a/src/minimake.h b/src/minimake.h deleted file mode 100644 index 7bb5f39..0000000 --- a/src/minimake.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef MINIMAKE_H -#define MINIMAKE_H - -// Error Codes -#define INVALID_ARG 2 -#define GENERIC_ERR 2 - -// Flags -#define FLAGS_CUSTOM_FILE 1 -#define FLAGS_PRINT 2 - -// Default values -#define DEFAULT_MAKEFILE "makefile" -#define DEFAULT_MAKEFILE_2 "Makefile" -#define BUFFER_SIZE 1024 -#define HASHMAP_SIZE 32 - -#include -#include - -#include "lines/lines.h" -#include "lists/lists.h" - -// Holds variable information -// WARNING its values must be freed after use -struct variable -{ - char *name; - char *value; -}; - -// Holds rule information -// WARNING its values must be freed after use -struct rule -{ - char *name; - struct list *dependencies; - struct list *recipe; -}; - -int make(char *path, struct list *rules, char *argv0, int flags); -void make_parse(char *path); -int make_run(struct list *rules); -void drop(int status, char *format, ...); -void dump_database(void); -size_t expand_variable(struct line *line, size_t index, char **value); - -#endif // ! MINIMAKE_H diff --git a/tests/Makefile.empty b/tests/Makefile.empty deleted file mode 100644 index e9228f2..0000000 --- a/tests/Makefile.empty +++ /dev/null @@ -1 +0,0 @@ -empty_target: diff --git a/tests/Makefile.syntax-test b/tests/Makefile.syntax-test deleted file mode 100644 index fff0427..0000000 --- a/tests/Makefile.syntax-test +++ /dev/null @@ -1,35 +0,0 @@ -SIMPLE_VAR = coucou -SIMPLE_VAR_COMMENT = the comment is gone # comment - -# the following line starts with a space then a tab - SPACES_BEFORE_TAB = var_beginning var_end - -sparse_rule: depa depb - - command 1 - - command 2 - - B = B_var_beginning B_var_end - -packed_rule: depa depb - command 1 - command 2 - -silent_rule: depa depb - @ command 1 - @command 2 - -rule_comment: depa depb # comment - -command_space_rule: depa depb - echo spaces before - echo spaces after - echo this is a # comment - -simple_rule: simple_dep - -no_dep_rule: - -variable_rule: beginning $(SIMPLE_VAR) end - echo "shouldn't be expanded: $(SIMPLE_VAR)" diff --git a/tests/Makefile.test3 b/tests/Makefile.test3 deleted file mode 100644 index 7a42836..0000000 --- a/tests/Makefile.test3 +++ /dev/null @@ -1 +0,0 @@ -VAR = 1 diff --git a/tests/Makefile.test4 b/tests/Makefile.test4 deleted file mode 100644 index 4da97dd..0000000 --- a/tests/Makefile.test4 +++ /dev/null @@ -1,7 +0,0 @@ -rule1: - echo Toto - echo Tata - echo Tutu - -rule2: - @echo Toto encore diff --git a/tests/Makefile.vars b/tests/Makefile.vars deleted file mode 100644 index b5ce417..0000000 --- a/tests/Makefile.vars +++ /dev/null @@ -1,4 +0,0 @@ -V=2 - -main: - echo $V diff --git a/tests/Makefile2.syntax-test b/tests/Makefile2.syntax-test deleted file mode 100644 index ac3c606..0000000 --- a/tests/Makefile2.syntax-test +++ /dev/null @@ -1,36 +0,0 @@ -SIMPLE_VAR = coucou -SIMPLE_VAR_COMMENT = the comment is gone # comment -$(SIMPLE_VAR) = 1 - -# the following line starts with a space then a tab - SPACES_BEFORE_TAB = var_beginning var_end - -sparse_rule: depa depb - - command 1 - - command 2 - - B = B_var_beginning B_var_end - -packed_rule: depa depb - command 1 - command 2 - -silent_rule: depa depb - @ command 1 - @command 2 - -rule_comment: depa depb # comment - -command_space_rule: depa depb - echo spaces before - echo spaces after - echo this is a # comment - -simple_rule: simple_dep - -no_dep_rule: - -variable_rule: beginning $(SIMPLE_VAR) end - echo "shouldn't be expanded: $(SIMPLE_VAR)" diff --git a/tests/run.sh b/tests/run.sh deleted file mode 100644 index 0fe1e07..0000000 --- a/tests/run.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh - -########################################### -# PIERRE PAGNOUX EXPERIENCE TESTSUITE # -########################################### - -#----------------- COLOR -----------------# -# 0 - No style | 1 - Bold -RED="\e[0;31m" -BRED="\e[1;31m" -GRN="\e[0;32m" -BGRN="\e[1;32m" -YEL="\e[0;33m" -BYEL="\e[1;33m" -BLU="\e[0;34m" -BBLU="\e[1;34m" -PUR="\e[0;35m" -BPUR="\e[1;35m" -CYA="\e[0;36m" -BCYA="\e[1;36m" -WHI="\e[0;37m" -BWHI="\e[1;37m" -GRE="\e[2;37m" - -#----------------- GLOBV -----------------# -ref_out=/tmp/ref_out.out -my_out=/tmp/my_out.out - -#----------------- TESTS -----------------# - -tit_wrap() -{ - echo -e $@$WHI -} - -func_test() -{ - tit_wrap - $PUR $1 - shift - printf $@ > $ref_out - ../../tinyprintf $@ > $my_out - - diff $ref_out $my_out > /tmp/null - - if [ $? -eq 0 ]; then - tit_wrap $GRN GOOD - else - tit_wrap $RED EXPECTED: $BRED$(cat $ref_out) \|$RED GOT: $BRED$(cat $my_out) - fi -} - -func_file() -{ - for file in *; do - if [ -f $file ]; then - func_test $file $(cat $file) - fi - done -} - -func_dir() -{ - cd tests - for dir in *; do - if [ -d $dir ]; then - tit_wrap == $dir == - cd $dir - func_file - cd .. - fi - done - cd .. -} - -# func_dir - -echo "Tests should be here"