JUSTOCASOU

This commit is contained in:
Gu://em_ 2025-10-31 21:34:09 +01:00
parent c358562ecc
commit a8ca407247
8 changed files with 220 additions and 41 deletions

View file

@ -7,7 +7,7 @@ DBG_LDFLAGS= -fsanitize=address
SRC_DIR = src
LIB_SRCS = lines/lines.c hash_maps/hash_maps.c lists/lists.c
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))

View file

@ -0,0 +1,99 @@
#include "files.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
// #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);
// char *executable;
// size_t args_offset = readword(command, strlen(command), &executable);
int id = fork();
if (id < 0)
{
perror("fork");
return -1;
}
if (id == 0)
{
int res = 0;
wait(&res);
// printf("Got return code: %d\n", res);
return res;
}
else
{
int res = execl("/bin/sh", "(make)", "-c", command, NULL);
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;
}

View file

@ -0,0 +1,14 @@
#ifndef FILES_H
#define FILES_H
#define _XOPEN_SOURCE 500
#include "../lists/lists.h"
#include <sys/types.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

View file

@ -5,6 +5,7 @@
#include <stdio.h>
#include <string.h>
#include "files/files.h"
#include "lists/lists.h"
#include "minimake.h"
@ -58,10 +59,12 @@ static int handle_args(int argc, char **argv, struct list **minimake_files,
else if (strcmp(argv[i], "-f") == 0)
{
flags |= FLAGS_CUSTOM_FILE;
if (i + 1 == argc || argv[i + 1][0] == '-')
i++;
if (i == argc || argv[i][0] == '-')
errx(INVALID_ARG, "No file specified after '-f'");
files = list_prepend(files, argv[i + 1]);
files = list_prepend(files, argv[i]);
}
// Print
else if (strcmp(argv[i], "-p") == 0)
@ -92,33 +95,6 @@ static int handle_args(int argc, char **argv, struct list **minimake_files,
return flags;
}
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;
}
int main(int argc, char **argv)
{
struct list *files;
@ -129,8 +105,8 @@ int main(int argc, char **argv)
if (filename == NULL)
errx(GENERIC_ERR, "No Makefile found");
make(filename, flags, argv[0]);
int res = make(filename, rules, argv[0], flags);
list_destroy(files);
list_destroy(rules);
return 0;
return res;
}

View file

@ -10,6 +10,7 @@
#include <string.h>
#include <unistd.h>
#include "files/files.h"
#include "hash_maps/hash_maps.h"
#include "lines/lines.h"
#include "lists/lists.h"
@ -459,21 +460,103 @@ void make_parse(char *path)
// ==== Runtime ====
// static void make_run(void)
// {}
// Expands and run a specified rule
static int run_rule(struct rule *rule)
{
struct list *commands = rule->recipe;
struct list *dependencies = rule->dependencies;
// Expand dependencies variables
// TODO
// Build dependencies
while (dependencies != NULL)
{
// 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);
}
}
}
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 ====
void make(char *path, int flags, char *argv0)
int make(char *path, struct list *rules, char *exec_name, int flags)
{
program_name = argv0;
program_name = exec_name;
make_parse(path);
if (flags & FLAGS_PRINT)
dump_database();
int status = make_run(rules);
free_all();
return status;
}
// Prints an error message before exiting gracefully (by freeing all variables)
@ -482,9 +565,9 @@ void drop(int status, char *format, ...)
// Print
va_list args;
va_start(args, format);
fprintf(stderr, "%s: ", program_name);
fprintf(stderr, "%s: *** ", program_name);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fprintf(stderr, ". Stop.\n");
va_end(args);
free_all();

View file

@ -10,8 +10,8 @@
#define FLAGS_PRINT 2
// Default values
#define DEFAULT_MAKEFILE "Makefile"
#define DEFAULT_MAKEFILE_2 "makefile"
#define DEFAULT_MAKEFILE "makefile"
#define DEFAULT_MAKEFILE_2 "Makefile"
#define BUFFER_SIZE 1024
#define HASHMAP_SIZE 32
@ -38,8 +38,9 @@ struct rule
struct list *recipe;
};
void make(char *path, int flags, char* program_name);
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);

View file

@ -0,0 +1 @@
VAR = 1

View file

@ -0,0 +1,5 @@
rule1:
echo Toto
rule2:
@echo Toto