/* Chrysalide - Outil d'analyse de fichiers binaires * line.c - ligne de contenu Yaml * * Copyright (C) 2019 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Chrysalide. If not, see . */ #include "line.h" #include #include #include /* Ligne de données au format Yaml (instance) */ struct _GYamlLine { GObject parent; /* A laisser en premier */ char *raw; /* Contenu brut de la ligne */ size_t number; /* Indice associé */ size_t indent; /* Niveau d'indentation */ bool is_list_item; /* Elément de liste ? */ const char *payload; /* Charge utile du contenu */ char *key; /* Clef de la ligne Yaml */ char *value; /* Valeyr de la ligne Yaml */ }; /* Ligne de données au format Yaml (classe) */ struct _GYamlLineClass { GObjectClass parent; /* A laisser en premier */ }; /* Initialise la classe des lignes de contenu Yaml. */ static void g_yaml_line_class_init(GYamlLineClass *); /* Initialise une instance de ligne de contenu Yaml. */ static void g_yaml_line_init(GYamlLine *); /* Supprime toutes les références externes. */ static void g_yaml_line_dispose(GYamlLine *); /* Procède à la libération totale de la mémoire. */ static void g_yaml_line_finalize(GYamlLine *); /* Indique le type défini pour une ligne de données au format Yaml. */ G_DEFINE_TYPE(GYamlLine, g_yaml_line, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe des lignes de contenu Yaml. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_line_class_init(GYamlLineClass *klass) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(klass); object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_line_dispose; object->finalize = (GObjectFinalizeFunc)g_yaml_line_finalize; } /****************************************************************************** * * * Paramètres : line = instance à initialiser. * * * * Description : Initialise une instance de ligne de contenu Yaml. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_line_init(GYamlLine *line) { line->raw = NULL; line->number = -1; line->indent = 0; line->is_list_item = false; line->payload = NULL; line->key = NULL; line->value = NULL; } /****************************************************************************** * * * Paramètres : line = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_line_dispose(GYamlLine *line) { G_OBJECT_CLASS(g_yaml_line_parent_class)->dispose(G_OBJECT(line)); } /****************************************************************************** * * * Paramètres : line = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_yaml_line_finalize(GYamlLine *line) { if (line->raw != NULL) free(line->raw); if (line->key != NULL) free(line->key); if (line->value != NULL) free(line->value); G_OBJECT_CLASS(g_yaml_line_parent_class)->finalize(G_OBJECT(line)); } /****************************************************************************** * * * Paramètres : raw = contenu brut d'une ligne au format Yaml. * * number = indice associé à la ligne. * * * * Description : Met en place un gestionnaire pour ligne au format Yaml. * * * * Retour : Instance mise en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GYamlLine *g_yaml_line_new(const char *raw, size_t number) { GYamlLine *result; /* Structure à retourner */ char *iter; /* Boucle de parcours */ bool string_content[2]; /* Ouvertures de chaînes */ bool escape; /* Echappement de marquant */ result = g_object_new(G_TYPE_YAML_LINE, NULL); result->raw = strdup(raw); result->number = number; /* Indentation */ for (iter = result->raw; *iter != '\0'; iter++) { if (*iter != ' ') break; result->indent++; } if (*iter == '-') { result->is_list_item = true; for (iter++; *iter != '\0'; iter++) if (*iter != ' ') break; } result->payload = iter; /* Eventuel couple clef/valeur */ string_content[0] = false; string_content[1] = false; for (; *iter != '\0'; iter++) { if (*iter == '\'' && !string_content[1]) { if (iter == result->payload) escape = false; else escape = *(iter - 1) == '\''; if (!escape) string_content[0] = !string_content[0]; } else if (*iter == '"' && !string_content[0]) { if (iter == result->payload) escape = false; else escape = *(iter - 1) == '\\'; if (!escape) string_content[1] = !string_content[1]; } else if (!string_content[0] && !string_content[1]) { if (*iter == ':') break; } } if (*iter != '\0') { result->key = strndup(result->payload, iter - result->payload); for (iter++; *iter != '\0'; iter++) if (*iter != ' ') break; if (*iter != '\0') result->value = strdup(iter); } return result; } /****************************************************************************** * * * Paramètres : line = ligne au format Yaml à consulter. * * * * Description : Fournit la taille de l'indentation d'une ligne Yaml. * * * * Retour : Taille de l'indentation rencontrée. * * * * Remarques : - * * * ******************************************************************************/ size_t g_yaml_line_count_indent(const GYamlLine *line) { size_t result; /* Quantité à retourner */ result = line->indent; return result; } /****************************************************************************** * * * Paramètres : line = ligne au format Yaml à consulter. * * * * Description : Indique si la ligne représente un élément de liste. * * * * Retour : Statut de l'état lié à une liste d'éléments. * * * * Remarques : - * * * ******************************************************************************/ bool g_yaml_line_is_list_item(const GYamlLine *line) { bool result; /* Statut à retourner */ result = line->is_list_item; return result; } /****************************************************************************** * * * Paramètres : line = ligne au format Yaml à consulter. * * * * Description : Fournit la charge utile associée à une ligne Yaml. * * * * Retour : Contenu sous forme de chaîne de caractères. * * * * Remarques : - * * * ******************************************************************************/ const char *g_yaml_line_get_payload(const GYamlLine *line) { const char *result; /* Valeur à retourner */ result = line->payload; return result; } /****************************************************************************** * * * Paramètres : line = ligne au format Yaml à consulter. * * * * Description : Fournit la clef associée à une ligne Yaml si elle existe. * * * * Retour : Clef sous forme de chaîne de caractères ou NULL. * * * * Remarques : - * * * ******************************************************************************/ const char *g_yaml_line_get_key(const GYamlLine *line) { char *result; /* Valeur à retourner */ result = line->key; return result; } /****************************************************************************** * * * Paramètres : line = ligne au format Yaml à consulter. * * * * Description : Fournit la valeur associée à une ligne Yaml si elle existe. * * * * Retour : Valeur sous forme de chaîne de caractères ou NULL. * * * * Remarques : - * * * ******************************************************************************/ const char *g_yaml_line_get_value(const GYamlLine *line) { char *result; /* Valeur à retourner */ result = line->value; return result; }