'
This commit is contained in:
parent
5f4d6af9c0
commit
afe78e4401
7 changed files with 131 additions and 93 deletions
|
|
@ -27,7 +27,7 @@ size_t hash(const char *key)
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hash_map *hashMapInit(size_t size)
|
struct hash_map *hashmap_init(size_t size)
|
||||||
{
|
{
|
||||||
struct pair_list **data = calloc(size, sizeof(struct pair_list));
|
struct pair_list **data = calloc(size, sizeof(struct pair_list));
|
||||||
struct hash_map *map = malloc(sizeof(struct hash_map));
|
struct hash_map *map = malloc(sizeof(struct hash_map));
|
||||||
|
|
@ -36,8 +36,8 @@ struct hash_map *hashMapInit(size_t size)
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hashMapInsert(struct hash_map *hash_map, const char *key, char *value,
|
bool hashmap_insert(struct hash_map *hash_map, char *key, void *value,
|
||||||
bool *updated)
|
bool *updated)
|
||||||
{
|
{
|
||||||
if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0)
|
if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -79,7 +79,7 @@ bool hashMapInsert(struct hash_map *hash_map, const char *key, char *value,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashMapFree(struct hash_map *hash_map)
|
void hashmap_free(struct hash_map *hash_map)
|
||||||
{
|
{
|
||||||
if (hash_map == NULL)
|
if (hash_map == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
@ -100,7 +100,10 @@ void hashMapFree(struct hash_map *hash_map)
|
||||||
free(hash_map);
|
free(hash_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashMapDump(struct hash_map *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++)
|
for (size_t i = 0; i < hash_map->size; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -109,12 +112,14 @@ void hashMapDump(struct hash_map *hash_map)
|
||||||
if (entry != NULL)
|
if (entry != NULL)
|
||||||
{
|
{
|
||||||
is_null = false;
|
is_null = false;
|
||||||
printf("%s: %s", entry->key, entry->value);
|
char *val = entry->value;
|
||||||
|
printf("%s: %s", entry->key, val);
|
||||||
entry = entry->next;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
while (entry != NULL)
|
while (entry != NULL)
|
||||||
{
|
{
|
||||||
printf(", %s: %s", entry->key, entry->value);
|
char *val = entry->value;
|
||||||
|
printf(", %s: %s", entry->key, val);
|
||||||
entry = entry->next;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
if (!is_null)
|
if (!is_null)
|
||||||
|
|
@ -122,7 +127,7 @@ void hashMapDump(struct hash_map *hash_map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *hashMapGet(const struct hash_map *hash_map, const char *key)
|
void *hashmap_get(const struct hash_map *hash_map, char *key)
|
||||||
{
|
{
|
||||||
if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0)
|
if (hash_map == NULL || hash_map->data == NULL || hash_map->size == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -139,7 +144,7 @@ const char *hashMapGet(const struct hash_map *hash_map, const char *key)
|
||||||
return entry->value;
|
return entry->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hashMapRemove(struct hash_map *hash_map, const char *key)
|
bool hashmap_remove(struct hash_map *hash_map, char *key)
|
||||||
{
|
{
|
||||||
if (hash_map == NULL || hash_map->size == 0 || hash_map->data == NULL)
|
if (hash_map == NULL || hash_map->size == 0 || hash_map->data == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
#ifndef HASH_MAP_H
|
#ifndef HASH_MAPS_H
|
||||||
#define HASH_MAP_H
|
#define HASH_MAPS_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// 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
|
struct pair_list
|
||||||
{
|
{
|
||||||
const char *key;
|
char *key;
|
||||||
char *value;
|
void *value;
|
||||||
struct pair_list *next;
|
struct pair_list *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -18,12 +22,12 @@ struct hash_map
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t hash(const char *str);
|
size_t hash(const char *str);
|
||||||
struct hash_map *hashMapInit(size_t size);
|
struct hash_map *hashmap_init(size_t size);
|
||||||
bool hashMapInsert(struct hash_map *hash_map, const char *key, char *value,
|
bool hashmap_insert(struct hash_map *hash_map, char *key, void *value,
|
||||||
bool *updated);
|
bool *updated);
|
||||||
void hashMapFree(struct hash_map *hash_map);
|
void hashmap_free(struct hash_map *hash_map);
|
||||||
void hashMapDump(struct hash_map *hash_map);
|
void hashmap_dump(struct hash_map *hash_map);
|
||||||
const char *hashMapGet(const struct hash_map *hash_map, const char *key);
|
void *hashmap_get(const struct hash_map *hash_map, char *key);
|
||||||
bool hashMapRemove(struct hash_map *hash_map, const char *key);
|
bool hashmap_remove(struct hash_map *hash_map, char *key);
|
||||||
|
|
||||||
#endif /* ! HASH_MAP_H */
|
#endif /* ! HASH_MAPS_H */
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// Helps to match a string (excludes blanks and special characters)
|
// Helps to match a string (excludes blanks and special characters)
|
||||||
int isChar(char c)
|
int ischar(char c)
|
||||||
{
|
{
|
||||||
return c != '\0' && !isblank(c) && c != ':' && c != '=' && c != '#'
|
return c != '\0' && !isblank(c) && c != ':' && c != '=' && c != '#'
|
||||||
&& c != '\n';
|
&& c != '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
int skipBlanks(char *buf, size_t buf_len)
|
int skipblanks(char *buf, size_t buf_len)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < buf_len && (isblank(buf[i]) || buf[i] == '\n'))
|
while (i < buf_len && (isblank(buf[i]) || buf[i] == '\n'))
|
||||||
|
|
@ -22,7 +22,7 @@ int skipBlanks(char *buf, size_t buf_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns 1 if line is blank
|
// Returns 1 if line is blank
|
||||||
int isBlankLine(struct line *l)
|
int isblankline(struct line *l)
|
||||||
{
|
{
|
||||||
size_t line_size = l->length;
|
size_t line_size = l->length;
|
||||||
char *buf = l->buffer;
|
char *buf = l->buffer;
|
||||||
|
|
@ -42,12 +42,12 @@ int isBlankLine(struct line *l)
|
||||||
// Returns the next word from buf until buf_len,
|
// Returns the next word from buf until buf_len,
|
||||||
// and the numbers of read characters in *read_chars
|
// and the numbers of read characters in *read_chars
|
||||||
// WARNING allocates the result on the heap
|
// WARNING allocates the result on the heap
|
||||||
size_t readWord(char *buf, size_t buf_len, char **word)
|
size_t readword(char *buf, size_t buf_len, char **word)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t res_size = STRING_BUFFER_SIZE;
|
size_t res_size = STRING_BUFFER_SIZE;
|
||||||
char *res = malloc(sizeof(char) * res_size);
|
char *res = malloc(sizeof(char) * res_size);
|
||||||
while (i < buf_len && isChar(buf[i]))
|
while (i < buf_len && ischar(buf[i]))
|
||||||
{
|
{
|
||||||
// Reallocate more space if necessary
|
// Reallocate more space if necessary
|
||||||
if (i >= res_size - 1)
|
if (i >= res_size - 1)
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ struct line
|
||||||
FILE* file_stream; // Full file stream
|
FILE* file_stream; // Full file stream
|
||||||
};
|
};
|
||||||
|
|
||||||
int isChar(char c);
|
int ischar(char c);
|
||||||
int isBlankLine(struct line *l);
|
int isblankline(struct line *l);
|
||||||
int skipBlanks(char *buf, size_t buf_len);
|
int skipblanks(char *buf, size_t buf_len);
|
||||||
size_t readWord(char *buf, size_t buf_len, char **word);
|
size_t readword(char *buf, size_t buf_len, char **word);
|
||||||
|
|
||||||
#endif // LINES_H
|
#endif // LINES_H
|
||||||
|
|
|
||||||
|
|
@ -123,5 +123,5 @@ int main(int argc, char **argv)
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
errx(GENERIC_ERR, "No Makefile found");
|
errx(GENERIC_ERR, "No Makefile found");
|
||||||
|
|
||||||
make(filename, flags);
|
make(filename, flags, argv[0]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,50 +15,81 @@
|
||||||
// Static variables
|
// Static variables
|
||||||
struct hash_map *variables = NULL;
|
struct hash_map *variables = NULL;
|
||||||
struct hash_map *rules = NULL;
|
struct hash_map *rules = NULL;
|
||||||
|
char *program_name;
|
||||||
|
|
||||||
|
// ==== 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;
|
||||||
|
free(entry->key);
|
||||||
|
free(entry->value);
|
||||||
|
free(entry);
|
||||||
|
entry = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(hash_map->data);
|
||||||
|
free(hash_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_all()
|
||||||
|
{
|
||||||
|
hashmap_deep_free(rules);
|
||||||
|
hashmap_deep_free(variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static void dump_database()
|
||||||
|
// {
|
||||||
|
// hashmap_dump(variables);
|
||||||
|
// hashmap_dump(rules);
|
||||||
|
// }
|
||||||
|
|
||||||
// ==== Parsing ====
|
// ==== Parsing ====
|
||||||
|
|
||||||
// Registers a new variable and returns its pointer
|
// Registers a new rule in the hashmap
|
||||||
// WARNING Allocates memory on the heap,
|
// WARNING Allocates memory on the heap,
|
||||||
// the variables hashmap should be freed before exit
|
// the rules hashmap should be freed before exit
|
||||||
static struct variable *createVariable(char *name)
|
static void register_rule(char *name, struct list *dependencies,
|
||||||
|
struct list *recipe)
|
||||||
{
|
{
|
||||||
struct variable *res = malloc(sizeof(struct variable));
|
struct rule *rule = malloc(sizeof(struct rule));
|
||||||
res->name = name;
|
rule->name = name;
|
||||||
res->value = NULL;
|
rule->dependencies = dependencies;
|
||||||
|
rule->recipe = recipe;
|
||||||
|
|
||||||
int err = hashMapInsert(variables, name, NULL, NULL);
|
int err = hashmap_insert(variables, name, rule, NULL);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
errx(1, "Internal Error: Couln't add entry for '%s' in the hashmap",
|
||||||
|
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)
|
if (!err)
|
||||||
{
|
{
|
||||||
// free(name);
|
|
||||||
free(res);
|
|
||||||
errx(2, "Internal Error: Couln't add entry for '%s' in the hashmap",
|
errx(2, "Internal Error: Couln't add entry for '%s' in the hashmap",
|
||||||
name);
|
name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers a new rule and returns its pointer
|
|
||||||
// WARNING Allocates memory on the heap,
|
|
||||||
// the rules hashmap should be freed before exit
|
|
||||||
static struct rule *createRule(char *name)
|
|
||||||
{
|
|
||||||
struct rule *res = malloc(sizeof(struct rule));
|
|
||||||
res->name = name;
|
|
||||||
res->dependencies = NULL;
|
|
||||||
res->recipe = NULL;
|
|
||||||
|
|
||||||
int err = hashMapInsert(variables, name, NULL, NULL);
|
|
||||||
if (!err)
|
|
||||||
errx(1, "Internal Error: Couln't add entry for '%s' in the hashmap",
|
|
||||||
name);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse dependencies from buf and returns them inside a chained list
|
// Parse dependencies from buf and returns them inside a chained list
|
||||||
static struct list *readDependencies(struct line *l, size_t offset)
|
static struct list *read_deps(struct line *l, size_t offset)
|
||||||
{
|
{
|
||||||
size_t i = offset;
|
size_t i = offset;
|
||||||
size_t buf_size = l->length;
|
size_t buf_size = l->length;
|
||||||
|
|
@ -67,11 +98,11 @@ static struct list *readDependencies(struct line *l, size_t offset)
|
||||||
|
|
||||||
while (i < buf_size)
|
while (i < buf_size)
|
||||||
{
|
{
|
||||||
i += skipBlanks(buf + i, buf_size - i);
|
i += skipblanks(buf + i, buf_size - i);
|
||||||
|
|
||||||
// Read word
|
// Read word
|
||||||
char *dep_name;
|
char *dep_name;
|
||||||
i += readWord(buf + i, buf_size - i, &dep_name);
|
i += readword(buf + i, buf_size - i, &dep_name);
|
||||||
if (dep_name != NULL)
|
if (dep_name != NULL)
|
||||||
// Add to list
|
// Add to list
|
||||||
res = list_append(res, dep_name);
|
res = list_append(res, dep_name);
|
||||||
|
|
@ -81,7 +112,7 @@ static struct list *readDependencies(struct line *l, size_t offset)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
// Unknown chars
|
// Unknown chars
|
||||||
if (!isChar(buf[i]) && !isblank(buf[i]) && buf[i] != '\0'
|
if (!ischar(buf[i]) && !isblank(buf[i]) && buf[i] != '\0'
|
||||||
&& buf[i] != '\n')
|
&& buf[i] != '\n')
|
||||||
{
|
{
|
||||||
printf("DEBUG: line: %s", l->buffer);
|
printf("DEBUG: line: %s", l->buffer);
|
||||||
|
|
@ -97,7 +128,7 @@ static struct list *readDependencies(struct line *l, size_t offset)
|
||||||
// Searches the following lines for recipes and returns them in the form of a
|
// Searches the following lines for recipes and returns them in the form of a
|
||||||
// list
|
// list
|
||||||
// WARNING begins to read the following line
|
// WARNING begins to read the following line
|
||||||
static struct list *readRecipe(struct line *l)
|
static struct list *read_recipe(struct line *l)
|
||||||
{
|
{
|
||||||
FILE *stream = l->file_stream;
|
FILE *stream = l->file_stream;
|
||||||
char *buf = l->buffer;
|
char *buf = l->buffer;
|
||||||
|
|
@ -111,7 +142,7 @@ static struct list *readRecipe(struct line *l)
|
||||||
l->number++;
|
l->number++;
|
||||||
|
|
||||||
// Skip blank lines and comments
|
// Skip blank lines and comments
|
||||||
if (isBlankLine(l))
|
if (isblankline(l))
|
||||||
continue;
|
continue;
|
||||||
else if (buf[0] != '\t') // Not a recipe
|
else if (buf[0] != '\t') // Not a recipe
|
||||||
{
|
{
|
||||||
|
|
@ -134,7 +165,7 @@ static struct list *readRecipe(struct line *l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads the value after a variable declaration
|
// Reads the value after a variable declaration
|
||||||
static char *readValue(char *buf, size_t buf_size)
|
static char *read_value(char *buf, size_t buf_size)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t str_buf_size = STRING_BUFFER_SIZE;
|
size_t str_buf_size = STRING_BUFFER_SIZE;
|
||||||
|
|
@ -164,48 +195,49 @@ static char *readValue(char *buf, size_t buf_size)
|
||||||
|
|
||||||
// Takes a buffer containing the line to parse and it length
|
// Takes a buffer containing the line to parse and it length
|
||||||
// As well as the line number in the file for error handling
|
// As well as the line number in the file for error handling
|
||||||
static void parseLine(struct line *current_line)
|
static void parse_line(struct line *current_line)
|
||||||
{
|
{
|
||||||
char *buf = current_line->buffer;
|
char *buf = current_line->buffer;
|
||||||
size_t line_size = current_line->length;
|
size_t line_size = current_line->length;
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
i += skipBlanks(buf + i, line_size - i);
|
i += skipblanks(buf + i, line_size - i);
|
||||||
|
|
||||||
// Read name
|
// Read name
|
||||||
char *name;
|
char *name;
|
||||||
i += readWord(buf + i, line_size - i, &name);
|
i += readword(buf + i, line_size - i, &name);
|
||||||
// if (name == NULL)
|
// if (name == NULL)
|
||||||
// errx(1, "Il s'est passé quoi là ? \nUnexpected character at %lu:%lu",
|
// errx(1, "Il s'est passé quoi là ? \nUnexpected character at %lu:%lu",
|
||||||
// current_line->number, i);
|
// current_line->number, i);
|
||||||
|
|
||||||
i += skipBlanks(buf + i, line_size - i);
|
i += skipblanks(buf + i, line_size - i);
|
||||||
|
|
||||||
// Potential elements
|
// Potential elements
|
||||||
struct rule *new_rule;
|
struct list *dependencies;
|
||||||
struct variable *new_variable;
|
struct list *recipe;
|
||||||
|
char *value;
|
||||||
|
|
||||||
// Definition type
|
// Definition type
|
||||||
switch (buf[i])
|
switch (buf[i])
|
||||||
{
|
{
|
||||||
// Variable
|
// Variable
|
||||||
case '=':
|
case '=':
|
||||||
new_variable = createVariable(name);
|
value = read_value(buf + i, line_size);
|
||||||
new_variable->value = readValue(buf + i, line_size);
|
register_variable(name, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Rule
|
// Rule
|
||||||
case ':':
|
case ':':
|
||||||
new_rule = createRule(name);
|
dependencies = read_deps(current_line, i + 1);
|
||||||
new_rule->dependencies = readDependencies(current_line, i + 1);
|
recipe = read_recipe(current_line);
|
||||||
new_rule->recipe = readRecipe(current_line);
|
register_rule(name, dependencies, recipe);
|
||||||
|
|
||||||
// Check for EOF
|
// Check for EOF
|
||||||
if (current_line->length == -1)
|
if (current_line->length == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
parseLine(current_line);
|
parse_line(current_line);
|
||||||
// TODO: check for loooooops
|
// TODO: check for loooooops
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -228,7 +260,7 @@ static void parseLine(struct line *current_line)
|
||||||
// free(name);
|
// free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeParse(char *path)
|
void make_parse(char *path)
|
||||||
{
|
{
|
||||||
// Open file
|
// Open file
|
||||||
FILE *stream = fopen(path, "r");
|
FILE *stream = fopen(path, "r");
|
||||||
|
|
@ -236,8 +268,8 @@ void makeParse(char *path)
|
||||||
errx(2, "Could not open file: %s", path);
|
errx(2, "Could not open file: %s", path);
|
||||||
|
|
||||||
// Init hash maps
|
// Init hash maps
|
||||||
variables = hashMapInit(HASHMAP_SIZE);
|
variables = hashmap_init(HASHMAP_SIZE);
|
||||||
rules = hashMapInit(HASHMAP_SIZE);
|
rules = hashmap_init(HASHMAP_SIZE);
|
||||||
if (variables == NULL || rules == NULL)
|
if (variables == NULL || rules == NULL)
|
||||||
errx(1, "Internal error: Failed to initiate hash maps");
|
errx(1, "Internal error: Failed to initiate hash maps");
|
||||||
|
|
||||||
|
|
@ -260,7 +292,7 @@ void makeParse(char *path)
|
||||||
current_line.buffer = buf;
|
current_line.buffer = buf;
|
||||||
current_line.length = nread;
|
current_line.length = nread;
|
||||||
|
|
||||||
parseLine(¤t_line);
|
parse_line(¤t_line);
|
||||||
|
|
||||||
current_line.number += 1;
|
current_line.number += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -274,18 +306,14 @@ void makeParse(char *path)
|
||||||
|
|
||||||
// ==== MAKE ====
|
// ==== MAKE ====
|
||||||
|
|
||||||
void make(char *path, int flags)
|
void make(char *path, int flags, char *argv0)
|
||||||
{
|
{
|
||||||
|
program_name = argv0;
|
||||||
|
|
||||||
if (flags & FLAGS_PRINT)
|
if (flags & FLAGS_PRINT)
|
||||||
errx(GENERIC_ERR, "Not Implemented");
|
errx(GENERIC_ERR, "Not Implemented");
|
||||||
|
|
||||||
makeParse(path);
|
make_parse(path);
|
||||||
|
// dump_database();
|
||||||
|
free_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== Misc ====
|
|
||||||
|
|
||||||
// static void free_all()
|
|
||||||
// {
|
|
||||||
// hashMapFree(rules);
|
|
||||||
// hashMapFree(variables);
|
|
||||||
// }
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ struct rule
|
||||||
struct list *recipe;
|
struct list *recipe;
|
||||||
};
|
};
|
||||||
|
|
||||||
void make(char *path, int flags);
|
void make(char *path, int flags, char* program_name);
|
||||||
|
void make_parse(char *path);
|
||||||
|
|
||||||
#endif // ! MINIMAKE_H
|
#endif // ! MINIMAKE_H
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue