#define _GNU_SOURCE #include #include #include #include #include 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"); }