42_Scale

a small software to create and edit 42 (.yaml) scale files easily
Log | Files | Refs | Submodules | README | LICENSE | git clone https://git.ne02ptzero.me/git/42_Scale

commit c92b882fd4c7f3cc3d25d7b125d65952f5e433f5
parent f94f0b9237bbdea5c35fc2cf02775fd61e38ea9b
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Sat, 23 Apr 2016 17:51:31 +0200

Add(YAML Parser): Working !

Diffstat:
M.gitmodules | 3+++
M.ycm_extra_conf.py | 3++-
Minc/scale.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibs/libyaml | 1+
Asrcs/yaml.c | 236+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 305 insertions(+), 1 deletion(-)

diff --git a/.gitmodules b/.gitmodules @@ -1,3 +1,6 @@ [submodule "inc/nuklear"] path = inc/nuklear url = https://github.com/vurtun/nuklear.git +[submodule "libs/libyaml"] + path = libs/libyaml + url = https://github.com/yaml/libyaml.git diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py @@ -91,7 +91,8 @@ flags = [ '-nostdlib', '-nodefaultlibs', '-I', 'inc', -'-I', 'inc/nuklear' +'-I', 'inc/nuklear', +'-I', './libs/libyaml/include' ] diff --git a/inc/scale.h b/inc/scale.h @@ -7,11 +7,74 @@ # include <stddef.h> # include <execinfo.h> # include <unistd.h> +# include <yaml.h> # define ERROR(...) printf("\033[1;31mFATAL ERROR:\033[0m 42_scale must stop. \n\033[0;31m> Reason: \033[0m"); printf(__VA_ARGS__); print_trace(); _exit(1); +enum { + LANG_FR, + LANG_EN, + LANG_RU +}; + +enum { + R_BOOL, + R_MULTI, + R_STAND, + R_BONUS +}; + +/* Some typedef for clarity. + * NOTE: Those typedefs are not used in structures declaration, for type clarity. + * NOTE: MD = Markdown +*/ + +typedef struct s_skills scale_skills; +typedef struct s_questions scale_questions; +typedef struct s_sections scale_sections; +typedef struct s_scale scale; + +struct s_skills { + int percent; // Percentage (1-100) value of the skill + char *name; // Skill name + struct s_skills *next; // Pointer to the next skill +}; + +struct s_questions { + char *name; // Name of the question + char *guidelines; // Guidelines of the question (MD) + int rating; // Rating of the question (R_BOOL | R_MULTI) + int kind; // Type of question (R_STAND | R_BONUS) + struct s_skills *skills; // Pointer to s_skills struct + struct s_questions *next; // Pointer to the next question +}; + +struct s_sections { + char *name; // Name of the section + char *description; // Description of the section + struct s_questions *questions; // Pointer to s_questions struct + struct s_sections *next; // Pointer to the next section +}; + +struct s_scale { + char *name; // Name of the subject + int lang; // Language of the scale (Enum value LANG_*) + char *comment; // Comment about the scale + char *intro; // Introduction about the scale (MD) + char *disclaimer; // Disclaimer about the scale (MD) + char *guidelines; // Guidelines of the scale (MD) + int correction_n; // Corrections number + struct s_sections *sections; // Pointer to s_sections structs +}; + /* HELPERS (helpers.c) */ void print_trace(void); +char *m_strcpy(yaml_token_t token); +void scale_debug(scale *res); + +/* YAML (yaml.c) */ + +scale *read_scale(FILE *fd); #endif diff --git a/libs/libyaml b/libs/libyaml @@ -0,0 +1 @@ +Subproject commit e6aa721cc0e5a48f408c52355559fd36780ba32a diff --git a/srcs/yaml.c b/srcs/yaml.c @@ -0,0 +1,236 @@ +# include <scale.h> + +void read_base_infos(yaml_parser_t *parser, scale *res) { + yaml_token_t token; + int cur = 0; + char *key = 0x0, *tmp; + + token.type = YAML_STREAM_START_TOKEN; + res->sections = 0x0; + while (token.type != YAML_STREAM_END_TOKEN) { + if (!yaml_parser_scan(parser, &token)) { + ERROR("YAML parser error ! Error value: (%d)", parser->error); + } + if (token.type == YAML_KEY_TOKEN) { + cur = 1; + } else if (token.type == YAML_VALUE_TOKEN) { + cur = 2; + } else if (token.type == YAML_SCALAR_TOKEN) { + if (cur == 1) { + key = m_strcpy(token); + } else { + if (!strcmp(key, "name")) + res->name = m_strcpy(token); + else if (!strcmp(key, "comment")) + res->comment = m_strcpy(token); + else if (!strcmp(key, "introduction_md")) + res->intro = m_strcpy(token); + else if (!strcmp(key, "disclaimer_md")) + res->disclaimer = m_strcpy(token); + else if (!strcmp(key, "guidelines_md")) + res->guidelines = m_strcpy(token); + else if (!strcmp(key, "lang")) { + tmp = m_strcpy(token); + if (!strcmp(tmp, "en")) + res->lang = LANG_EN; + else if (!strcmp(tmp, "fr")) + res->lang = LANG_FR; + else if (!strcmp(tmp, "ru")) + res->lang = LANG_RU; + free(tmp); + } else if (!strcmp(key, "correction_number")) { + res->correction_n = atoi((char *)token.data.scalar.value); + } + free(key); + key = 0x0; + cur = 0; + } + } else if (token.type == 14) { + break ; + } + if (token.type != YAML_STREAM_END_TOKEN) { + yaml_token_delete(&token); + } + } + yaml_token_delete(&token); +} + +void read_skills(yaml_parser_t *parser, scale_questions *question) { + yaml_token_t token; + scale_skills *sk, *it; + int cur = 0, ct = 0; + char *key = 0x0, *tmp = 0x0; + + token.type = YAML_STREAM_START_TOKEN; + sk = malloc(sizeof(scale_skills)); + sk->next = 0x0; + (void)question; + while (token.type != YAML_STREAM_END_TOKEN) { + if (!yaml_parser_scan(parser, &token)) { + ERROR("YAML parser error ! Error value: (%d)", parser->error); + } + if (token.type == YAML_KEY_TOKEN) { + cur = 1; + } else if (token.type == YAML_VALUE_TOKEN) { + cur = 2; + } else if (token.type == YAML_SCALAR_TOKEN) { + if (cur == 1) { + key = m_strcpy(token); + } else { + if (!strcmp(key, "name")) { + sk->name = m_strcpy(token); + } else if (!strcmp(key, "percentage")) { + tmp = m_strcpy(token); + sk->percent = atoi(tmp); + free(tmp); + } + } + } else if (token.type == YAML_BLOCK_END_TOKEN) { + ct++; + if (ct == 2) + return ; + if (!question->skills) { + question->skills = sk; + } else { + for (it = question->skills; it->next; it = it->next); + it->next = sk; + } + sk->next = 0x0; + sk = malloc(sizeof(scale_skills)); + } else { + ct = 0; + } + } + +} + +void read_questions(yaml_parser_t *parser, scale_sections *sec) { + yaml_token_t token; + scale_questions *question, *it; + int cur = 0; + char *key = 0x0, *tmp = 0x0; + + question = malloc(sizeof(scale_questions)); + question->next = 0x0; + token.type = YAML_STREAM_START_TOKEN; + while (token.type != YAML_STREAM_END_TOKEN) { + if (!yaml_parser_scan(parser, &token)) { + ERROR("YAML parser error ! Error value: (%d)", parser->error); + } + if (token.type == YAML_KEY_TOKEN) { + cur = 1; + } else if (token.type == YAML_VALUE_TOKEN) { + cur = 2; + } else if (token.type == YAML_SCALAR_TOKEN) { + if (cur == 1) { + key = m_strcpy(token); + if (!strcmp(key, "questions_skills")) { + read_skills(parser, question); + if (!sec->questions) { + sec->questions = question; + } else { + for (it = sec->questions; it->next; it = it->next); + it->next = question; + } + question = malloc(sizeof(scale_questions)); + question->next = 0x0; + } + } else { + if (!strcmp(key, "name")) + question->name = m_strcpy(token); + else if (!strcmp(key, "guidelines")) + question->guidelines = m_strcpy(token); + else if (!strcmp(key, "rating")) { + tmp = m_strcpy(token); + if (!strcmp(tmp, "bool")) + question->rating = R_BOOL; + else if (!strcmp(tmp, "multi")) + question->rating = R_MULTI; + free(tmp); + } else if (!strcmp(key, "kind")) { + tmp = m_strcpy(token); + if (!strcmp(tmp, "standard")) + question->kind = R_STAND; + else if (!strcmp(tmp, "bonus")) + question->kind = R_BONUS; + } + free(key); + } + } else if (token.type == YAML_BLOCK_END_TOKEN) { + return ; + } + if (token.type != YAML_STREAM_END_TOKEN) { + yaml_token_delete(&token); + } + } + yaml_token_delete(&token); +} + +void read_sections(yaml_parser_t *parser, scale *res) { + yaml_token_t token; + int cur = 0; + char *key = 0x0; + scale_sections *sec, *it; + + token.type = YAML_STREAM_START_TOKEN; + sec = malloc(sizeof(scale_sections)); + sec->questions = 0x0; + sec->next = 0x0; + while (token.type != YAML_STREAM_END_TOKEN) { + if (!yaml_parser_scan(parser, &token)) { + ERROR("YAML parser error ! Error value: (%d)", parser->error); + } + if (token.type == YAML_KEY_TOKEN) { + cur = 1; + } else if (token.type == YAML_VALUE_TOKEN) { + cur = 2; + } else if (token.type == YAML_SCALAR_TOKEN) { + if (cur == 1) { + key = m_strcpy(token); + if (!strcmp(key, "questions")) { + read_questions(parser, sec); + if (!res->sections) { + res->sections = sec; + } else { + for (it = res->sections; it->next; it = it->next); + it->next = sec; + } + sec = malloc(sizeof(scale_sections)); + sec->questions = 0x0; + sec->next = 0x0; + } + } else { + if (!strcmp(key, "name")) + sec->name = m_strcpy(token); + else if (!strcmp(key, "description")) + sec->description = m_strcpy(token); + free(key); + key = 0x0; + cur = 0; + } + } + if (token.type != YAML_STREAM_END_TOKEN) { + yaml_token_delete(&token); + } + } + yaml_token_delete(&token); +} + +scale *read_scale(FILE *fd) { + yaml_parser_t parser; + scale *res; + + if (!yaml_parser_initialize(&parser)) { + ERROR("Failed to initialize YAML parser !\n"); + } + yaml_parser_set_input_file(&parser, fd); + if (!(res = malloc(sizeof(scale)))) { + ERROR("Malloc error !\n"); + } + read_base_infos(&parser, res); + read_sections(&parser, res); + scale_debug(res); + yaml_parser_delete(&parser); + fclose(fd); + return res; +}