diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 19 | ||||
-rw-r--r-- | src/common/extstr.c | 24 | ||||
-rw-r--r-- | src/common/fnv1a.c | 12 | ||||
-rw-r--r-- | src/common/fnv1a.h | 2 | ||||
-rw-r--r-- | src/common/io.c | 44 | ||||
-rw-r--r-- | src/common/io.h | 6 | ||||
-rw-r--r-- | src/common/xml.c | 15 | ||||
-rw-r--r-- | src/configuration.c | 427 | ||||
-rw-r--r-- | src/configuration.h | 96 | ||||
-rwxr-xr-x | src/core/Makefile.am | 15 | ||||
-rw-r--r-- | src/core/core.c | 76 | ||||
-rw-r--r-- | src/core/core.h | 40 | ||||
-rw-r--r-- | src/core/params.c | 112 | ||||
-rw-r--r-- | src/core/params.h (renamed from src/params.h) | 37 | ||||
-rw-r--r-- | src/editor.c | 8 | ||||
-rw-r--r-- | src/format/mangling/itanium/context.c | 2 | ||||
-rw-r--r-- | src/glibext/Makefile.am | 1 | ||||
-rw-r--r-- | src/glibext/configuration.c | 1232 | ||||
-rw-r--r-- | src/glibext/configuration.h | 199 | ||||
-rw-r--r-- | src/glibext/gbuffersegment.c | 2 | ||||
-rw-r--r-- | src/gtkext/gtkdockstation.c | 10 | ||||
-rw-r--r-- | src/gui/panels/Makefile.am | 1 | ||||
-rw-r--r-- | src/gui/panels/panel.c | 4 | ||||
-rw-r--r-- | src/gui/panels/regedit.c | 1071 | ||||
-rw-r--r-- | src/gui/panels/regedit.h | 65 | ||||
-rw-r--r-- | src/gui/panels/symbols.c | 4 | ||||
-rw-r--r-- | src/main.c | 25 | ||||
-rw-r--r-- | src/params.c | 61 | ||||
-rw-r--r-- | src/project.c | 10 |
29 files changed, 2961 insertions, 659 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 75d16d6..7a0ef4d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ -lib_LTLIBRARIES = libchrysaglibext.la libchrysadisass.la libchrysagtkext.la libchrysagui.la libchrysaplugin.la +lib_LTLIBRARIES = libchrysacore.la libchrysaglibext.la libchrysadisass.la libchrysagtkext.la libchrysagui.la libchrysaplugin.la bin_PROGRAMS = chrysalide @@ -13,6 +13,17 @@ bin_PROGRAMS = chrysalide #--- libchrysadisas +libchrysacore_la_SOURCES = + +libchrysacore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) \ + -Lcommon/.libs -lcommon + +libchrysacore_la_LIBADD = \ + core/libcore.la + + +#--- libchrysadisas + libchrysadisass_la_SOURCES = libchrysadisass_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) \ @@ -76,10 +87,8 @@ libchrysaplugin_la_LIBADD = \ ############################################################ chrysalide_SOURCES = \ - configuration.h configuration.c \ editor.h editor.c \ main.c \ - params.h params.c \ project.h project.c @@ -89,7 +98,7 @@ AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) chrysalide_LDFLAGS = $(LIBGTK_LIBS) -L/usr/X11R6/lib -ldl -lm $(LIBXML_LIBS) `pkg-config --libs gthread-2.0` $(LIBPYTHON_LIBS) $(LIBARCHIVE_LIBS) $(LIBSQLITE_LIBS) \ - -L.libs -lchrysaglibext -lchrysadisass -lchrysagtkext -lchrysagui \ + -L.libs -lchrysaglibext -lchrysadisass -lchrysagtkext -lchrysagui -lchrysacore \ -Lcommon/.libs -lcommon \ -Lplugins/.libs -lplugins @@ -105,6 +114,6 @@ chrysalide_LDADD = $(LIBINTL) \ # glibext doit être traité en premier, à cause des marshals GLib -SUBDIRS = glibext gtkext analysis arch format common debug decomp dialogs gui plugins +SUBDIRS = core glibext gtkext analysis arch format common debug decomp dialogs gui plugins # TODO: rm -rf panels diff --git a/src/common/extstr.c b/src/common/extstr.c index caffbcd..851401c 100644 --- a/src/common/extstr.c +++ b/src/common/extstr.c @@ -174,18 +174,15 @@ char *strrpl(char *haystack, const char *needle1, const char *needle2) size_t inlen; /* Taille en entrée */ size_t len1; /* Taille de l'aiguille n°1 */ size_t len2; /* Taille de l'aiguille n°2 */ - regex_t preg; /* Expression régulière */ - size_t curpos; /* Point de recherche */ - regmatch_t pmatch; /* Résultats remontés */ + char *found; /* Position d'une trouvaille */ inlen = strlen(haystack) + 1; len1 = strlen(needle1); len2 = strlen(needle2); - /* On considère que la compilation est toujours bonne... */ - regcomp(&preg, needle1, REG_EXTENDED | REG_ICASE); - - for (curpos = 0; regexec(&preg, &haystack[curpos], 1, &pmatch, 0) != REG_NOMATCH; ) + for (found = strstr(haystack, needle1); + found != NULL; + found = strstr(haystack, needle1)) { if (len1 != len2) { @@ -198,23 +195,16 @@ char *strrpl(char *haystack, const char *needle1, const char *needle2) haystack = (char *)realloc(haystack, inlen * sizeof(char *)); if (len2 > len1) - memmove(&haystack[curpos + pmatch.rm_eo + len2 - len1], &haystack[curpos + pmatch.rm_eo], - inlen - (len2 - len1) - curpos - pmatch.rm_eo); - + memmove(found + len2, found + len1, inlen - len1 - (found - haystack)); else - memmove(&haystack[curpos + pmatch.rm_eo + len1 - len2], &haystack[curpos + pmatch.rm_eo], - inlen - (len1 - len2) - curpos - pmatch.rm_eo); + memmove(found + len1, found + len2, inlen - len1 - (found - haystack)); } - memcpy(&haystack[curpos + pmatch.rm_so], needle2, len2); - - curpos += pmatch.rm_eo + len2; + memcpy(found, needle2, len2); } - regfree(&preg); - return haystack; } diff --git a/src/common/fnv1a.c b/src/common/fnv1a.c index c21a5e1..d017d70 100644 --- a/src/common/fnv1a.c +++ b/src/common/fnv1a.c @@ -40,15 +40,21 @@ * * * Description : Détermine si deux empreintes FNV1a sont indentiques ou non. * * * -* Retour : Bilan de la comparaison. * +* Retour : Bilan de la comparaison : -1, 0 ou 1. * * * * Remarques : - * * * ******************************************************************************/ -bool cmp_fnv_64a(fnv64_t a, fnv64_t b) +int cmp_fnv_64a(fnv64_t a, fnv64_t b) { - return (a == b); + int result; /* Bilan à retourner */ + + if (a < b) result = -1; + else if (a == b) result = 0; + else result = 1; + + return result; } diff --git a/src/common/fnv1a.h b/src/common/fnv1a.h index 294ce12..973781b 100644 --- a/src/common/fnv1a.h +++ b/src/common/fnv1a.h @@ -41,7 +41,7 @@ typedef uint64_t fnv64_t; /* Détermine si deux empreintes FNV1a sont indentiques ou non. */ -bool cmp_fnv_64a(fnv64_t, fnv64_t); +int cmp_fnv_64a(fnv64_t, fnv64_t); /* Détermine l'empreinte FNV1a d'une chaîne de caractères. */ fnv64_t fnv_64a_hash(const char *); diff --git a/src/common/io.c b/src/common/io.c index c3d3231..2275cb4 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -24,4 +24,48 @@ #include "io.h" +#include <libgen.h> +#include <malloc.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à valider. * +* * +* Description : S'assure qu'un chemin donné existe dans le système. * +* * +* Retour : 0 si le chemin est actuellement présent, -1 sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int ensure_path_exists(const char *path) +{ + int result; /* Bilan de l'assurance */ + char *copy; /* Chemin libérable */ + char *tmp; /* Chemin altérable */ + + copy = strdup(path); + tmp = dirname(copy); + + result = access(tmp, W_OK | X_OK); + + if (result != 0) + { + result = ensure_path_exists(tmp); + + if (result == 0) + result = mkdir(tmp, 0700); + + } + + free(copy); + + return result; + +} diff --git a/src/common/io.h b/src/common/io.h index 9145736..491d8d0 100644 --- a/src/common/io.h +++ b/src/common/io.h @@ -40,4 +40,10 @@ #define safe_write write + +/* S'assure qu'un chemin donné existe dans le système. */ +int ensure_path_exists(const char *); + + + #endif /* _COMMON_IO_H */ diff --git a/src/common/xml.c b/src/common/xml.c index 8c4cc81..36171b3 100644 --- a/src/common/xml.c +++ b/src/common/xml.c @@ -223,11 +223,24 @@ char *qck_get_node_text_value(xmlNodePtr node) result = NULL; if (node != NULL) + { if (node->children != NULL) if (node->children->content != NULL) result = strdup((char *)node->children->content); - if (result == NULL) XML_LOG(stderr, "No text value for node '%s'\n", node->name); + /** + * Si le noeud existe mais qu'il n'y pas de contenu, + * il faut marquer la différence entre deux retours NULL. + * + * On choisit donc : + * - NULL : pas de valeur trouvée car noeud non existant. + * - "" : pas de valeur trouvée, mais noeud bien présent. + */ + + if (result == NULL) + result = strdup(""); + + } return result; diff --git a/src/configuration.c b/src/configuration.c deleted file mode 100644 index 12feeb6..0000000 --- a/src/configuration.c +++ /dev/null @@ -1,427 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * configuration.c - éléments de configuration du programme - * - * Copyright (C) 2009-2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "configuration.h" - - -#include <libgen.h> -#include <malloc.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> - - -#include "common/extstr.h" -#include "common/xdg.h" -#include "common/xml.h" - - - -/* Paramètres de configuration */ -struct _configuration -{ - config_param *params; /* Paramètres à consulter */ - unsigned int count; /* Quantité de ces paramètres */ - - char *filename; /* Fichier externe */ - - xmlDocPtr xdoc; /* Document XML de configurat° */ - xmlXPathContextPtr context; /* Contexte de recherche XPath */ - -}; - - -/* S'assure qu'un chemin donné existe dans le système. */ -static int ensure_path_exists(const char *); - - - -/****************************************************************************** -* * -* Paramètres : name = désignation de la configuration. * -* params = tableau de paramètres à consulter / mettre à jour. * -* count = taille du tableau en question. * -* * -* Description : Charge la configuration principale. * -* * -* Retour : Configuration prête à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -configuration *load_configuration(const char *name, config_param *params, unsigned int count) -{ - configuration *result; /* Structure à retourner */ - char *suffix; /* Fin du nom de fichier */ - unsigned int i; /* Boucle de parcours */ - char *strval; /* Valeur en chaîne de carac. */ - - result = (configuration *)calloc(1, sizeof(configuration)); - - for (i = 0; i < count; i++) - params[i].cur = params[i].def; - - result->params = params; - result->count = count; - - suffix = strdup("openida/"); - suffix = stradd(suffix, name); - suffix = stradd(suffix, ".xml"); - - result->filename = get_xdg_config_dir(suffix); - - free(suffix); - - if (!open_xml_file(result->filename, &result->xdoc, &result->context)) - create_new_xml_file(&result->xdoc, &result->context); - - else - for (i = 0; i < count; i++) - switch (params[i].type) - { - case CVT_BOOLEAN: - strval = get_node_text_value(result->context, params[i].path); - if (strval != NULL) - { - set_boolean_config_value(result, i, strcmp(strval, "true") == 0); - free(strval); - } - break; - - case CVT_INTEGER: - strval = get_node_text_value(result->context, params[i].path); - if (strval != NULL) - { - set_integer_config_value(result, i, atoi(strval)); - free(strval); - } - break; - - case CVT_STRING: - strval = get_node_text_value(result->context, params[i].path); - set_string_config_value(result, i, strval); - if (strval != NULL) free(strval); - break; - - default: - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : path = chemin d'accès à valider. * -* * -* Description : S'assure qu'un chemin donné existe dans le système. * -* * -* Retour : 0 si le chemin est actuellement présent, -1 sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int ensure_path_exists(const char *path) -{ - int result; /* Bilan de l'assurance */ - char *tmp; /* Chemin altérable */ - - tmp = strdup(path); - tmp = dirname(tmp); - - result = access(tmp, W_OK | X_OK); - - if (result != 0) - { - result = ensure_path_exists(tmp); - - if (result == 0) - result = mkdir(tmp, 0700); - - } - - free(tmp); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à libérer de la mémoire. * -* * -* Description : Décharge la configuration principale. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void unload_configuration(configuration *config) -{ - int ret; /* Bilan de l'assurance */ - unsigned int i; /* Boucle de parcours */ - config_param *params; /* Confort d'utilisation */ - char tmp[12 /* -INT_MIN */]; /* Reconstruction en chaîne */ - - close_xml_file(config->xdoc, config->context); - - ret = ensure_path_exists(config->filename); - if (ret != 0) goto uc_exit; - - create_new_xml_file(&config->xdoc, &config->context); - - for (i = 0; i < config->count; i++) - { - params = &config->params[i]; - - switch (params->type) - { - case CVT_BOOLEAN: - if (params->cur.boolean == params->def.boolean) - continue; - - add_content_to_node(config->xdoc, config->context, - params->path, - params->cur.boolean ? "true" : "false"); - - break; - - case CVT_INTEGER: - if (params->cur.integer == params->def.integer) - continue; - - snprintf(tmp, 12, "%d", params->cur.integer); - add_content_to_node(config->xdoc, config->context, - params->path, tmp); - - break; - - case CVT_STRING: - - if (params->cur.string == NULL && params->def.string == NULL) - continue; - - if (params->def.string != NULL && params->def.string != NULL - && strcmp(params->cur.string, params->def.string) == 0) - continue; - - add_content_to_node(config->xdoc, config->context, - params->path, - params->cur.string != NULL ? params->cur.string : ""); - - break; - - default: - break; - - } - - } - - save_xml_file(config->xdoc, config->filename); - - uc_exit: - - free(config); - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* value = valeur à considérer comme valeur courante. * -* * -* Description : Définit une valeur booléenne dans la configuration. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool set_boolean_config_value(configuration *config, unsigned int index, bool value) -{ - if (index >= config->count) return false; - if (config->params[index].type != CVT_BOOLEAN) return false; - - config->params[index].defined = true; - - config->params[index].cur.boolean = value; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* * -* Description : Fournit une valeur booléenne issue de la configuration. * -* * -* Retour : Valeur courante ou par défaut de la configuration. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool get_boolean_config_value(configuration *config, unsigned int index) -{ - bool result; /* Valeur à retourner */ - - if (index >= config->count) return false; - if (config->params[index].type != CVT_BOOLEAN) return false; - - if (config->params[index].defined) result = config->params[index].cur.boolean; - else result = config->params[index].def.boolean; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* value = valeur à considérer comme valeur courante. * -* * -* Description : Définit une valeur entière dans la configuration. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool set_integer_config_value(configuration *config, unsigned int index, int value) -{ - if (index >= config->count) return false; - if (config->params[index].type != CVT_INTEGER) return false; - - config->params[index].defined = true; - - config->params[index].cur.integer = value; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* * -* Description : Fournit une valeur entière issue de la configuration. * -* * -* Retour : Valeur courante ou par défaut de la configuration. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int get_integer_config_value(configuration *config, unsigned int index) -{ - int result; /* Valeur à retourner */ - - if (index >= config->count) return 0; - if (config->params[index].type != CVT_INTEGER) return 0; - - if (config->params[index].defined) result = config->params[index].cur.integer; - else result = config->params[index].def.integer; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* value = valeur à considérer comme valeur courante. * -* * -* Description : Définit une chaîne de caractères dans la configuration. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool set_string_config_value(configuration *config, unsigned int index, const char *value) -{ - if (index >= config->count) return false; - if (config->params[index].type != CVT_STRING) return false; - - config->params[index].defined = true; - - if (config->params[index].cur.string != NULL) - free(config->params[index].cur.string); - - config->params[index].cur.string = (value != NULL ? strdup(value) : NULL); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* * -* Description : Fournit une chaîne de caractères issue de la configuration. * -* * -* Retour : Valeur courante ou par défaut de la configuration. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *get_string_config_value(configuration *config, unsigned int index) -{ - const char *result; /* Valeur à retourner */ - - if (index >= config->count) return NULL; - if (config->params[index].type != CVT_STRING) return NULL; - - if (config->params[index].defined) result = config->params[index].cur.string; - else result = config->params[index].def.string; - - return result; - -} diff --git a/src/configuration.h b/src/configuration.h deleted file mode 100644 index b77c52f..0000000 --- a/src/configuration.h +++ /dev/null @@ -1,96 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * configuration.h - prototypes pour les éléments de configuration du programme - * - * Copyright (C) 2009-2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#ifndef _CONFIGURATION_H -#define _CONFIGURATION_H - - -#include <stdbool.h> - - -/* Tyoes de valeur pour élement de configuration */ -typedef enum _ConfigValueType -{ - CVT_BOOLEAN, /* Valeur booléenne */ - CVT_INTEGER, /* Valeur entière */ - CVT_STRING, /* Chaîne de caractère */ - - CVT_COUNT - -} ConfigValueType; - -/* Valeurs supportées par les configurations */ -typedef union _config_value -{ - bool boolean; /* Valeur booléenne */ - int integer; /* Valeur entière */ - char *string; /* Chaîne de caractère */ - -} config_value; - -/* Eléments des configurations */ -typedef struct _config_param -{ - const char *path; /* Chemin d'accès XML */ - - ConfigValueType type; /* Type de valeur */ - - bool defined; /* Présence de valeur courante */ - - config_value def; /* Valeur par défaut */ - config_value cur; /* Valeur courante */ - -} config_param; - - -/* Paramètres de configuration */ -typedef struct _configuration configuration; - - -/* Charge la configuration principale. */ -configuration *load_configuration(const char *, config_param *, unsigned int); - -/* Décharge la configuration principale. */ -void unload_configuration(configuration *); - -/* Définit une valeur booléenne dans la configuration. */ -bool set_boolean_config_value(configuration *, unsigned int, bool); - -/* Fournit une valeur booléenne issue de la configuration. */ -bool get_boolean_config_value(configuration *, unsigned int); - -/* Définit une valeur entière dans la configuration. */ -bool set_integer_config_value(configuration *, unsigned int, int); - -/* Fournit une valeur entière issue de la configuration. */ -int get_integer_config_value(configuration *, unsigned int); - -/* Définit une chaîne de caractères dans la configuration. */ -bool set_string_config_value(configuration *, unsigned int, const char *); - -/* Fournit une chaîne de caractères issue de la configuration. */ -const char *get_string_config_value(configuration *, unsigned int); - - - -#endif /* _CONFIGURATION_H */ diff --git a/src/core/Makefile.am b/src/core/Makefile.am new file mode 100755 index 0000000..0724a3f --- /dev/null +++ b/src/core/Makefile.am @@ -0,0 +1,15 @@ + +noinst_LTLIBRARIES = libcore.la + +libcore_la_SOURCES = \ + core.h core.c \ + params.h params.c + +libcore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/core/core.c b/src/core/core.c new file mode 100644 index 0000000..d90dd5c --- /dev/null +++ b/src/core/core.c @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.c - chargement et le déchargement du tronc commun + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "core.h" + + +#include "params.h" + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Charge les éléments de base du programme. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_all_basic_components(void) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= load_main_config_parameters(); + + result &= g_generic_config_read(get_main_configuration()); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Décharge les éléments de base du programme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_all_basic_components(void) +{ + g_generic_config_write(get_main_configuration()); + + unload_main_config_parameters(); + +} diff --git a/src/core/core.h b/src/core/core.h new file mode 100644 index 0000000..2b0ef76 --- /dev/null +++ b/src/core/core.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.h - prototypes pour le chargement et le déchargement du tronc commun + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _CORE_CORE_H +#define _CORE_CORE_H + + +#include <stdbool.h> + + + +/* Charge les éléments de base du programme. */ +bool load_all_basic_components(void); + +/* Décharge les éléments de base du programme. */ +void unload_all_basic_components(void); + + + +#endif /* _CORE_CORE_H */ diff --git a/src/core/params.c b/src/core/params.c new file mode 100644 index 0000000..c8263f0 --- /dev/null +++ b/src/core/params.c @@ -0,0 +1,112 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * params.c - éléments de la configuration principale + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "params.h" + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède au chargement de la configuration principale. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_main_config_parameters(void) +{ + GGenConfig *config; /* Configuration à charger */ + GCfgParam *param; /* Paramètre chargé */ + + config = g_generic_config_new("main"); + set_main_configuration(config); + + param = g_generic_config_create_param(config, MPK_LAST_PROJECT, CPT_STRING, NULL); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_ELLIPSIS_HEADER, CPT_INTEGER, 54); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_ELLIPSIS_TAB, CPT_INTEGER, 35); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_KEYBINDINGS_EDIT, CPT_STRING, "<Shift>F2"); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_AUTO_SAVE, CPT_BOOLEAN, true); + if (param == NULL) return false; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède au déchargement de la configuration principale. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_main_config_parameters(void) +{ + GGenConfig *config; /* Configuration à décharger */ + + config = get_main_configuration(); + + g_object_unref(G_OBJECT(config)); + +} + + +/****************************************************************************** +* * +* Paramètres : config = éventuelle configuration à définir comme principale.* +* * +* Description : Fournit un lien vers la configuration principale. * +* * +* Retour : Configuration prête à emploi ou NULL si aucune définie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGenConfig *_get_main_configuration(GGenConfig *config) +{ + static GGenConfig *result = NULL; /* Structure à retourner */ + + if (config != NULL) + result = config; + + return result; + +} diff --git a/src/params.h b/src/core/params.h index 47c822d..b79cc3a 100644 --- a/src/params.h +++ b/src/core/params.h @@ -21,41 +21,38 @@ */ -#ifndef _PARAMS_H -#define _PARAMS_H +#ifndef _CORE_PARAMS_H +#define _CORE_PARAMS_H -#include "configuration.h" +#include "../glibext/configuration.h" -#ifndef NULL -# define NULL ((void *)0) -#endif +/** + * Clefs de paramètres de configuration principale. + */ +#define MPK_LAST_PROJECT "gui.editor.last_project" +#define MPK_ELLIPSIS_HEADER "gui.editor.panels.ellipsis_header" +#define MPK_ELLIPSIS_TAB "gui.editor.panels.ellipsis_tab" +#define MPK_KEYBINDINGS_EDIT "gui.key_bindings.global.edit" +#define MPK_AUTO_SAVE "project.autosave" -/* Eléments de la configuration principale */ - -typedef enum _MainParamType -{ - MPT_LAST_PROJECT, /* Dernier projet ouvert */ - MPT_ELLIPSIS_HEADER, /* Titre supérieur des panneaux*/ - MPT_ELLIPSIS_TAB, /* Titre inférieur des panneaux*/ - - MPT_AUTO_SAVE, /* Sauvegarde automatique ? */ - MPT_COUNT -} MainParamType; +/* Procède au chargement de la configuration principale. */ +bool load_main_config_parameters(void); +/* Procède au déchargement de la configuration principale. */ +void unload_main_config_parameters(void); #define set_main_configuration(cfg) _get_main_configuration(cfg) #define get_main_configuration() _get_main_configuration(NULL) - /* Fournit un lien vers la configuration principale. */ -configuration *_get_main_configuration(configuration *); +GGenConfig *_get_main_configuration(GGenConfig *); -#endif /* _PARAMS_H */ +#endif /* _CORE_PARAMS_H */ diff --git a/src/editor.c b/src/editor.c index d333cf5..d67c4d0 100644 --- a/src/editor.c +++ b/src/editor.c @@ -250,6 +250,7 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da result = FALSE; project = get_current_project(); + if (project == NULL) goto ode_no_project; if (g_study_project_get_filename(project) == NULL) { @@ -282,6 +283,8 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da } + ode_no_project: + return result; } @@ -303,7 +306,10 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da static void on_destroy_editor(GtkWidget *widget, gpointer data) { - g_object_unref(G_OBJECT(get_current_project())); + GStudyProject *project; /* Projet courant */ + + project = get_current_project(); + if (project != NULL) g_object_unref(G_OBJECT(project)); /* Fermeture propre */ diff --git a/src/format/mangling/itanium/context.c b/src/format/mangling/itanium/context.c index 87cb9ed..d4be54c 100644 --- a/src/format/mangling/itanium/context.c +++ b/src/format/mangling/itanium/context.c @@ -480,7 +480,7 @@ void g_itanium_dcontext_add_substitution(GItaniumDContext *context, itanium_comp hash = itd_hash_comp(comp); for (i = 0; i < context->subst_count; i++) - if (cmp_fnv_64a(itd_hash_comp(context->substitutions[i]), hash)) + if (cmp_fnv_64a(itd_hash_comp(context->substitutions[i]), hash) == 0) break; if (i == context->subst_count) diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 19ff59a..50b9902 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -5,6 +5,7 @@ noinst_LTLIBRARIES = libglibext.la libglibext_la_SOURCES = \ chrysamarshal.h chrysamarshal.c \ + configuration.h configuration.c \ delayed-int.h \ delayed.h delayed.c \ gbinportion.h gbinportion.c \ diff --git a/src/glibext/configuration.c b/src/glibext/configuration.c new file mode 100644 index 0000000..30cbcaf --- /dev/null +++ b/src/glibext/configuration.c @@ -0,0 +1,1232 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.c - éléments de configuration du programme + * + * Copyright (C) 2009-2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "configuration.h" + + +#include <assert.h> +#include <limits.h> +#include <malloc.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +#include "../common/cpp.h" +#include "../common/extstr.h" +#include "../common/fnv1a.h" +#include "../common/io.h" +#include "../common/xdg.h" +#include "../common/xml.h" + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Valeurs supportées par les paramètres */ +typedef union _param_value +{ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char *string; /* Chaîne de caractères */ + +} param_value; + +/* Configuration générique quelconque (instance) */ +struct _GCfgParam +{ + GObject parent; /* A laisser en premier */ + + char *path; /* Chemin d'accès XML */ + fnv64_t hash; /* Empreinte pour accès rapide */ + + ConfigParamType type; /* Type de valeur */ + + ConfigParamState cached_state; /* Etat du paramétrage */ + + param_value def; /* Valeur par défaut */ + bool def_empty; /* Non défini par défaut ? */ + param_value cur; /* Valeur courante */ + bool cur_empty; /* Actuellement non défini ? */ + +}; + +/* Configuration générique quelconque (classe) */ +struct _GCfgParamClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (*modified) (GCfgParam *); + +}; + + +/* Initialise la classe des blocs de données binaires. */ +static void g_config_param_class_init(GCfgParamClass *); + +/* Initialise une instance de bloc de données binaires. */ +static void g_config_param_init(GCfgParam *); + +/* Supprime toutes les références externes. */ +static void g_config_param_dispose(GCfgParam *); + +/* Procède à la libération totale de la mémoire. */ +static void g_config_param_finalize(GCfgParam *); + +/* Lit un paramètre de configuration depuis un fichier. */ +static bool g_config_param_read(GCfgParam *, xmlXPathContextPtr); + +/* Ecrit un paramètre de configuration dans un fichier. */ +static bool g_config_param_write(GCfgParam *, xmlDocPtr, xmlXPathContextPtr); + + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +/* Configuration générique quelconque (instance) */ +struct _GGenConfig +{ + GObject parent; /* A laisser en premier */ + + char *filename; /* CHemin d'accès complet */ + + GList *params; /* Eléments de configuration */ + GRWLock params_access; /* Verrou de protection */ + +}; + +/* Configuration générique quelconque (classe) */ +struct _GGenConfigClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des blocs de données binaires. */ +static void g_generic_config_class_init(GGenConfigClass *); + +/* Initialise une instance de bloc de données binaires. */ +static void g_generic_config_init(GGenConfig *); + +/* Supprime toutes les références externes. */ +static void g_generic_config_dispose(GGenConfig *); + +/* Procède à la libération totale de la mémoire. */ +static void g_generic_config_finalize(GGenConfig *); + + + +/* ---------------------------------------------------------------------------------- */ +/* ELEMENT DE CONFIGURATION */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour les configurations géénriques. */ +G_DEFINE_TYPE(GCfgParam, g_config_param, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des blocs de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_class_init(GCfgParamClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_config_param_dispose; + object->finalize = (GObjectFinalizeFunc)g_config_param_finalize; + + g_signal_new("modified", + G_TYPE_CFG_PARAM, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GCfgParamClass, modified), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance à initialiser. * +* * +* Description : Initialise une instance de bloc de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_init(GCfgParam *param) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_dispose(GCfgParam *param) +{ + G_OBJECT_CLASS(g_config_param_parent_class)->dispose(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_finalize(GCfgParam *param) +{ + free(param->path); + + switch (param->type) + { + case CPT_STRING: + if (param->def.string != NULL) + free(param->def.string); + if (param->cur.string != NULL) + free(param->cur.string); + break; + + default: + break; + + } + + G_OBJECT_CLASS(g_config_param_parent_class)->finalize(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à un paramètre en guise de clef. * +* type = type de paramètre à installer. * +* ... = valeur par défaut du paramètre. * +* * +* Description : Crée un paramètre de configuration. * +* * +* Retour : Elément mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *g_config_param_new(const char *path, ConfigParamType type, ...) +{ + GCfgParam *result; /* Structure à retourner */ + va_list ap; /* Liste d'arguments */ + + result = g_object_new(G_TYPE_CFG_PARAM, NULL); + + result->path = strdup(path); + result->hash = fnv_64a_hash(path); + + result->type = type; + + va_start(ap, type); + + switch (result->type) + { + case CPT_BOOLEAN: + result->def.boolean = va_arg(ap, /*bool*/int); + break; + + case CPT_INTEGER: + result->def.integer = va_arg(ap, int); + break; + + case CPT_STRING: + result->def.string = va_arg(ap, char *); + if (result->def.string != NULL) + result->def.string = strdup(result->def.string); + break; + + default: + g_object_unref(G_OBJECT(result)); + result = NULL; + assert(false); + break; + + } + + va_end(ap); + + g_config_param_reset(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à un paramètre en guise de clef. * +* type = type de paramètre à installer. * +* * +* Description : Crée un paramètre de configuration sans valeur. * +* * +* Retour : Elément mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *g_config_param_new_empty(const char *path, ConfigParamType type) +{ + GCfgParam *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_CFG_PARAM, NULL); + + result->path = strdup(path); + result->hash = fnv_64a_hash(path); + + result->type = type; + + g_config_param_make_empty(result); + + result->def = result->cur; + result->def_empty = true; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : config = paramètre de configuration à charger. * +* context = contexte de lecture d'un fichier XML. * +* * +* Description : Lit un paramètre de configuration depuis un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_config_param_read(GCfgParam *param, xmlXPathContextPtr context) +{ + char *access; /* Chemin d'accès XML */ + char *value; /* Valeur en chaîne de carac. */ + + access = strdup(param->path); + access = strrpl(access, ".", "/"); + access = strprep(access, "/ChrysalideConfig/"); + + value = get_node_text_value(context, access); + if (value == NULL) goto gcpr_no_value; + + if (strlen(value) == 0) + g_config_param_make_empty(param); + + else + switch (param->type) + { + case CPT_BOOLEAN: + g_config_param_set_value(param, strcmp(value, "true") == 0); + break; + + case CPT_INTEGER: + g_config_param_set_value(param, atoi(value)); + break; + + case CPT_STRING: + g_config_param_set_value(param, value); + break; + + default: + assert(false); + break; + + } + + free(value); + + gcpr_no_value: + + free(access); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : config = paramètre de configuration à charger. * +* xdoc = document XML à mettre en place. * +* context = contexte de lecture d'un fichier XML. * +* * +* Description : Ecrit un paramètre de configuration dans un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_config_param_write(GCfgParam *param, xmlDocPtr xdoc, xmlXPathContextPtr context) +{ + bool result; /* Bilan à retourner */ + ConfigParamState state; /* Etat du paramètre */ + char *access; /* Chemin d'accès XML */ + char int_val[sizeof(XSTR(INT_MIN)) + 1];/* Valeur en chaîne de carac. */ + + state = g_config_param_get_state(param); + + if (state & CPS_DEFAULT) + return true; + + result = true; + + access = strdup(param->path); + access = strrpl(access, ".", "/"); + access = strprep(access, "/ChrysalideConfig/"); + + if (state & CPS_EMPTY) + result = add_content_to_node(xdoc, context, access, ""); + + else + switch (param->type) + { + case CPT_BOOLEAN: + result = add_content_to_node(xdoc, context, access, + param->cur.boolean ? "true" : "false"); + break; + + case CPT_INTEGER: + snprintf(int_val, sizeof(int_val), "%d", param->cur.integer); + result = add_content_to_node(xdoc, context, access, int_val); + break; + + case CPT_STRING: + + if (param->def.string != NULL && param->def.string != NULL + && strcmp(param->cur.string, param->def.string) == 0) + break; + + result = add_content_to_node(xdoc, context, access, + param->cur.string != NULL ? param->cur.string : ""); + break; + + default: + assert(false); + break; + + } + + free(access); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à analyser. * +* path = chemin d'accès à retrouver. * +* * +* Description : Etablit une comparaison selon un chemin d'accès. * +* * +* Retour : -1, 0 ou 1 selon les conclusions de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint g_config_param_compare(const GCfgParam *param, const GCfgParam *path) +{ + gint result; /* Bilan à renvoyer */ + + result = cmp_fnv_64a(param->hash, path->hash); + + if (result == 0) + result = strcmp(param->path, path->path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à consulter. * +* * +* Description : Indique le chemin d'accès utilisé pour un paramètre. * +* * +* Retour : Clef servant de chemin d'accès. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_config_param_get_path(const GCfgParam *param) +{ + return param->path; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à consulter. * +* * +* Description : Indique le type de valeur utilisée par un paramètre. * +* * +* Retour : Type de paramètre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ConfigParamType g_config_param_get_ptype(const GCfgParam *param) +{ + return param->type; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à consulter. * +* * +* Description : Indique le statut d'une valeur utilisée par un paramètre. * +* * +* Retour : Etat de paramètre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ConfigParamState g_config_param_get_state(GCfgParam *param) +{ + if (param->cached_state == CPS_UNDEFINED) + { + if (param->def_empty || param->cur_empty) + { + param->cached_state = (param->def_empty && param->cur_empty ? CPS_DEFAULT : CPS_CHANGED); + param->cached_state |= CPS_EMPTY; + + goto gcpgs_recached; + + } + + switch (param->type) + { + case CPT_BOOLEAN: + param->cached_state = (param->def.boolean && param->cur.boolean ? CPS_DEFAULT : CPS_CHANGED); + break; + + case CPT_INTEGER: + param->cached_state = (param->def.integer == param->cur.integer ? CPS_DEFAULT : CPS_CHANGED); + break; + + case CPT_STRING: + if (param->def.string == NULL && param->cur.string == NULL) + param->cached_state = CPS_DEFAULT; + else if (param->def.string != NULL && param->cur.string != NULL) + param->cached_state = strcmp(param->def.string, param->cur.string) == 0 ? CPS_DEFAULT : CPS_CHANGED; + else + param->cached_state = CPS_CHANGED; + break; + + default: + break; + + } + + gcpgs_recached:; + + } + + return param->cached_state; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à mettre à jour. * +* * +* Description : Efface toute valeur courante d'un paramètre de configuration.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_make_empty(GCfgParam *param) +{ + switch (param->type) + { + case CPT_BOOLEAN: + param->cur.boolean = false; + break; + + case CPT_INTEGER: + param->cur.integer = INT_MIN; + break; + + case CPT_STRING: + if (param->cur.string != NULL) + { + free(param->cur.string); + param->cur.string = NULL; + } + break; + + default: + break; + + } + + if (!param->cur_empty) + { + param->cur_empty = true; + + /* Réinitialisation du cache d'état... */ + param->cached_state = CPS_UNDEFINED; + + g_signal_emit_by_name(param, "modified"); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à mettre à jour. * +* * +* Description : Réinitialise la valeur d'un paramètre de configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_reset(GCfgParam *param) +{ + bool modified; /* Détermine une modification */ + + modified = !(g_config_param_get_state(param) & CPS_DEFAULT); + + switch (param->type) + { + case CPT_BOOLEAN: + param->cur.boolean = param->def.boolean; + break; + + case CPT_INTEGER: + param->cur.integer = param->def.integer; + break; + + case CPT_STRING: + if (param->def.string != NULL) + param->cur.string = strdup(param->def.string); + else + param->cur.string = NULL; + break; + + default: + assert(false); + break; + + } + + if (modified) + { + param->cur_empty = param->def_empty; + + /* Réinitialisation du cache d'état... */ + param->cached_state = CPS_UNDEFINED; + + g_signal_emit_by_name(param, "modified"); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à mettre à jour. * +* ... = nouvelle valeur du paramètre. * +* * +* Description : Modifie la valeur courante d'un paramètre de configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_set_value(GCfgParam *param, ...) +{ + va_list ap; /* Liste d'arguments */ + bool old_boolean; /* Valeur booléenne */ + int old_integer; /* Valeur entière */ + char *old_string; /* Chaîne de caractères */ + bool modified; /* Détermine une modification */ + + va_start(ap, param); + + switch (param->type) + { + case CPT_BOOLEAN: + old_boolean = param->cur.boolean; + param->cur.boolean = va_arg(ap, /*bool*/int); + modified = (old_boolean != param->cur.boolean); + break; + + case CPT_INTEGER: + old_integer = param->cur.integer; + param->cur.integer = va_arg(ap, int); + modified = (old_integer != param->cur.integer); + break; + + case CPT_STRING: + old_string = param->cur.string; + param->cur.string = va_arg(ap, char *); + if (param->cur.string != NULL) + param->cur.string = strdup(param->cur.string); + + if (old_string == NULL && param->cur.string == NULL) + modified = false; + else if (old_string != NULL && param->cur.string != NULL) + modified = (strcmp(old_string, param->cur.string) != 0); + else + modified = true; + + if (old_string != NULL) + free(old_string); + + break; + + default: + assert(false); + modified = false; + break; + + } + + va_end(ap); + + if (modified) + { + param->cur_empty = false; + + /* Réinitialisation du cache d'état... */ + param->cached_state = CPS_UNDEFINED; + + g_signal_emit_by_name(param, "modified"); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à consulter. * +* ... = zone d'enregistrement de la valeur du paramètre. * +* * +* Description : Indique la valeur courante d'un paramètre de configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_get_value(GCfgParam *param, ...) +{ + va_list ap; /* Liste d'arguments */ + + va_start(ap, param); + + switch (param->type) + { + case CPT_BOOLEAN: + *(va_arg(ap, bool *)) = param->cur.boolean; + break; + + case CPT_INTEGER: + *(va_arg(ap, int *)) = param->cur.integer; + break; + + case CPT_STRING: + *(va_arg(ap, char **)) = param->cur.string; + break; + + default: + assert(false); + break; + + } + + va_end(ap); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION GENERIQUE DE CONFIGURATION */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour les configurations génériques. */ +G_DEFINE_TYPE(GGenConfig, g_generic_config, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des blocs de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_class_init(GGenConfigClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_generic_config_dispose; + object->finalize = (GObjectFinalizeFunc)g_generic_config_finalize; + + +} + + +/****************************************************************************** +* * +* Paramètres : config = instance à initialiser. * +* * +* Description : Initialise une instance de bloc de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_init(GGenConfig *config) +{ + g_rw_lock_init(&config->params_access); + +} + + +/****************************************************************************** +* * +* Paramètres : config = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_dispose(GGenConfig *config) +{ + GList *iter; /* Boucle de parcours */ + + for (iter = g_list_first(config->params); + iter != NULL; + iter = g_list_next(iter)) + { + g_object_unref(G_OBJECT(iter->data)); + } + + G_OBJECT_CLASS(g_generic_config_parent_class)->dispose(G_OBJECT(config)); + +} + + +/****************************************************************************** +* * +* Paramètres : config = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_finalize(GGenConfig *config) +{ + free(config->filename); + + g_rw_lock_clear(&config->params_access); + + G_OBJECT_CLASS(g_generic_config_parent_class)->finalize(G_OBJECT(config)); + +} + + +/****************************************************************************** +* * +* Paramètres : name = désignation de la configuration. * +* * +* Description : Crée une description de partie de code vierge. * +* * +* Retour : Elément mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGenConfig *g_generic_config_new(const char *name) +{ + GGenConfig *result; /* Structure à retourner */ + char *suffix; /* Fin du nom de fichier */ + + result = g_object_new(G_TYPE_GEN_CONFIG, NULL); + + suffix = strdup("chrysalide/"); + suffix = stradd(suffix, name); + suffix = stradd(suffix, ".xml"); + + result->filename = get_xdg_config_dir(suffix); + + free(suffix); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration à consulter.* +* * +* Description : Indique le fichier utilisé pour l'enregistrement XML. * +* * +* Retour : Chemin d'accès, potentiellement non existant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_generic_config_get_filename(const GGenConfig *config) +{ + return config->filename; + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à mettre à jour. * +* write = précise le type d'accès prévu (lecture/écriture). * +* lock = indique le sens du verrouillage à mener. * +* * +* Description : Met à disposition un encadrement des accès aux paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_generic_config_lock_unlock(GGenConfig *config, bool write, bool lock) +{ + if (write) + { + if (lock) g_rw_lock_writer_lock(&config->params_access); + else g_rw_lock_writer_unlock(&config->params_access); + } + else + { + if (lock) g_rw_lock_reader_lock(&config->params_access); + else g_rw_lock_reader_unlock(&config->params_access); + } + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration à charger. * +* * +* Description : Lit la configuration depuis un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_generic_config_read(GGenConfig *config) +{ + bool result; /* Bilan à retourner */ + int ret; /* Test de présence de fichier */ + xmlDocPtr xdoc; /* Document XML de configurat° */ + xmlXPathContextPtr context; /* Contexte de recherche XPath */ + GList *iter; /* Boucle de parcours */ + + ret = access(config->filename, F_OK); + if (ret != 0) return true; + + if (!open_xml_file(config->filename, &xdoc, &context)) + return false; + + g_generic_config_rlock(config); + + for (result = true, iter = g_list_first(config->params); + result && iter != NULL; + iter = g_list_next(iter)) + { + result = g_config_param_read(G_CFG_PARAM(iter->data), context); + } + + g_generic_config_runlock(config); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration à décharger.* +* * +* Description : Ecrit la configuration dans un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_generic_config_write(GGenConfig *config) +{ + bool result; /* Bilan à retourner */ + int ret; /* Bilan de l'assurance */ + xmlDocPtr xdoc; /* Document XML de configurat° */ + xmlXPathContextPtr context; /* Contexte de recherche XPath */ + GList *iter; /* Boucle de parcours */ + + ret = ensure_path_exists(config->filename); + if (ret != 0) return false; + + if (!create_new_xml_file(&xdoc, &context)) + return false; + + g_generic_config_rlock(config); + + for (result = true, iter = g_list_first(config->params); + result && iter != NULL; + iter = g_list_next(iter)) + { + result = g_config_param_write(G_CFG_PARAM(iter->data), xdoc, context); + } + + g_generic_config_runlock(config); + + save_xml_file(xdoc, config->filename); + + close_xml_file(xdoc, context); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration. * +* path = chemin d'accès au paramètre visé. * +* lock = pose un verrou si ce n'est déjà fait. * +* * +* Description : Retrouve un élément de configuration par son chemin. * +* * +* Retour : Elément trouvé ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *_g_generic_config_search(GGenConfig *config, const char *path, bool lock) +{ + GList *item; /* Elément générique de liste */ + GCfgParam fake; /* Faux élément partiel */ + + fake.path = (char *)path; + fake.hash = fnv_64a_hash(path); + + if (lock) + g_generic_config_rlock(config); + + item = g_list_find_custom(config->params, &fake, (GCompareFunc)g_config_param_compare); + + if (lock) + g_generic_config_runlock(config); + + return item ? item->data : NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à mettre à jour. * +* param = paramètre à intégrer dans la configuration. * +* * +* Description : Ajoute un paramètre à une configuration. * +* * +* Retour : Elément mis en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *g_generic_config_add_param(GGenConfig *config, GCfgParam *param) +{ + const char *path; /* Chemin d'accès unique */ + GCfgParam *old; /* Test de présence */ + + path = g_config_param_get_path(param); + + g_generic_config_wlock(config); + + old = _g_generic_config_search(config, path, false); + if (old != NULL) + { + g_object_unref(G_OBJECT(param)); + return NULL; + } + + config->params = g_list_append(config->params, param); + + g_generic_config_wunlock(config); + + return param; + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à mettre à jour. * +* path = chemin d'accès au paramètre visé. * +* * +* Description : Retire un paramètre d'une configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_generic_config_delete_param(GGenConfig *config, const char *path) +{ + GCfgParam *old; /* Test de présence */ + + g_generic_config_wlock(config); + + old = _g_generic_config_search(config, path, false); + + if (old != NULL) + config->params = g_list_remove(config->params, old); + + g_generic_config_wunlock(config); + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à consulter. * +* * +* Description : Renvoie la liste des paramètres de configuration. * +* * +* Retour : Liste d'éléments à parcourir. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GList *g_generic_config_list_params(const GGenConfig *config) +{ + /** + * Un verrou doit être posé ! + * Il n'y a pas d'assert() possible pour le vérifier... + */ + + return config->params; + +} diff --git a/src/glibext/configuration.h b/src/glibext/configuration.h new file mode 100644 index 0000000..84d494f --- /dev/null +++ b/src/glibext/configuration.h @@ -0,0 +1,199 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.h - prototypes pour les éléments de configuration du programme + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_CONFIGURATION_H +#define _GLIBEXT_CONFIGURATION_H + + +#include <glib-object.h> +#include <stdbool.h> + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Types de valeur pour élement de configuration */ +typedef enum _ConfigParamType +{ + CPT_BOOLEAN, /* Valeur booléenne */ + CPT_INTEGER, /* Valeur entière */ + CPT_STRING, /* Chaîne de caractère */ + + CPT_COUNT + +} ConfigParamType; + + +/* Liste dess états d'un paramètre de configuration */ +typedef enum _ConfigParamState +{ + CPS_UNDEFINED = (0 << 0), /* Etat non déterminé */ + CPS_CHANGED = (0 << 1), /* Modification utilisateur */ + CPS_DEFAULT = (1 << 1), /* Valeur par défaut */ + CPS_EMPTY = (1 << 2) /* Valeur vide */ + +} ConfigParamState; + + +#define G_TYPE_CFG_PARAM (g_config_param_get_type()) +#define G_CFG_PARAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CFG_PARAM, GCfgParam)) +#define G_IS_CFG_PARAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CFG_PARAM)) +#define G_CFG_PARAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CFG_PARAM, GCfgParamClass)) +#define G_IS_CFG_PARAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CFG_PARAM)) +#define G_CFG_PARAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CFG_PARAM, GCfgParamClass)) + + +/* Configuration générique quelconque (instance) */ +typedef struct _GCfgParam GCfgParam; + +/* Configuration générique quelconque (classe) */ +typedef struct _GCfgParamClass GCfgParamClass; + + +/* Indique le type défini par la GLib pour les configurations géénriques. */ +GType g_config_param_get_type(void); + +/* Crée un paramètre de configuration. */ +GCfgParam *g_config_param_new(const char *, ConfigParamType, ...); + +/* Crée un paramètre de configuration sans valeur. */ +GCfgParam *g_config_param_new_empty(const char *, ConfigParamType); + +/* Etablit une comparaison selon un chemin d'accès. */ +gint g_config_param_compare(const GCfgParam *, const GCfgParam *); + +/* Indique le chemin d'accès utilisé pour un paramètre. */ +const char *g_config_param_get_path(const GCfgParam *); + +/* Indique le type de valeur utilisée par un paramètre. */ +ConfigParamType g_config_param_get_ptype(const GCfgParam *); + +/* Indique le statut d'une valeur utilisée par un paramètre. */ +ConfigParamState g_config_param_get_state(GCfgParam *); + +/* Efface toute valeur courante d'un paramètre de configuration. */ +void g_config_param_make_empty(GCfgParam *); + +/* Réinitialise la valeur d'un paramètre de configuration. */ +void g_config_param_reset(GCfgParam *); + +/* Modifie la valeur courante d'un paramètre de configuration. */ +void g_config_param_set_value(GCfgParam *, ...); + +/* Indique la valeur courante d'un paramètre de configuration. */ +void g_config_param_get_value(GCfgParam *, ...); + + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +#define G_TYPE_GEN_CONFIG (g_generic_config_get_type()) +#define G_GEN_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GEN_CONFIG, GGenConfig)) +#define G_IS_GEN_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GEN_CONFIG)) +#define G_GEN_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GEN_CONFIG, GGenConfigClass)) +#define G_IS_GEN_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GEN_CONFIG)) +#define G_GEN_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GEN_CONFIG, GGenConfigClass)) + + +/* Configuration générique quelconque (instance) */ +typedef struct _GGenConfig GGenConfig; + +/* Configuration générique quelconque (classe) */ +typedef struct _GGenConfigClass GGenConfigClass; + + +/* Indique le type défini par la GLib pour les configurations génériques. */ +GType g_generic_config_get_type(void); + +/* Crée une description de partie de code vierge. */ +GGenConfig *g_generic_config_new(const char *); + +/* Indique le fichier utilisé pour l'enregistrement XML. */ +const char *g_generic_config_get_filename(const GGenConfig *); + +/* Met à disposition un encadrement des accès aux paramètres. */ +void g_generic_config_lock_unlock(GGenConfig *, bool, bool); + + +#define g_generic_config_wlock(cfg) g_generic_config_lock_unlock(cfg, true, true); +#define g_generic_config_wunlock(cfg) g_generic_config_lock_unlock(cfg, true, false); + +#define g_generic_config_rlock(cfg) g_generic_config_lock_unlock(cfg, false, true); +#define g_generic_config_runlock(cfg) g_generic_config_lock_unlock(cfg, false, false); + + +/* Lit la configuration depuis un fichier. */ +bool g_generic_config_read(GGenConfig *); + +/* Ecrit la configuration dans un fichier. */ +bool g_generic_config_write(GGenConfig *); + +/* Retrouve un élément de configuration par son chemin. */ +GCfgParam *_g_generic_config_search(GGenConfig *, const char *, bool); + + +#define g_generic_config_search(cfg, p) _g_generic_config_search(cfg, p, true) + +#define g_generic_config_set_value(c, p, ...) \ + ({ \ + GCfgParam *__param; \ + __param = g_generic_config_search(c, p); \ + if (__param != NULL) \ + g_config_param_set_value(__param, __VA_ARGS__); \ + __param != NULL ? true : false; \ + }) + +#define g_generic_config_get_value(c, p, ...) \ + ({ \ + GCfgParam *__param; \ + __param = g_generic_config_search(c, p); \ + if (__param != NULL) \ + g_config_param_get_value(__param, __VA_ARGS__); \ + __param != NULL ? true : false; \ + }) + + +/* Ajoute un paramètre à une configuration. */ +GCfgParam *g_generic_config_add_param(GGenConfig *, GCfgParam *); + + +#define g_generic_config_create_param(c, p, t, ...) \ + ({ \ + GCfgParam *__result; \ + __result = g_config_param_new(p, t, __VA_ARGS__); \ + __result = g_generic_config_add_param(c, __result); \ + __result; \ + }) + + +/* Retire un paramètre d'une configuration. */ +void g_generic_config_delete_param(GGenConfig *, const char *); + +/* Renvoie la liste des paramètres de configuration. */ +GList *g_generic_config_list_params(const GGenConfig *); + + + +#endif /* _GLIBEXT_CONFIGURATION_H */ diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c index a289cd0..e610a51 100644 --- a/src/glibext/gbuffersegment.c +++ b/src/glibext/gbuffersegment.c @@ -312,7 +312,7 @@ bool g_buffer_segment_compare(const GBufferSegment *segment, const GBufferSegmen { bool result; /* Bilan à retourner */ - result = cmp_fnv_64a(segment->hash, ref->hash); + result = (cmp_fnv_64a(segment->hash, ref->hash) == 0); result &= (strcmp(segment->text, ref->text) == 0); diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c index 157b286..b14e299 100644 --- a/src/gtkext/gtkdockstation.c +++ b/src/gtkext/gtkdockstation.c @@ -29,7 +29,7 @@ #include "easygtk.h" -#include "../params.h" +#include "../core/params.h" #include "../common/extstr.h" #include "../glibext/chrysamarshal.h" @@ -231,7 +231,8 @@ void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const char *str; /* Titre des prochaines fois */ GtkWidget *label; /* Etiquette d'onglet */ - max = 35; // TODO : config dans un .so pour Python // get_integer_config_value(get_main_configuration(), MPT_ELLIPSIS_TAB); + if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max)) + max = -1; str = ellipsis(strdup(caption), max); label = qck_create_label(NULL, NULL, str); @@ -250,7 +251,10 @@ void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const str = g_object_get_data(G_OBJECT(widget), "title"); if (str != NULL) free(str); - max = 54; // TODO : config dans un .so pour Python // get_integer_config_value(get_main_configuration(), MPT_ELLIPSIS_HEADER); + + if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_HEADER, &max)) + max = -1; + g_object_set_data(G_OBJECT(widget), "title", ellipsis(strdup(desc), max)); gtk_dock_panel_update_title(station, widget, desc); diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am index 12b51cb..0f7768c 100644 --- a/src/gui/panels/Makefile.am +++ b/src/gui/panels/Makefile.am @@ -5,6 +5,7 @@ libguipanels_la_SOURCES = \ glance.h glance.c \ log.h log.c \ panel.h panel.c \ + regedit.h regedit.c \ strings.h strings.c \ symbols.h symbols.c \ welcome.h welcome.c diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index 9a1e1c2..5a7fc53 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -33,6 +33,7 @@ #include "glance.h" #include "log.h" #include "panel-int.h" +#include "regedit.h" #include "strings.h" #include "symbols.h" #include "welcome.h" @@ -372,6 +373,9 @@ void load_main_panels(GObject *ref) g_signal_connect(_nodes->station, "dock-widget", G_CALLBACK(on_docking_to_main_panel), NULL); + item = create_regedit_panel(ref); + g_panel_item_dock(item); + item = create_log_panel(ref); g_panel_item_dock(item); diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c new file mode 100644 index 0000000..77fea39 --- /dev/null +++ b/src/gui/panels/regedit.c @@ -0,0 +1,1071 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * regedit.c - panneau d'affichage des paramètres de configuration + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "regedit.h" + + +#include <assert.h> +#include <malloc.h> +#include <regex.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <gtk/gtk.h> + + +#include "panel-int.h" +#include "../../core/params.h" +#include "../../common/cpp.h" +#include "../../common/extstr.h" +#include "../../gtkext/easygtk.h" + + + +/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ + + +/* Panneau d'affichage des paramètres de configuration (instance) */ +struct _GRegeditPanel +{ + GPanelItem parent; /* A laisser en premier */ + + GtkTreeView *treeview; /* Composant d'affichage */ + regex_t *filter; /* Filtre appliqué ou NULL */ + + GtkMenu *menu; /* Menu contextuel pour param. */ + +}; + +/* Panneau d'affichage des paramètres de configuration (classe) */ +struct _GRegeditPanelClass +{ + GPanelItemClass parent; /* A laisser en premier */ + +}; + + +/* Colonnes de la liste des messages */ +typedef enum _CfgParamColumn +{ + CPC_PARAM, /* Paramètre présenté */ + CPC_BOLD, /* Visuel des changements */ + + CPC_PATH, /* Chemin d'accès à une valeur */ + CPC_STATUS, /* Etat de la définition */ + CPC_TYPE, /* Type de paramètre */ + CPC_VALUE, /* Valeur courante */ + + LGC_COUNT /* Nombre de colonnes */ + +} CfgParamColumn; + + + + +/* Initialise la classe des panneaux des paramètres de config. */ +static void g_regedit_panel_class_init(GRegeditPanelClass *); + +/* Initialise une instance de panneau de paramètres de config. */ +static void g_regedit_panel_init(GRegeditPanel *); + +/* Supprime toutes les références externes. */ +static void g_regedit_panel_dispose(GRegeditPanel *); + +/* Procède à la libération totale de la mémoire. */ +static void g_regedit_panel_finalize(GRegeditPanel *); + + + +/* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */ + + +/* Recharge une configuration donnée à l'affichage. */ +static void reload_config_into_treeview(GRegeditPanel *, GGenConfig *); + +/* Actualise l'affichage des données d'un paramètre modifié. */ +static void on_config_param_modified(GCfgParam *, GRegeditPanel *); + +/* Actualise la valeur affichée d'un paramètre de configuration. */ +static void update_config_param_value(GtkTreeStore *, GtkTreeIter *); + +/* Etablit une comparaison entre deux lignes de paramètres. */ +static gint compare_config_list_columns(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer); + +/* Réagit à une pression sur <Shift+F2> et simule l'édition. */ +static gboolean on_key_pressed_over_params(GtkTreeView *, GdkEventKey *, GRegeditPanel *); + +/* Réagit à une édition de la valeur d'un paramètre. */ +static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTreeStore *); + + + +/* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */ + + +/* Démarre l'actualisation du filtrage des paramètres. */ +static void on_param_search_changed(GtkSearchEntry *, GRegeditPanel *); + +/*Détermine si un paramètre doit être filtré ou non. */ +static bool is_param_filtered(GRegeditPanel *, const char *); + + + +/* ------------------------ ATTRIBUTION D'UN MENU CONTEXTUEL ------------------------ */ + + +/* Assure la gestion des clics de souris sur les paramètres. */ +static gboolean on_button_press_over_params(GtkWidget *, GdkEventButton *, GRegeditPanel *); + +/* Construit le menu contextuel pour les paramètres. */ +GtkMenu *build_param_panel_menu(GRegeditPanel *); + +/* Fournit le paramètre sélectionné dans la liste. */ +static GCfgParam *get_selected_panel_param(GtkTreeView *, GtkTreeIter *); + +/* Réagit avec le menu "Copier le nom". */ +static void mcb_param_panel_copy(GtkMenuItem *, GRegeditPanel *); + +/* Réagit avec le menu "Valeur néant". */ +static void mcb_param_panel_empty(GtkMenuItem *, GRegeditPanel *); + +/* Réagit avec le menu "Réinitialiser la valeur". */ +static void mcb_param_panel_reset(GtkMenuItem *, GRegeditPanel *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTIE PRINCIPALE DU PANNEAU */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit pour un panneau d'aperçu de graphiques. */ +G_DEFINE_TYPE(GRegeditPanel, g_regedit_panel, G_TYPE_PANEL_ITEM); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des panneaux des paramètres de config. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_class_init(GRegeditPanelClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_regedit_panel_dispose; + object->finalize = (GObjectFinalizeFunc)g_regedit_panel_finalize; + + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance à initialiser. * +* * +* Description : Initialise une instance de panneau de paramètres de config. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_init(GRegeditPanel *panel) +{ + GEditorItem *base; /* Version basique d'instance */ + GObject *ref; /* Espace de référencement */ + GtkWidget *label; /* Etiquette à utiliser */ + GtkWidget *search; /* Zone de recherche */ + GtkWidget *scrolled; /* Fenêtre défilante */ + GtkTreeStore *store; /* Modèle de gestion */ + GtkWidget *treeview; /* Affichage de la liste */ + GtkCellRenderer *renderer; /* Moteur de rendu de colonne */ + GtkTreeViewColumn *column; /* Colonne de la liste */ + GtkTreeSortable *sortable; /* Autre vision de la liste */ + + base = G_EDITOR_ITEM(panel); + + base->widget = gtk_grid_new(); + gtk_widget_show(base->widget); + + gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8); + + ref = G_OBJECT(base->widget); + g_object_set_data(ref, "panel", panel); + + /* Partie recherche */ + + label = qck_create_label(NULL, NULL, _("Look for:")); + g_object_set(label, "margin", 8, NULL); + gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1); + + search = gtk_search_entry_new(); + g_signal_connect(search, "search-changed", G_CALLBACK(on_param_search_changed), panel); + gtk_widget_show(search); + gtk_widget_set_hexpand(search, TRUE); + gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1); + + /* Partie paramètres */ + + scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolled); + gtk_widget_set_vexpand(scrolled, TRUE); + gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); + + store = gtk_tree_store_new(LGC_COUNT, G_TYPE_OBJECT, G_TYPE_INT, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + + treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); + panel->treeview = GTK_TREE_VIEW(treeview); + + g_signal_connect(G_OBJECT(treeview), "button-press-event", + G_CALLBACK(on_button_press_over_params), panel); + g_signal_connect(G_OBJECT(treeview), "key-press-event", + G_CALLBACK(on_key_pressed_over_params), panel); + + gtk_widget_show(treeview); + gtk_container_add(GTK_CONTAINER(scrolled), treeview); + + g_object_unref(G_OBJECT(store)); + + /* Cellule d'affichage */ + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Access path"), renderer, + "text", CPC_PATH, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_PATH); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Status"), renderer, + "text", CPC_STATUS, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_STATUS); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Type"), renderer, + "text", CPC_TYPE, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_TYPE); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL); + g_signal_connect(renderer, "edited", G_CALLBACK(on_param_value_edited), store); + column = gtk_tree_view_column_new_with_attributes(_("Value"), renderer, + "text", CPC_VALUE, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_VALUE); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + /* Tri de la liste */ + + sortable = GTK_TREE_SORTABLE(store); + + gtk_tree_sortable_set_sort_func(sortable, CPC_PATH, compare_config_list_columns, + GINT_TO_POINTER(CPC_PATH), NULL); + + gtk_tree_sortable_set_sort_func(sortable, CPC_STATUS, compare_config_list_columns, + GINT_TO_POINTER(CPC_STATUS), NULL); + + gtk_tree_sortable_set_sort_func(sortable, CPC_TYPE, compare_config_list_columns, + GINT_TO_POINTER(CPC_TYPE), NULL); + + gtk_tree_sortable_set_sort_func(sortable, CPC_VALUE, compare_config_list_columns, + GINT_TO_POINTER(CPC_VALUE), NULL); + + gtk_tree_sortable_set_sort_column_id(sortable, CPC_PATH, GTK_SORT_ASCENDING); + + /* Préparation du menu contextuel */ + + panel->menu = build_param_panel_menu(panel); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_dispose(GRegeditPanel *panel) +{ + G_OBJECT_CLASS(g_regedit_panel_parent_class)->dispose(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_finalize(GRegeditPanel *panel) +{ + if (panel->filter != NULL) + regfree(panel->filter); + + G_OBJECT_CLASS(g_regedit_panel_parent_class)->finalize(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Crée un panneau d'affichage des paramètres de configuration. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEditorItem *g_regedit_panel_new(GObject *ref) +{ + GEditorItem *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_REGEDIT_PANEL, NULL); + + g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_REGEDIT_ID, + _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "M"); + + reload_config_into_treeview(G_REGEDIT_PANEL(result), get_main_configuration()); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Construit le panneau d'affichage des messages système. * +* * +* Retour : Adresse du panneau mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GPanelItem *create_regedit_panel(GObject *ref) +{ + GEditorItem *result; /* Elément réactif à renvoyer */ + + result = g_regedit_panel_new(ref); + + /* Enregistre correctement le tout */ + register_editor_item(result); + + return G_PANEL_ITEM(result); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* AFFICHAGE A L'AIDE D'UNE LISTE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : panel = panneau d'affichage de paramètres de configuration. * +* config = configuration à présenter à l'écran. * +* * +* Description : Recharge une configuration donnée à l'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config) +{ + GtkTreeStore *store; /* Modèle de gestion */ + GList *params; /* Paramètres de configuration */ + GCfgParam *param; /* Paramètre en cours d'étude */ + GList *p; /* Boucle de parcours */ + char *type_desc; /* Type de paramètre */ + GtkTreeIter iter; /* Point d'insertion */ + + store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview)); + gtk_tree_store_clear(store); + + g_generic_config_rlock(config); + + params = g_generic_config_list_params(config); + + for (p = g_list_first(params); p != NULL; p = g_list_next(p)) + { + param = G_CFG_PARAM(p->data); + + if (is_param_filtered(panel, g_config_param_get_path(param))) + continue; + + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + type_desc = _("Boolean"); + break; + + case CPT_INTEGER: + type_desc = _("Integer"); + break; + + case CPT_STRING: + type_desc = _("String"); + break; + + default: + type_desc = _("<Unknown type>"); + break; + + } + + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, + CPC_PARAM, param, + CPC_PATH, g_config_param_get_path(param), + CPC_TYPE, type_desc, + -1); + + update_config_param_value(store, &iter); + + g_signal_connect(param, "modified", G_CALLBACK(on_config_param_modified), panel); + + } + + g_generic_config_runlock(config); + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance dont le contenu a évolué. * +* panel = panneau d'affichage de paramètres à mettre à jour. * +* * +* Description : Actualise l'affichage des données d'un paramètre modifié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_config_param_modified(GCfgParam *param, GRegeditPanel *panel) +{ + GtkTreeModel *model; /* Gestionnaire de données */ + GtkTreeIter iter; /* Point de recherche */ + gboolean looping; /* Autorisation de bouclage */ + GCfgParam *item; /* Elément de la liste */ + + model = gtk_tree_view_get_model(panel->treeview); + + for (looping = gtk_tree_model_get_iter_first (model, &iter); + looping; + looping = gtk_tree_model_iter_next(model, &iter)) + { + gtk_tree_model_get(model, &iter, CPC_PARAM, &item, -1); + + if (item == param) + { + update_config_param_value(GTK_TREE_STORE(model), &iter); + break; + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : store = gestionnaire du tableau de données. * +* iter = point de modification dans les lignes. * +* param = paramètre dont la valeur est à afficher. * +* * +* Description : Actualise la valeur affichée d'un paramètre de configuration.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void update_config_param_value(GtkTreeStore *store, GtkTreeIter *iter) +{ + GCfgParam *param; /* Paramètre à consulter */ + ConfigParamState state; /* Etat du paramètre */ + char *state_desc; /* Version chaînée de l'état */ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char int_val[sizeof(XSTR(INT_MIN)) + 1];/* Valeur en chaîne de carac. */ + char *string; /* Chaîne de caractères */ + char *desc; /* Description à afficher */ + + gtk_tree_model_get(GTK_TREE_MODEL(store), iter, CPC_PARAM, ¶m, -1); + + state = g_config_param_get_state(param); + + if (state & CPS_DEFAULT) + state_desc = strdup(_("By default")); + else + state_desc = strdup(_("Changed")); + + if (state & CPS_EMPTY) + state_desc = stradd(state_desc, _(" + empty")); + + if (state & CPS_EMPTY) + desc = ""; + + else + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + g_config_param_get_value(param, &boolean); + desc = (boolean ? _("true") : _("false")); + break; + + case CPT_INTEGER: + g_config_param_get_value(param, &integer); + snprintf(int_val, sizeof(int_val), "%d", integer); + desc = int_val; + break; + + case CPT_STRING: + g_config_param_get_value(param, &string); + desc = (string != NULL ? string : ""); + break; + + default: + assert(false); + desc = "???"; + break; + + } + + gtk_tree_store_set(store, iter, + CPC_BOLD, state & CPS_DEFAULT ? 400 : 800, + CPC_STATUS, state_desc, + CPC_VALUE, desc, -1); + + free(state_desc); + + g_object_unref(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : model = gestionnaire du tableau de données. * +* a = première ligne de données à traiter. * +* b = seconde ligne de données à traiter. * +* column = indice de la colonne à considérer, encodée. * +* * +* Description : Etablit une comparaison entre deux lignes de paramètres. * +* * +* Retour : Indication de tri entre les deux lignes fournies. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gint compare_config_list_columns(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer column) +{ + gint result; /* Valeur calculée à retourner */ + gchar *value_a; /* Cellule de la ligne 'a' */ + gchar *value_b; /* Cellule de la ligne 'b' */ + + gtk_tree_model_get(model, a, GPOINTER_TO_INT(column), &value_a, -1); + gtk_tree_model_get(model, b, GPOINTER_TO_INT(column), &value_b, -1); + + if (value_a == NULL || value_b == NULL) + { + if (value_a == NULL && value_b == NULL) + result = 0; + else + result = (value_a == NULL ? -1 : 1); + } + else + result = g_utf8_collate(value_a,value_b); + + g_free(value_a); + g_free(value_b); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : treeview = composant graphique présentant les paramètres. * +* event = informations liées à l'événement. * +* panel = panneau d'affichage sur lequel s'appuyer. * +* * +* Description : Réagit à une pression sur <Shift+F2> et simule l'édition. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean on_key_pressed_over_params(GtkTreeView *treeview, GdkEventKey *event, GRegeditPanel *panel) +{ + const gchar *accelerator; /* Combinaison de raccourci */ + guint accel_key; /* Touche de raccourci */ + GdkModifierType accel_mod; /* Modifiateurs attendus aussi */ + GtkTreeIter iter; /* Point de la sélection */ + GtkTreeModel *model; /* Gestionnaire de données */ + GtkTreePath *path; /* Chemin d'accès à ce point */ + + if (!g_generic_config_get_value(get_main_configuration(), MPK_KEYBINDINGS_EDIT, &accelerator)) + return FALSE; + + if (accelerator == NULL) + return FALSE; + + gtk_accelerator_parse(accelerator, &accel_key, &accel_mod); + + if (event->keyval == accel_key && event->state == accel_mod) + { + if (get_selected_panel_param(treeview, &iter) != NULL) + { + model = gtk_tree_view_get_model(treeview); + path = gtk_tree_model_get_path(model, &iter); + + gtk_tree_view_set_cursor(treeview, path, + gtk_tree_view_get_column(treeview, CPC_VALUE - CPC_PATH), + TRUE); + + gtk_tree_path_free(path); + + } + + } + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : renderer = moteur de rendu pour la cellule. * +* path = chemin d'accès vers la cellule éditée. * +* new = nouvelle valeur sous forme de texte à valider. * +* store = gestionnaire des données de la liste affichée. * +* * +* Description : Réagit à une édition de la valeur d'un paramètre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gchar *new, GtkTreeStore *store) +{ + GtkTreePath *tree_path; /* Chemin d'accès natif */ + GtkTreeIter iter; /* Point de la modification */ + GCfgParam *param; /* Paramètre à actualiser */ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char *end; /* Pointeur vers '\0' final ? */ + + tree_path = gtk_tree_path_new_from_string(path); + if (tree_path == NULL) return; + + if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, tree_path)) + goto opve_bad_iter; + + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, CPC_PARAM, ¶m, -1); + + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + + if (strcmp(new, "true") != 0 && strcmp(new, "false") != 0) + goto opve_bad_value; + + boolean = (strcmp(new, "true") == 0); + g_config_param_set_value(param, boolean); + + break; + + case CPT_INTEGER: + + integer = strtol(new, &end, 10); + if (*end != '\0') goto opve_bad_value; + + g_config_param_set_value(param, integer); + + break; + + case CPT_STRING: + g_config_param_set_value(param, new); + break; + + default: + assert(false); + goto opve_bad_value; + break; + + } + + opve_bad_value: + + g_object_unref(G_OBJECT(param)); + + opve_bad_iter: + + gtk_tree_path_free(tree_path); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* FILTRAGE DES SYMBOLES PRESENTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : entry = entrée de texte contenant le filtre brut. * +* panel = panneau assurant l'affichage des paramètres. * +* * +* Description : Démarre l'actualisation du filtrage des paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_param_search_changed(GtkSearchEntry *entry, GRegeditPanel *panel) +{ + const gchar *text; /* Texte de l'utilisateur */ + int ret; /* Bilan de mise en place */ + GdkRGBA error; /* Couleur d'erreur */ + + if (panel->filter != NULL) + { + regfree(panel->filter); + free(panel->filter); + panel->filter = NULL; + } + + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + if (strlen(text) > 0) + { + panel->filter = (regex_t *)calloc(1, sizeof(regex_t)); + ret = regcomp(panel->filter, text, REG_EXTENDED); + + if (ret != 0) + { + free(panel->filter); + panel->filter = NULL; + + error.red = 1.0; + error.green = 0.0; + error.blue = 0.0; + error.alpha = 1.0; + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error); + + return; + + } + + } + + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); + + reload_config_into_treeview(panel, get_main_configuration()); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau assurant l'affichage des paramètres. * +* name = chemin d'accès au paramètre à traiter. * +* * +* Description : Détermine si un paramètre doit être filtré ou non. * +* * +* Retour : true si le paramètre ne doit pas être affiché, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool is_param_filtered(GRegeditPanel *panel, const char *name) +{ + regmatch_t match; /* Récupération des trouvailles*/ + int ret; /* Bilan du filtrage */ + + if (panel->filter == NULL) + return false; + + ret = regexec(panel->filter, name, 1, &match, 0); + if (ret == REG_NOMATCH) + return true; + + return false; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* ATTRIBUTION D'UN MENU CONTEXTUEL */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* panel = informations liées au panneau associé. * +* * +* Description : Assure la gestion des clics de souris sur les paramètres. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean on_button_press_over_params(GtkWidget *widget, GdkEventButton *event, GRegeditPanel *panel) +{ + if (event->button == 3) + gtk_menu_popup(panel->menu, NULL, NULL, NULL, NULL, event->button, event->time); + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau d'affichage des paramètres de configuration. * +* * +* Description : Construit le menu contextuel pour les paramètres. * +* * +* Retour : Panneau de menus mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkMenu *build_param_panel_menu(GRegeditPanel *panel) +{ + GtkWidget *result; /* Support à retourner */ + GtkWidget *submenuitem; /* Sous-élément de menu */ + + result = gtk_menu_new(); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Copy the name"), G_CALLBACK(mcb_param_panel_copy), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Make empty"), G_CALLBACK(mcb_param_panel_empty), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Reset"), G_CALLBACK(mcb_param_panel_reset), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + return GTK_MENU(result); + +} + + +/****************************************************************************** +* * +* Paramètres : treeview = liste d'affichage à consulter. * +* save = zone de conservation du point de trouvaille. [OUT]* +* * +* Description : Fournit le paramètre sélectionné dans la liste. * +* * +* Retour : Paramètre en cours d'édition ou NULL en cas de soucis. * +* * +* Remarques : Le résultat non nul est à déréférencer après usage. * +* * +******************************************************************************/ + +static GCfgParam *get_selected_panel_param(GtkTreeView *treeview, GtkTreeIter *save) +{ + GCfgParam *result; /* Paramètre à renvoyer */ + GtkTreeSelection *selection; /* Représentation de sélection */ + GtkTreeModel *model; /* Gestionnaire des données */ + GtkTreeIter iter; /* Point de la sélection */ + + result = NULL; + + selection = gtk_tree_view_get_selection(treeview); + + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + gtk_tree_model_get(model, &iter, CPC_PARAM, &result, -1); + + if (save != NULL) + *save = iter; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des paramètres de config. * +* * +* Description : Réagit avec le menu "Copier le nom". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_param_panel_copy(GtkMenuItem *menuitem, GRegeditPanel *panel) +{ + GCfgParam *param; /* Paramètre sélectionné */ + const char *content; /* Prochain contenu à diffuser */ + gint clen; /* Taille de ce contenu */ + GtkClipboard *clipboard; /* Presse-papiers à remplir */ + + param = get_selected_panel_param(panel->treeview, NULL); + if (param == NULL) return; + + content = g_config_param_get_path(param); + clen = g_utf8_strlen(content, -1); + + clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, content, clen); + + clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + gtk_clipboard_set_text(clipboard, content, clen); + + g_object_unref(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des paramètres de config. * +* * +* Description : Réagit avec le menu "Valeur néant". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_param_panel_empty(GtkMenuItem *menuitem, GRegeditPanel *panel) +{ + GCfgParam *param; /* Paramètre sélectionné */ + + param = get_selected_panel_param(panel->treeview, NULL); + if (param == NULL) return; + + g_config_param_make_empty(param); + + g_object_unref(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des paramètres de config. * +* * +* Description : Réagit avec le menu "Réinitialiser". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_param_panel_reset(GtkMenuItem *menuitem, GRegeditPanel *panel) +{ + GCfgParam *param; /* Paramètre sélectionné */ + + param = get_selected_panel_param(panel->treeview, NULL); + if (param == NULL) return; + + g_config_param_reset(param); + + g_object_unref(G_OBJECT(param)); + +} diff --git a/src/gui/panels/regedit.h b/src/gui/panels/regedit.h new file mode 100644 index 0000000..7166168 --- /dev/null +++ b/src/gui/panels/regedit.h @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * regedit.h - prototypes pour le panneau d'affichage des paramètres de configuration + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA 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. + * + * OpenIDA 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _GUI_PANELS_REGEDIT_H +#define _GUI_PANELS_REGEDIT_H + + +#include <i18n.h> + + +#include "panel.h" + + + +#define PANEL_REGEDIT_ID _("Configuration") + + +#define G_TYPE_REGEDIT_PANEL g_regedit_panel_get_type() +#define G_REGEDIT_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_regedit_panel_get_type(), GRegeditPanel)) +#define G_IS_REGEDIT_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_regedit_panel_get_type())) +#define G_REGEDIT_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_REGEDIT_PANEL, GRegeditPanelClass)) +#define G_IS_REGEDIT_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_REGEDIT_PANEL)) +#define G_REGEDIT_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_REGEDIT_PANEL, GRegeditPanelClass)) + + +/* Panneau d'affichage des paramètres de configuration (instance) */ +typedef struct _GRegeditPanel GRegeditPanel; + +/* Panneau d'affichage des paramètres de configuration (classe) */ +typedef struct _GRegeditPanelClass GRegeditPanelClass; + + +/* Indique le type définit pour un panneau d'affichage des paramètres de configuration. */ +GType g_regedit_panel_get_type(void); + +/* Crée un panneau d'affichage des paramètres de configuration. */ +GEditorItem *g_regedit_panel_new(GObject *); + +/* Construit le panneau d'affichage des messages système. */ +GPanelItem *create_regedit_panel(GObject *); + + + +#endif /* _GUI_PANELS_REGEDIT_H */ diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index e9cc637..064c31d 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -44,7 +44,7 @@ /* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ -/* Panneau d'aperçu de graphiques (instance) */ +/* Panneau d'affichage des symboles (instance) */ struct _GSymbolsPanel { GPanelItem parent; /* A laisser en premier */ @@ -58,7 +58,7 @@ struct _GSymbolsPanel }; -/* Panneau d'aperçu de graphiques (classe) */ +/* Panneau d'affichage des symboles (classe) */ struct _GSymbolsPanelClass { GPanelItemClass parent; /* A laisser en premier */ @@ -30,10 +30,11 @@ #include <i18n.h> #include "editor.h" -#include "params.h" #include "project.h" #include "analysis/db/server.h" #include "arch/processor.h" +#include "core/core.h" +#include "core/params.h" #include "format/format.h" #include "glibext/delayed.h" #include "glibext/gbinportion.h" @@ -42,11 +43,9 @@ #include "../revision.h" +// TODO : remme! #include "format/mangling/itanium/abi.h" - - -/* params.c : configuration générale */ -extern config_param main_params[MPT_COUNT]; +#include "analysis/db/cdb.h" @@ -66,7 +65,7 @@ static void show_version(void) { printf("\n"); - printf("-o- OpenIDA r%u -o-\n", REVISION); + printf("-o- Chrysalide r%u -o-\n", REVISION); printf(_("Last compiled on %s at %s\n"), __DATE__, __TIME__); printf("\n"); @@ -78,7 +77,7 @@ static void show_version(void) printf("\n"); } -#include "analysis/db/cdb.h" + /****************************************************************************** * * @@ -95,7 +94,6 @@ static void show_version(void) int main(int argc, char **argv) { - configuration *config; /* Configuration principale */ GtkWidget *editor; /* Fenêtre graphique */ GDbServer *server; /* Enregistrements locaux */ const char *filename; /* Chemin du dernier projet */ @@ -107,9 +105,6 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } - config = load_configuration("main", main_params, MPT_COUNT); - set_main_configuration(config); - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALE_DIR); textdomain(PACKAGE); @@ -119,6 +114,9 @@ int main(int argc, char **argv) setlocale (LC_ALL, ""); gtk_init(&argc, &argv); + if (!load_all_basic_components()) + return EXIT_FAILURE; + /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared @@ -176,7 +174,8 @@ int main(int argc, char **argv) /* Charge le dernier projet */ - filename = get_string_config_value(config, MPT_LAST_PROJECT); + if (!g_generic_config_get_value(get_main_configuration(), MPK_LAST_PROJECT, &filename)) + filename = NULL; if (filename == NULL) project = g_study_project_new(G_OBJECT(editor)); else project = g_study_project_open(G_OBJECT(editor), filename); @@ -193,7 +192,7 @@ int main(int argc, char **argv) exit_binary_portion_colors(); - unload_configuration(config); + unload_all_basic_components(); return EXIT_SUCCESS; diff --git a/src/params.c b/src/params.c deleted file mode 100644 index db57951..0000000 --- a/src/params.c +++ /dev/null @@ -1,61 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * params.c - éléments de la configuration principale - * - * Copyright (C) 2009-2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * OpenIDA 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. - * - * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "params.h" - - - -config_param main_params[MPT_COUNT] = { - - [MPT_LAST_PROJECT] = { "/OpenIDA/Editor/LastProject", CVT_STRING, false, { .string = NULL } }, - [MPT_ELLIPSIS_HEADER] = { "/OpenIDA/Editor/Panels/ellipsis_header", CVT_INTEGER, false, { .integer = 54 } }, - [MPT_ELLIPSIS_TAB] = { "/OpenIDA/Editor/Panels/ellipsis_tab", CVT_INTEGER, false, { .integer = 35 } }, - - [MPT_AUTO_SAVE] = { "/OpenIDA/Project/Autosave", CVT_BOOLEAN, false, { .boolean = true } }, - -}; - - - -/****************************************************************************** -* * -* Paramètres : config = éventuelle configuration à définir comme principale.* -* * -* Description : Fournit un lien vers la configuration principale. * -* * -* Retour : Configuration prête à emploi ou NULL si aucune définie. * -* * -* Remarques : - * -* * -******************************************************************************/ - -configuration *_get_main_configuration(configuration *config) -{ - static configuration *result = NULL; /* Structure à retourner */ - - if (config != NULL) - result = config; - - return result; - -} diff --git a/src/project.c b/src/project.c index bc3ec66..a555f2d 100644 --- a/src/project.c +++ b/src/project.c @@ -29,9 +29,9 @@ #include <string.h> -#include "params.h" -#include "common/xml.h" #include "analysis/binaries/file.h" +#include "common/xml.h" +#include "core/params.h" #include "gtkext/easygtk.h" #include "gtkext/gtkblockview.h" #include "gtkext/gtkgraphview.h" @@ -685,10 +685,6 @@ void push_project_into_recent_list(const GStudyProject *project) /* Pour la prochaine ouverture du programme... */ - set_string_config_value(get_main_configuration(), MPT_LAST_PROJECT, project->filename); - - /* Pour la prochaine ouverture du programme... */ - - set_string_config_value(get_main_configuration(), MPT_LAST_PROJECT, project->filename); + g_generic_config_set_value(get_main_configuration(), MPK_LAST_PROJECT, project->filename); } |