180 lines
4.2 KiB
C
180 lines
4.2 KiB
C
#define _GNU_SOURCE
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <err.h>
|
|
|
|
void parser(FILE *fd);
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc <= 1)
|
|
{
|
|
fprintf(stderr, "Usage: ./parser FILE\n");
|
|
return 1;
|
|
}
|
|
|
|
FILE *fd = fopen(argv[1], "r");
|
|
if (!fd)
|
|
{
|
|
fprintf(stderr, "Error opening file '%s'\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
parser(fd);
|
|
|
|
fclose(fd);
|
|
return 0;
|
|
}
|
|
|
|
char *get_id(char *buf, size_t buf_size, size_t *i)
|
|
{
|
|
size_t start_nb = 0;
|
|
short previous_number = 0;
|
|
for (; *i < buf_size; *i += 1)
|
|
{
|
|
if ((buf[*i] >= '0' && buf[*i] <= '9') || buf[*i] == 'L' || buf[*i] == 'C')
|
|
{
|
|
if (!start_nb)
|
|
start_nb = *i;
|
|
previous_number = 1;
|
|
}
|
|
else if (previous_number)
|
|
{
|
|
buf[*i] = 0;
|
|
return buf + start_nb;
|
|
}
|
|
}
|
|
errx(2, "Error when compiling, pin number not found in a digitalWrite");
|
|
}
|
|
|
|
char *get_state(char *buf, size_t buf_size, size_t *i)
|
|
{
|
|
for (; *i < buf_size - 3; *i += 1)
|
|
{
|
|
if (*i < buf_size - 4 && !strncmp("HIGH", buf + *i, 4))
|
|
{
|
|
buf[*i + 4] = 0;
|
|
return buf + *i;
|
|
}
|
|
if (!strncmp("LOW", buf + *i, 3))
|
|
{
|
|
buf[*i + 3] = 0;
|
|
return buf + *i;
|
|
}
|
|
}
|
|
errx(2, "Error when compiling, HIGH or LOW not found in a digitalWrite");
|
|
}
|
|
|
|
void skip_end(char *buf, size_t buf_size, size_t *i)
|
|
{
|
|
while (*i < buf_size && buf[*i] != ';')
|
|
*i += 1;
|
|
*i += 1;
|
|
}
|
|
|
|
size_t convert_fct(char *buf, size_t start, size_t buf_size, FILE *dst)
|
|
{
|
|
const size_t size_str = strlen("digitalWrite");
|
|
if (buf_size - start < size_str)
|
|
return start;
|
|
size_t index = start;
|
|
if (!strncmp("digitalWrite", (buf + start), size_str))
|
|
{
|
|
index += size_str + 1;
|
|
char *id = get_id(buf, buf_size, &index);
|
|
char *state = get_state(buf, buf_size, &index);
|
|
state[0] = (state[0] == 'H') ? '1' : '0';
|
|
fwrite("set_pin(", 1, 8, dst);
|
|
fwrite(id, 1, strlen(id), dst);
|
|
fwrite(", ", 1, 2, dst);
|
|
fwrite(state, 1, 1, dst);
|
|
fwrite(", &row, &col, sequence, pointer);", 1, 33, dst);
|
|
skip_end(buf, buf_size, &index);
|
|
}
|
|
else if (!strncmp("delay", (buf + start), 5))
|
|
{
|
|
index = buf_size;
|
|
}
|
|
return index;
|
|
}
|
|
void write_buf(char *buf, size_t start, size_t buf_size, FILE *dst, size_t *nb_bracket)
|
|
{
|
|
for (size_t i = start; i < buf_size; i++)
|
|
{
|
|
if (buf[i] == '}')
|
|
*nb_bracket -= 1;
|
|
else if (buf[i] == '{')
|
|
*nb_bracket += 1;
|
|
|
|
if (nb_bracket != 0)
|
|
{
|
|
size_t index = convert_fct(buf, i, buf_size, dst);
|
|
if (index < buf_size)
|
|
fwrite(buf + index, 1, 1, dst);
|
|
i = index;
|
|
}
|
|
}
|
|
}
|
|
|
|
size_t find_loop(char *buf, size_t buf_size)
|
|
{
|
|
for (size_t i = 0; i < buf_size - 6; i++)
|
|
{
|
|
if (!strncmp("loop()", (buf + i), 6))
|
|
{
|
|
return i + 6;
|
|
}
|
|
}
|
|
return buf_size + 1;
|
|
}
|
|
|
|
FILE *init_student()
|
|
{
|
|
FILE *student = fopen("./src/student.c", "w+");
|
|
FILE *default_student = fopen("./src/default_student.c", "r");
|
|
if (!student)
|
|
errx(1, "Failed to create file 'student.c'");
|
|
if (!default_student)
|
|
{
|
|
fclose(student);
|
|
errx(1, "Failed to open file 'default_student.c'");
|
|
}
|
|
int c;
|
|
while ((c = fgetc(default_student)) != EOF)
|
|
fputc(c, student);
|
|
fclose (default_student);
|
|
return student;
|
|
}
|
|
|
|
void parser(FILE *fd)
|
|
{
|
|
char *buf = NULL;
|
|
size_t buf_size = 0;
|
|
ssize_t bytes_read = 0;
|
|
size_t nb_bracket = -1;
|
|
short in_loop = 0;
|
|
FILE *student = init_student();
|
|
while ((bytes_read = getline(&buf, &buf_size, fd)) != -1)
|
|
{
|
|
if (in_loop)
|
|
{
|
|
write_buf(buf, 0, bytes_read, student, &nb_bracket);
|
|
}
|
|
else
|
|
{
|
|
size_t index_loop = find_loop(buf, buf_size);
|
|
if (index_loop != buf_size + 1)
|
|
{
|
|
in_loop = 1;
|
|
}
|
|
}
|
|
}
|
|
if (buf)
|
|
free(buf);
|
|
fclose(student);
|
|
if (!in_loop)
|
|
errx(2, "Could not find the main loop function");
|
|
}
|