summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-07-10 14:47:37 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-07-10 14:47:37 (GMT)
commitdb863244b804cbf4c06399f7c6f8241d91c9ee9b (patch)
treeda7cc911b0f10c5122536271235ab68f2202804a
parente8aa314462196cc9e8461ae23eb13f8bffcc983f (diff)
Fully rewritten the core configuration system.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@381 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog128
-rw-r--r--configure.ac2
-rw-r--r--plugins/pychrysa/Makefile.am8
-rw-r--r--plugins/pychrysa/analysis/binaries/file.c4
-rw-r--r--plugins/pychrysa/core/Makefile.am15
-rw-r--r--plugins/pychrysa/core/module.c91
-rw-r--r--plugins/pychrysa/core/module.h39
-rw-r--r--plugins/pychrysa/core/params.c178
-rw-r--r--plugins/pychrysa/core/params.h42
-rw-r--r--plugins/pychrysa/glibext/Makefile.am8
-rw-r--r--plugins/pychrysa/glibext/configuration.c1214
-rw-r--r--plugins/pychrysa/glibext/configuration.h66
-rw-r--r--plugins/pychrysa/glibext/module.c49
-rw-r--r--plugins/pychrysa/glibext/module.h6
-rw-r--r--plugins/pychrysa/pychrysa.c16
-rw-r--r--src/Makefile.am19
-rw-r--r--src/common/extstr.c24
-rw-r--r--src/common/fnv1a.c12
-rw-r--r--src/common/fnv1a.h2
-rw-r--r--src/common/io.c44
-rw-r--r--src/common/io.h6
-rw-r--r--src/common/xml.c15
-rw-r--r--src/configuration.c427
-rw-r--r--src/configuration.h96
-rwxr-xr-xsrc/core/Makefile.am15
-rw-r--r--src/core/core.c76
-rw-r--r--src/core/core.h40
-rw-r--r--src/core/params.c112
-rw-r--r--src/core/params.h (renamed from src/params.h)37
-rw-r--r--src/editor.c8
-rw-r--r--src/format/mangling/itanium/context.c2
-rw-r--r--src/glibext/Makefile.am1
-rw-r--r--src/glibext/configuration.c1232
-rw-r--r--src/glibext/configuration.h199
-rw-r--r--src/glibext/gbuffersegment.c2
-rw-r--r--src/gtkext/gtkdockstation.c10
-rw-r--r--src/gui/panels/Makefile.am1
-rw-r--r--src/gui/panels/panel.c4
-rw-r--r--src/gui/panels/regedit.c1071
-rw-r--r--src/gui/panels/regedit.h65
-rw-r--r--src/gui/panels/symbols.c4
-rw-r--r--src/main.c25
-rw-r--r--src/params.c61
-rw-r--r--src/project.c10
44 files changed, 4793 insertions, 693 deletions
diff --git a/ChangeLog b/ChangeLog
index 470aef1..68d7c81 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,109 @@
+14-07-10 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ Add the new Makefiles from the 'plugins/pychrysa/core' and 'src/core'
+ directories to AC_CONFIG_FILES.
+
+ * plugins/pychrysa/analysis/binaries/file.c:
+ Typo. Clean the code.
+
+ * plugins/pychrysa/core/Makefile.am:
+ * plugins/pychrysa/core/module.c:
+ * plugins/pychrysa/core/module.h:
+ * plugins/pychrysa/core/params.c:
+ * plugins/pychrysa/core/params.h:
+ New entries: add support for items found in 'src/core/'.
+
+ * plugins/pychrysa/glibext/configuration.c:
+ * plugins/pychrysa/glibext/configuration.h:
+ New entries: implement configuration in Python.
+
+ * plugins/pychrysa/glibext/Makefile.am:
+ Define a new libpychrysaglibext.la.
+
+ * plugins/pychrysa/glibext/module.c:
+ * plugins/pychrysa/glibext/module.h:
+ Update code.
+
+ * plugins/pychrysa/Makefile.am:
+ Add 'libpychrysacore.la' and 'libpychrysaglibext.la' to
+ pychrysalide_la_LIBADD, '-lchrysacore' to pychrysalide_la_LDFLAGS
+ and 'core' to SUBDIRS.
+
+ * plugins/pychrysa/pychrysa.c:
+ Update code. Load all basic components.
+
+ * src/common/extstr.c:
+ Do not rely on regex for replacements anymore. Thus, searching for a
+ simple dot works.
+
+ * src/common/fnv1a.c:
+ * src/common/fnv1a.h:
+ Extend the comparisons by return an integer instead of a boolean.
+
+ * src/common/io.c:
+ * src/common/io.h:
+ Provide a way to create the directories needed for an access path.
+
+ * src/common/xml.c:
+ Fix a kind of bug: make a difference between "no node" and "no value".
+
+ * src/configuration.c:
+ * src/configuration.h:
+ Moved entries: see the 'src/glibext/configuration.[ch]' files.
+
+ * src/core/core.c:
+ * src/core/core.h:
+ * src/core/Makefile.am:
+ * src/core/params.c:
+ * src/core/params.h:
+ New entries: centralize all core features for isolated plugins (for instance, Python).
+
+ * src/editor.c:
+ Fix bugs: check if there is a defined project or not when exiting.
+
+ * src/format/mangling/itanium/context.c:
+ Update code when calling cmp_fnv_64a().
+
+ * src/glibext/configuration.c:
+ * src/glibext/configuration.h:
+ New entries: fully rewrite the core configuration system.
+
+ * src/glibext/gbuffersegment.c:
+ Update code when calling cmp_fnv_64a().
+
+ * src/glibext/Makefile.am:
+ Add the 'configuration.[ch]' files to libglibext_la_SOURCES.
+
+ * src/gtkext/gtkdockstation.c:
+ Restore the old behavior with the main configuration.
+
+ * src/gui/panels/Makefile.am:
+ Add the 'regedit.[ch]' to libguipanels_la_SOURCES.
+
+ * src/gui/panels/panel.c:
+ Load and show the configuration panel ; this has to be updated.
+
+ * src/gui/panels/regedit.c:
+ * src/gui/panels/regedit.h:
+ New entries: provide a graphical panel to edit the main configuration.
+
+ * src/gui/panels/symbols.c:
+ Typo.
+
+ * src/main.c:
+ Update code.
+
+ * src/Makefile.am:
+ Inclue the core shared object.
+
+ * src/params.c
+ * src/params.h:
+ Move entries: see the 'src/core/params.[ch]' files.
+
+ * src/project.c:
+ Update code.<
+
14-06-25 Cyrille Bagard <nocbos@gmail.com>
* plugins/pychrysa/analysis/binaries/file.c:
@@ -982,7 +1088,7 @@
14-03-20 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Include the libarchive and SQLite to the project. Add the new Makfile
+ Include the libarchive and SQLite to the project. Add the new Makefile
from the 'src/analysis/db' directory to AC_CONFIG_FILES.
* src/analysis/binary.c:
@@ -1305,7 +1411,7 @@
13-06-14 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfile from the 'plugins/pychrysa/format/elf' directory
+ Add the new Makefile from the 'plugins/pychrysa/format/elf' directory
to AC_CONFIG_FILES.
* plugins/pychrysa/format/elf/elf.c:
@@ -1452,7 +1558,7 @@
13-03-19 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfiles from the 'src/gtkext/graph/nodes' directories
+ Add the new Makefiles from the 'src/gtkext/graph/nodes' directories
to AC_CONFIG_FILES.
* plugins/pychrysa/analysis/blocks/flow.c:
@@ -1807,7 +1913,7 @@
13-01-26 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfiles from the 'plugins/pychrysa/analysis/blocks' and
+ Add the new Makefiles from the 'plugins/pychrysa/analysis/blocks' and
'plugins/python/samples' directories to AC_CONFIG_FILES.
* plugins/pychrysa/analysis/block.c:
@@ -2272,7 +2378,7 @@
12-12-22 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfile from the 'plugins/pychrysa/analysis/binaries'
+ Add the new Makefile from the 'plugins/pychrysa/analysis/binaries'
directory to AC_CONFIG_FILES.
* plugins/pychrysa/analysis/binaries/file.c:
@@ -2397,7 +2503,7 @@
12-12-18 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfile from the 'plugins/pychrysa/gtkext directory to
+ Add the new Makefile from the 'plugins/pychrysa/gtkext directory to
AC_CONFIG_FILES.
* plugins/pychrysa/glibext/module.c:
@@ -2625,7 +2731,7 @@
12-12-08 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfile from the 'src/analysis/blocks' directory to
+ Add the new Makefile from the 'src/analysis/blocks' directory to
AC_CONFIG_FILES.
* plugins/androhelpers/androhelpers.c:
@@ -2884,7 +2990,7 @@
12-11-19 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfiles from the 'plugins/androhelpers' and
+ Add the new Makefiles from the 'plugins/androhelpers' and
'plugins/pychrysa/format/dex' directories to AC_CONFIG_FILES.
Remove the old 'plugins/dexresolver' one.
@@ -3277,7 +3383,7 @@
12-10-18 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfiles from the src/arch/x86/opcodes and
+ Add the new Makefiles from the src/arch/x86/opcodes and
src/arch/x86/operands directories to AC_CONFIG_FILES.
* src/arch/dalvik/operands/register.c:
@@ -3530,7 +3636,7 @@
12-10-12 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfiles from the src/analysis/types directory to
+ Add the new Makefiles from the src/analysis/types directory to
AC_CONFIG_FILES.
* plugins/dexresolver/operand.c:
@@ -3642,7 +3748,7 @@
12-09-15 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
- Add the new Makfiles from the plugins/pychrysa/gui and
+ Add the new Makefiles from the plugins/pychrysa/gui and
plugins/pychrysa/gui/panels directories to AC_CONFIG_FILES.
* plugins/pychrysa/arch/instruction.c:
diff --git a/configure.ac b/configure.ac
index e318ba4..846cc82 100644
--- a/configure.ac
+++ b/configure.ac
@@ -276,6 +276,7 @@ AC_CONFIG_FILES([Makefile
plugins/pychrysa/analysis/binaries/Makefile
plugins/pychrysa/analysis/blocks/Makefile
plugins/pychrysa/arch/Makefile
+ plugins/pychrysa/core/Makefile
plugins/pychrysa/debug/Makefile
plugins/pychrysa/format/Makefile
plugins/pychrysa/format/dex/Makefile
@@ -313,6 +314,7 @@ AC_CONFIG_FILES([Makefile
src/arch/x86/opcodes/Makefile
src/arch/x86/operands/Makefile
src/common/Makefile
+ src/core/Makefile
src/debug/Makefile
src/debug/jdwp/Makefile
src/debug/jdwp/misc/Makefile
diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am
index 8664193..8c59c10 100644
--- a/plugins/pychrysa/Makefile.am
+++ b/plugins/pychrysa/Makefile.am
@@ -27,11 +27,13 @@ pychrysalide_la_SOURCES = \
pychrysalide_la_LIBADD = \
analysis/libpychrysaanalysis.la \
- arch/libpychrysaarch.la
+ arch/libpychrysaarch.la \
+ core/libpychrysacore.la \
+ glibext/libpychrysaglibext.la
pychrysalide_la_LDFLAGS = -module -avoid-version \
$(LIBPYTHON_LIBS) $(LIBSQLITE_LIBS) $(LIBARCHIVE_LIBS) \
- -L../../src/.libs -lchrysadisass -lchrysagtkext \
+ -L../../src/.libs -lchrysadisass -lchrysagtkext -lchrysacore \
-L../../src/plugins/.libs -lplugins
@@ -41,4 +43,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = analysis arch debug format glibext gtkext gui
+SUBDIRS = analysis arch core debug format glibext gtkext gui
diff --git a/plugins/pychrysa/analysis/binaries/file.c b/plugins/pychrysa/analysis/binaries/file.c
index e5cc2f1..6bf553b 100644
--- a/plugins/pychrysa/analysis/binaries/file.c
+++ b/plugins/pychrysa/analysis/binaries/file.c
@@ -155,7 +155,7 @@ PyTypeObject *get_python_binary_file_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.*
+* Description : Prend en charge l'objet 'pychrysalide.analysis.BinaryFile'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -174,7 +174,7 @@ bool register_python_binary_file(PyObject *module)
py_binary_file_type->tp_base = get_python_loaded_binary_type();
py_binary_file_type->tp_basicsize = py_binary_file_type->tp_base->tp_basicsize;
- if (PyType_Ready(py_binary_file_type) < 0)
+ if (PyType_Ready(py_binary_file_type) != 0)
return false;
Py_INCREF(py_binary_file_type);
diff --git a/plugins/pychrysa/core/Makefile.am b/plugins/pychrysa/core/Makefile.am
new file mode 100644
index 0000000..1ffacf4
--- /dev/null
+++ b/plugins/pychrysa/core/Makefile.am
@@ -0,0 +1,15 @@
+
+noinst_LTLIBRARIES = libpychrysacore.la
+
+libpychrysacore_la_SOURCES = \
+ module.h module.c \
+ params.h params.c
+
+
+libpychrysacore_la_LDFLAGS =
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I../../../src
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/pychrysa/core/module.c b/plugins/pychrysa/core/module.c
new file mode 100644
index 0000000..489f173
--- /dev/null
+++ b/plugins/pychrysa/core/module.c
@@ -0,0 +1,91 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire core en tant que module
+ *
+ * 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 "module.h"
+
+
+#include "params.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Ajoute le module 'core' au module Python. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_core_module_to_python_module(PyObject *super)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *module; /* Sous-module mis en place */
+ int ret; /* Bilan d'un appel */
+
+ static PyModuleDef py_chrysalide_core_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.core",
+ .m_doc = "Python module for Chrysalide.core",
+
+ .m_size = -1,
+
+ };
+
+ result = false;
+
+ module = PyModule_Create(&py_chrysalide_core_module);
+ if (module == NULL) return false;
+
+ ret = PyState_AddModule(super, &py_chrysalide_core_module);
+ if (ret != 0) goto acmtpm_exit;
+
+ ret = _PyImport_FixupBuiltin(module, "pychrysalide.core");
+ if (ret != 0) goto acmtpm_exit;
+
+ Py_INCREF(module);
+ ret = PyModule_AddObject(super, "core", module);
+ if (ret != 0) goto acmtpm_exit;
+
+ result = true;
+
+ result &= register_python_params(module);
+
+ acmtpm_exit:
+
+ if (!result)
+ {
+ printf("something went wrong in %s...\n", __FUNCTION__);
+ /* ... */
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysa/core/module.h b/plugins/pychrysa/core/module.h
new file mode 100644
index 0000000..1da57a1
--- /dev/null
+++ b/plugins/pychrysa/core/module.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire core en tant que module
+ *
+ * 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 _PLUGINS_PYCHRYSALIDE_CORE_MODULE_H
+#define _PLUGINS_PYCHRYSALIDE_CORE_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'core' au module Python. */
+bool add_core_module_to_python_module(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_CORE_MODULE_H */
diff --git a/plugins/pychrysa/core/params.c b/plugins/pychrysa/core/params.c
new file mode 100644
index 0000000..987bca6
--- /dev/null
+++ b/plugins/pychrysa/core/params.c
@@ -0,0 +1,178 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * params.c - équivalent Python du fichier "core/params.c"
+ *
+ * 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 "params.h"
+
+
+#include <pygobject.h>
+
+
+#include <core/params.h>
+
+
+
+/* Fournit la version du programme global. */
+static PyObject *py_params_get_main_configuration(PyObject *, PyObject *);
+
+/* Définit les constantes pour les paramètres. */
+static bool py_params_define_constants(PyObject *);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : self = NULL car méthode statique. *
+* args = non utilisé ici. *
+* *
+* Description : Fournit la version du programme global. *
+* *
+* Retour : Numéro de révision. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_params_get_main_configuration(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance GLib à retourner */
+ GGenConfig *config; /* Configuration à convertir */
+
+ config = get_main_configuration();
+
+ result = pygobject_new(G_OBJECT(config));
+ Py_XINCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_params_type(void)
+{
+ static PyMethodDef py_params_methods[] = {
+
+ { "get_main_configuration", py_params_get_main_configuration,
+ METH_NOARGS | METH_STATIC,
+ "Give access to the main configuration of Chrysalide."
+ },
+ { NULL }
+
+ };
+
+ static PyTypeObject py_params_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.core.params",
+ .tp_basicsize = sizeof(PyObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "Python object for parameters",
+
+ .tp_methods = py_params_methods
+
+ };
+
+ return &py_params_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dict = dictionnaire à compléter. *
+* *
+* Description : Définit les constantes pour les paramètres. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_params_define_constants(PyObject *dict)
+{
+ int ret; /* Bilan d'un ajout */
+
+#define DEF_STR_CONST(name) \
+ ret = PyDict_SetItemString(dict, #name, PyUnicode_FromString(name)); \
+ if (ret == -1) return false;
+
+ DEF_STR_CONST(MPK_LAST_PROJECT);
+ DEF_STR_CONST(MPK_ELLIPSIS_HEADER);
+ DEF_STR_CONST(MPK_ELLIPSIS_TAB);
+ DEF_STR_CONST(MPK_KEYBINDINGS_EDIT);
+ DEF_STR_CONST(MPK_AUTO_SAVE);
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.core.params'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_params(PyObject *module)
+{
+ PyTypeObject *py_params_type; /* Type Python pour 'params' */
+ int ret; /* Bilan d'un appel */
+
+ py_params_type = get_python_params_type();
+
+ py_params_type->tp_new = PyType_GenericNew;
+
+ if (PyType_Ready(py_params_type) != 0)
+ return false;
+
+ if (!py_params_define_constants(py_params_type->tp_dict))
+ return false;
+
+ Py_INCREF(py_params_type);
+ ret = PyModule_AddObject(module, "params", (PyObject *)py_params_type);
+
+ return (ret == 0);
+
+}
diff --git a/plugins/pychrysa/core/params.h b/plugins/pychrysa/core/params.h
new file mode 100644
index 0000000..23d1db5
--- /dev/null
+++ b/plugins/pychrysa/core/params.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * params.h - prototypes pour l'équivalent Python du fichier "core/params.h"
+ *
+ * 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 _PLUGINS_PYCHRYSALIDE_CORE_PARAMS_H
+#define _PLUGINS_PYCHRYSALIDE_CORE_PARAMS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_params_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.core.params'. */
+bool register_python_params(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_CORE_PARAMS_H */
diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am
index 14ab026..8383434 100644
--- a/plugins/pychrysa/glibext/Makefile.am
+++ b/plugins/pychrysa/glibext/Makefile.am
@@ -1,9 +1,13 @@
noinst_LTLIBRARIES = libpychrysaglibext.la
+# libpychrysaglibext_la_SOURCES = \
+# bufferline.h bufferline.c \
+# codebuffer.h codebuffer.c \
+# module.h module.c
+
libpychrysaglibext_la_SOURCES = \
- bufferline.h bufferline.c \
- codebuffer.h codebuffer.c \
+ configuration.h configuration.c \
module.h module.c
diff --git a/plugins/pychrysa/glibext/configuration.c b/plugins/pychrysa/glibext/configuration.c
new file mode 100644
index 0000000..9820af3
--- /dev/null
+++ b/plugins/pychrysa/glibext/configuration.c
@@ -0,0 +1,1214 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * configuration.c - prototypes pour l'équivalent Python du fichier "glibext/configuration.c"
+ *
+ * Copyright (C) 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "configuration.h"
+
+
+#include <pygobject.h>
+
+
+#include <glibext/configuration.h>
+
+
+
+/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */
+
+
+/* Crée un nouvel objet Python de type 'ConfigParam'. */
+static PyObject *py_config_param_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Efface toute valeur courante d'un paramètre de configuration. */
+static PyObject *py_config_param_make_empty(PyObject *, PyObject *);
+
+/* Réinitialise la valeur d'un paramètre de configuration. */
+static PyObject *py_config_param_reset(PyObject *, PyObject *);
+
+/* Indique le chemin d'accès utilisé pour un paramètre. */
+static PyObject *py_config_param_get_path(PyObject *, void *);
+
+/* Indique le type de valeur utilisée par un paramètre. */
+static PyObject *py_config_param_get_type(PyObject *, void *);
+
+/* Indique le statut d'une valeur utilisée par un paramètre. */
+static PyObject *py_config_param_get_state(PyObject *, void *);
+
+/* Indique la valeur courante d'un paramètre de configuration. */
+static PyObject *py_config_param_get_value(PyObject *, void *);
+
+/* Modifie la valeur courante d'un paramètre de configuration. */
+static int py_config_param_set_value(PyObject *, PyObject *, void *);
+
+/* Définit les constantes pour les paramètres. */
+static bool py_config_param_define_constants(PyObject *);
+
+
+
+/* ----------------------------- PARCOURS DE PARAMETRES ----------------------------- */
+
+
+
+typedef struct _pyConfigParamIterator
+{
+
+ PyObject_HEAD
+ long int m;
+ long int i;
+
+
+
+ GGenConfig *config; /* Configuration à parcourir */
+ GList *params; /* Liste de paramètres */
+
+ GList *last; /* Dernier élément retourné */
+
+} pyConfigParamIterator;
+
+
+
+
+/* Prend acte d'un compteur de référence à 0. */
+static void py_config_param_iterator_dealloc(PyObject *);
+
+/* Fournit un itérateur pour paramètres de configuration. */
+static PyObject *py_config_param_iterator_iter(PyObject *);
+
+/* Fournit un itérateur pour paramètres de configuration. */
+static PyObject *py_config_param_iterator_next(PyObject *);
+
+/* Initialise un objet Python de type 'ConfigParamIterator'. */
+static int py_config_param_iterator_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */
+
+
+/* Crée un nouvel objet Python de type 'GenConfig'. */
+static PyObject *py_generic_config_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Lit la configuration depuis un fichier. */
+static PyObject *py_generic_config_read(PyObject *, PyObject *);
+
+/* Ecrit la configuration dans un fichier. */
+static PyObject *py_generic_config_write(PyObject *, PyObject *);
+
+/* Retrouve un élément de configuration par son chemin. */
+static PyObject *py_generic_config_search(PyObject *, PyObject *);
+
+/* Ajoute un paramètre à une configuration. */
+static PyObject *py_generic_config_add(PyObject *, PyObject *);
+
+/* Retire un paramètre d'une configuration. */
+static PyObject *py_generic_config_delete(PyObject *, PyObject *);
+
+/* Fournit le chemin d'accès au binaire représenté. */
+static PyObject *py_generic_config_get_filename(PyObject *, void *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ELEMENT DE CONFIGURATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de l'objet à instancier. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Crée un nouvel objet Python de type 'ConfigParam'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Instance à retourner */
+ char *path; /* Accès au paramètre */
+ unsigned int ptype; /* Type de paramètre */
+ PyObject *value; /* Valeur par défaut éventuelle*/
+ int ret; /* Bilan de lecture des args. */
+ GCfgParam *param; /* Paramètre mis en place */
+
+ value = NULL;
+
+ ret = PyArg_ParseTuple(args, "sI|O", &path, &ptype, &value);
+ if (!ret) Py_RETURN_NONE;
+
+ if (value == NULL || value == Py_None)
+ param = g_config_param_new_empty(path, ptype);
+
+ else
+ switch (ptype)
+ {
+ case CPT_BOOLEAN:
+ if (PyBool_Check(value))
+ param = g_config_param_new(path, CPT_BOOLEAN, (bool)(value == Py_True));
+ else
+ param = NULL;
+ break;
+
+ case CPT_INTEGER:
+ if (PyLong_Check(value))
+ param = g_config_param_new(path, CPT_INTEGER, (int)PyLong_AsLong(value));
+ else
+ param = NULL;
+ break;
+
+ case CPT_STRING:
+ if (PyUnicode_Check(value))
+ param = g_config_param_new(path, CPT_STRING, PyUnicode_DATA(value));
+ else
+ param = NULL;
+ break;
+
+ default:
+ param = NULL;
+ break;
+
+ }
+
+ if (param != NULL)
+ {
+ result = pygobject_new(G_OBJECT(param));
+ g_object_unref(param);
+ }
+ else result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = paramètre de configuration à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Efface toute valeur courante d'un paramètre de configuration.*
+* *
+* Retour : None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_make_empty(PyObject *self, PyObject *args)
+{
+ GCfgParam *param; /* Paramètre visé par l'opérat°*/
+
+ param = G_CFG_PARAM(pygobject_get(self));
+
+ g_config_param_make_empty(param);
+
+ Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = paramètre de configuration à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Réinitialise la valeur d'un paramètre de configuration. *
+* *
+* Retour : None. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_reset(PyObject *self, PyObject *args)
+{
+ GCfgParam *param; /* Paramètre visé par l'opérat°*/
+
+ param = G_CFG_PARAM(pygobject_get(self));
+
+ g_config_param_reset(param);
+
+ Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = paramètre de configuration à manipuler. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique le chemin d'accès utilisé pour un paramètre. *
+* *
+* Retour : Chemin d'accès en Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_get_path(PyObject *self, void *closure)
+{
+ GCfgParam *param; /* Paramètre visé par l'opérat°*/
+ const char *path; /* Chemin d'accès à diffuser */
+
+ param = G_CFG_PARAM(pygobject_get(self));
+ path = g_config_param_get_path(param);
+
+ return PyUnicode_FromString(path);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = paramètre de configuration à manipuler. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique le type de valeur utilisée par un paramètre. *
+* *
+* Retour : Type en Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_get_type(PyObject *self, void *closure)
+{
+ GCfgParam *param; /* Paramètre visé par l'opérat°*/
+ ConfigParamType type; /* Type de paramètre */
+
+ param = G_CFG_PARAM(pygobject_get(self));
+ type = g_config_param_get_ptype(param);
+
+ return PyLong_FromLong(type);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = paramètre de configuration à manipuler. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique le statut d'une valeur utilisée par un paramètre. *
+* *
+* Retour : Etat en Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_get_state(PyObject *self, void *closure)
+{
+ GCfgParam *param; /* Paramètre visé par l'opérat°*/
+ ConfigParamState state; /* Statut de paramètre */
+
+ param = G_CFG_PARAM(pygobject_get(self));
+ state = g_config_param_get_state(param);
+
+ return PyLong_FromLong(state);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = paramètre de configuration à manipuler. *
+* closure = non utilisé ici. *
+* *
+* Description : Indique la valeur courante d'un paramètre de configuration. *
+* *
+* Retour : Etat en Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_get_value(PyObject *self, void *closure)
+{
+ PyObject *result; /* Valeur à retourner */
+ GCfgParam *param; /* Paramètre visé par l'opérat°*/
+ ConfigParamType type; /* Type de paramètre manipulé */
+ bool boolean; /* Valeur booléenne */
+ int integer; /* Valeur entière */
+ char *string; /* Chaîne de caractères */
+
+ param = G_CFG_PARAM(pygobject_get(self));
+ type = g_config_param_get_ptype(param);
+
+ switch (type)
+ {
+ case CPT_BOOLEAN:
+ g_config_param_get_value(param, &boolean);
+ result = (boolean ? Py_True : Py_False);
+ Py_INCREF(result);
+ break;
+
+ case CPT_INTEGER:
+ g_config_param_get_value(param, &integer);
+ result = PyLong_FromLong(integer);
+ break;
+
+ case CPT_STRING:
+ g_config_param_get_value(param, &string);
+ if (string != NULL)
+ result = PyUnicode_FromString(string);
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ break;
+
+ default:
+ result = NULL;
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = paramètre de configuration à manipuler. *
+* value = nouvelle valeur à convertir et définir. *
+* closure = non utilisé ici. *
+* *
+* Description : Modifie la valeur courante d'un paramètre de configuration. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_config_param_set_value(PyObject *self, PyObject *value, void *closure)
+{
+ int result; /* Conclusion à remonter */
+ GCfgParam *param; /* Paramètre visé par l'opérat°*/
+ ConfigParamType type; /* Type de paramètre manipulé */
+
+ result = -1;
+
+ param = G_CFG_PARAM(pygobject_get(self));
+
+ if (value == Py_None)
+ {
+ g_config_param_make_empty(param);
+ result = 0;
+ }
+
+ else
+ {
+ type = g_config_param_get_ptype(param);
+
+ switch (type)
+ {
+ case CPT_BOOLEAN:
+ if (PyBool_Check(value))
+ {
+ g_config_param_set_value(param, (bool)(value == Py_True));
+ result = 0;
+ }
+ break;
+
+ case CPT_INTEGER:
+ if (PyLong_Check(value))
+ {
+ g_config_param_set_value(param, (int)PyLong_AsLong(value));
+ result = 0;
+ }
+ break;
+
+ case CPT_STRING:
+ if (PyUnicode_Check(value))
+ {
+ g_config_param_set_value(param, PyUnicode_DATA(value));
+ result = 0;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_config_param_type(void)
+{
+ static PyMethodDef py_config_param_methods[] = {
+ { "make_empty", py_config_param_make_empty,
+ METH_NOARGS,
+ "Unset the value of the current parameter."
+ },
+ { "reset", py_config_param_reset,
+ METH_NOARGS,
+ "Reset the content of the current parameter."
+ },
+ { NULL }
+ };
+
+ static PyGetSetDef py_config_param_getseters[] = {
+ {
+ "path", py_config_param_get_path, NULL,
+ "Show the path used as key for a configuration parameter.", NULL
+ },
+ {
+ "type", py_config_param_get_type, NULL,
+ "Show the type of value provided by a configuration parameter.", NULL
+ },
+ {
+ "state", py_config_param_get_state, NULL,
+ "Show the state of a configuration parameter.", NULL
+ },
+ {
+ "value", py_config_param_get_value, py_config_param_set_value,
+ "Handle the value of a configuration parameter.", NULL
+ },
+ { NULL }
+ };
+
+ static PyTypeObject py_config_param_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.glibext.ConfigParam",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "PyChrysalide generic configuration",
+
+ .tp_methods = py_config_param_methods,
+ .tp_getset = py_config_param_getseters,
+ .tp_new = (newfunc)py_config_param_new
+
+ };
+
+ return &py_config_param_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : dict = dictionnaire à compléter. *
+* *
+* Description : Définit les constantes pour les paramètres. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_config_param_define_constants(PyObject *dict)
+{
+ int ret; /* Bilan d'un ajout */
+
+#define DEF_ULONG_CONST(name) \
+ ret = PyDict_SetItemString(dict, #name, PyLong_FromUnsignedLong(name)); \
+ if (ret == -1) return false;
+
+ DEF_ULONG_CONST(CPT_BOOLEAN);
+ DEF_ULONG_CONST(CPT_INTEGER);
+ DEF_ULONG_CONST(CPT_STRING);
+ DEF_ULONG_CONST(CPT_COUNT);
+
+ DEF_ULONG_CONST(CPS_UNDEFINED);
+ DEF_ULONG_CONST(CPS_CHANGED);
+ DEF_ULONG_CONST(CPS_DEFAULT);
+ DEF_ULONG_CONST(CPS_EMPTY);
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.glibext.ConfigParam'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_config_param(PyObject *module)
+{
+ PyTypeObject *py_config_param_type; /* Type Python 'ConfigParam' */
+ int ret; /* Bilan d'un appel */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_config_param_type = get_python_config_param_type();
+
+ py_config_param_type->tp_base = &PyGObject_Type;
+ py_config_param_type->tp_basicsize = py_config_param_type->tp_base->tp_basicsize;
+
+ if (PyType_Ready(py_config_param_type) != 0)
+ return false;
+
+ if (!py_config_param_define_constants(py_config_param_type->tp_dict))
+ return false;
+
+ Py_INCREF(py_config_param_type);
+ ret = PyModule_AddObject(module, "ConfigParam", (PyObject *)py_config_param_type);
+ if (ret != 0) return false;
+
+ dict = PyModule_GetDict(module);
+ pygobject_register_class(dict, "ConfigParam", G_TYPE_CFG_PARAM, py_config_param_type,
+ Py_BuildValue("(O)", py_config_param_type->tp_base));
+
+ return true;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* PARCOURS DE PARAMETRES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance Python à libérer de la mémoire. *
+* *
+* Description : Prend acte d'un compteur de référence à 0. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_config_param_iterator_dealloc(PyObject *self)
+{
+ pyConfigParamIterator *iterator; /* Références pour le parcours */
+
+ /**
+ * Il aurait été sans doute mieux de reposer ici sur .tp_finalize,
+ * mais cela semble impliquer de mettre en place tous les mécanismes de GC...
+ *
+ * cf. https://docs.python.org/3/extending/newtypes.html#finalization-and-de-allocation
+ */
+
+ iterator = (pyConfigParamIterator *)self;
+
+ g_generic_config_runlock(iterator->config);
+ g_object_unref(G_OBJECT(iterator->config));
+
+ Py_TYPE(self)->tp_free((PyObject*)self);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = itérateur à manipuler. *
+* *
+* Description : Fournit un itérateur pour paramètres de configuration. *
+* *
+* Retour : Instance Python prête à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_iterator_iter(PyObject *self)
+{
+ Py_INCREF(self);
+
+ return self;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = itérateur à manipuler. *
+* *
+* Description : Fournit un itérateur pour paramètres de configuration. *
+* *
+* Retour : Instance Python prête à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_config_param_iterator_next(PyObject *self)
+{
+ PyObject *result; /* Instance à retourner */
+ pyConfigParamIterator *iterator; /* Références pour le parcours */
+ GList *item; /* Nouvel élément courant */
+
+ iterator = (pyConfigParamIterator *)self;
+
+ if (iterator->last == NULL) item = iterator->params;
+ else item = g_list_next(iterator->last);
+
+ iterator->last = item;
+
+ if (item != NULL)
+ {
+ result = pygobject_new(G_OBJECT(item->data));
+ Py_XINCREF(result);
+ }
+ else
+ {
+ PyErr_SetNone(PyExc_StopIteration);
+ result = NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet instancié à initialiser. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Initialise un objet Python de type 'ConfigParamIterator'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_config_param_iterator_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ pyConfigParamIterator *iterator; /* Références pour le parcours */
+ PyObject *config; /* Configuration format Python */
+ int ret; /* Bilan de lecture des args. */
+
+ ret = PyArg_ParseTuple(args, "O", &config);
+ if (!ret) return -1;
+
+ ret = PyObject_IsInstance(config, (PyObject *)get_python_generic_config_type());
+ if (!ret) return -1;
+
+ iterator = (pyConfigParamIterator *)self;
+
+ iterator->config = G_GEN_CONFIG(pygobject_get(config));
+ g_object_ref(G_OBJECT(iterator->config));
+
+ g_generic_config_rlock(iterator->config);
+
+ iterator->params = g_generic_config_list_params(iterator->config);
+
+ iterator->last = NULL;
+
+ return 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_config_param_iterator_type(void)
+{
+ static PyTypeObject py_config_param_iterator_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.glibext.ConfigParamIterator",
+ .tp_basicsize = sizeof(pyConfigParamIterator),
+
+ .tp_dealloc = py_config_param_iterator_dealloc,
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "Iterator for configuration parameters",
+
+ .tp_iter = py_config_param_iterator_iter,
+ .tp_iternext = py_config_param_iterator_next,
+
+ .tp_init = py_config_param_iterator_init,
+
+ .tp_new = PyType_GenericNew,
+
+ };
+
+ return &py_config_param_iterator_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide...ConfigParamIterator'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_config_param_iterator(PyObject *module)
+{
+ PyTypeObject *py_config_param_iterator_type; /* Type Python 'ConfigParamIterator' */
+ int ret; /* Bilan d'un appel */
+
+ py_config_param_iterator_type = get_python_config_param_iterator_type();
+
+ py_config_param_iterator_type->tp_base = &PyBaseObject_Type;
+ py_config_param_iterator_type->tp_basicsize = py_config_param_iterator_type->tp_base->tp_basicsize;
+
+ if (PyType_Ready(py_config_param_iterator_type) != 0)
+ return false;
+
+ Py_INCREF(py_config_param_iterator_type);
+ ret = PyModule_AddObject(module, "ConfigParamIterator", (PyObject *)py_config_param_iterator_type);
+ if (ret != 0) return false;
+
+ return true;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GESTION GENERIQUE DE CONFIGURATION */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de l'objet à instancier. *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
+* *
+* Description : Crée un nouvel objet Python de type 'GenConfig'. *
+* *
+* Retour : Instance Python mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *result; /* Instance à retourner */
+ char *name; /* Nom du fichier à charger */
+ int ret; /* Bilan de lecture des args. */
+ GGenConfig *config; /* Version GLib du format */
+
+ ret = PyArg_ParseTuple(args, "s", &name);
+ if (!ret) Py_RETURN_NONE;
+
+ config = g_generic_config_new(name);
+
+ result = pygobject_new(G_OBJECT(config));
+ g_object_unref(config);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = configuration à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Lit la configuration depuis un fichier. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_read(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GGenConfig *config; /* Version GLib du format */
+ bool status; /* Bilan de l'opération */
+
+ config = G_GEN_CONFIG(pygobject_get(self));
+
+ status = g_generic_config_read(config);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = configuration à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Ecrit la configuration dans un fichier. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_write(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GGenConfig *config; /* Version GLib du format */
+ bool status; /* Bilan de l'opération */
+
+ config = G_GEN_CONFIG(pygobject_get(self));
+
+ status = g_generic_config_write(config);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = configuration à manipuler. *
+* args = indication sur l'élément à retrouver. *
+* *
+* Description : Retrouve un élément de configuration par son chemin. *
+* *
+* Retour : Elément trouvé ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_search(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GGenConfig *config; /* Version GLib du format */
+ char *path; /* Chemin d'accès du paramètre */
+ int ret; /* Bilan de lecture des args. */
+ GCfgParam *param; /* Paramètre trouvé ou NULL */
+
+ config = G_GEN_CONFIG(pygobject_get(self));
+
+ ret = PyArg_ParseTuple(args, "s", &path);
+ if (!ret) Py_RETURN_NONE;
+
+ param = g_generic_config_search(config, path);
+
+ result = pygobject_new(G_OBJECT(param));
+ Py_XINCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = configuration à manipuler. *
+* args = indication sur l'élément à retrouver. *
+* *
+* Description : Ajoute un paramètre à une configuration. *
+* *
+* Retour : Elément ajouté ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_add(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ GGenConfig *config; /* Version GLib du format */
+ PyObject *param; /* Paramètre transmis */
+ int ret; /* Bilan de lecture des args. */
+ GCfgParam *added; /* Elément ajouté ou NULL */
+
+ config = G_GEN_CONFIG(pygobject_get(self));
+
+ ret = PyArg_ParseTuple(args, "O", &param);
+ if (!ret) Py_RETURN_NONE;
+
+ ret = PyObject_IsInstance(param, (PyObject *)get_python_config_param_type());
+ if (!ret) Py_RETURN_NONE;
+
+ added = g_generic_config_add_param(config, G_CFG_PARAM(pygobject_get(param)));
+
+ if (added != NULL)
+ {
+ result = pygobject_new(G_OBJECT(added));
+ Py_XINCREF(result);
+ }
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = configuration à manipuler. *
+* args = indication sur l'élément à retrouver. *
+* *
+* Description : Retire un paramètre d'une configuration. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_delete(PyObject *self, PyObject *args)
+{
+ GGenConfig *config; /* Version GLib du format */
+ char *path; /* Chemin d'accès du paramètre */
+ int ret; /* Bilan de lecture des args. */
+
+ config = G_GEN_CONFIG(pygobject_get(self));
+
+ ret = PyArg_ParseTuple(args, "s", &path);
+ if (!ret) Py_RETURN_NONE;
+
+ g_generic_config_delete_param(config, path);
+
+ Py_RETURN_NONE;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = configuration à manipuler. *
+* args = non utilisé ici. *
+* *
+* Description : Renvoie la liste des paramètres de configuration. *
+* *
+* Retour : Itérateur pour la liste des paramètres. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_list_params(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ PyTypeObject *iterator_type; /* Type Python de l'itérateur */
+ PyObject *args_list; /* Arguments de mise en place */
+
+ iterator_type = get_python_config_param_iterator_type();
+
+ Py_INCREF(self);
+
+ args_list = Py_BuildValue("(O)", self);
+ result = PyObject_CallObject((PyObject *)iterator_type, args_list);
+
+ Py_DECREF(args_list);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = NULL car méthode statique. *
+* closure = non utilisé ici. *
+* *
+* Description : Fournit le chemin d'accès au binaire représenté. *
+* *
+* Retour : Chemin d'accès en Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_generic_config_get_filename(PyObject *self, void *closure)
+{
+ GGenConfig *config; /* Version GLib du format */
+ const char *filename; /* Chemin d'accès au fichier */
+
+ config = G_GEN_CONFIG(pygobject_get(self));
+
+ filename = g_generic_config_get_filename(config);
+
+ return PyUnicode_FromString(filename);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit un accès à une définition de type à diffuser. *
+* *
+* Retour : Définition d'objet pour Python. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PyTypeObject *get_python_generic_config_type(void)
+{
+ static PyMethodDef py_generic_config_methods[] = {
+ { "read", py_generic_config_read,
+ METH_NOARGS,
+ "Read the configuration from its relative XML file."
+ },
+ { "write", py_generic_config_write,
+ METH_NOARGS,
+ "Write the configuration to its relative XML file."
+ },
+ { "search", py_generic_config_search,
+ METH_VARARGS,
+ "Look for a given configuration parameter."
+ },
+ { "add", py_generic_config_add,
+ METH_VARARGS,
+ "Add an existing parameter to a configuration."
+ },
+ { "delete", py_generic_config_delete,
+ METH_VARARGS,
+ "Delete an existing parameter from a configuration."
+ },
+ { "params", py_generic_config_list_params,
+ METH_NOARGS,
+ "List all registered configuration parameters."
+ },
+ { NULL }
+ };
+
+ static PyGetSetDef py_generic_config_getseters[] = {
+ {
+ "filename", py_generic_config_get_filename, NULL,
+ "Show the filename of the loaded binary file.", NULL
+ },
+ { NULL }
+ };
+
+ static PyTypeObject py_generic_config_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.glibext.GenConfig",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+
+ .tp_doc = "PyChrysalide generic configuration",
+
+ .tp_methods = py_generic_config_methods,
+ .tp_getset = py_generic_config_getseters,
+ .tp_new = (newfunc)py_generic_config_new
+
+ };
+
+ return &py_generic_config_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.glibext.GenConfig'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool register_python_generic_config(PyObject *module)
+{
+ PyTypeObject *py_generic_config_type; /* Type Python 'GenConfig' */
+ int ret; /* Bilan d'un appel */
+ PyObject *dict; /* Dictionnaire du module */
+
+ py_generic_config_type = get_python_generic_config_type();
+
+ py_generic_config_type->tp_base = &PyGObject_Type;
+ py_generic_config_type->tp_basicsize = py_generic_config_type->tp_base->tp_basicsize;
+
+ if (PyType_Ready(py_generic_config_type) != 0)
+ return false;
+
+ Py_INCREF(py_generic_config_type);
+ ret = PyModule_AddObject(module, "GenConfig", (PyObject *)py_generic_config_type);
+ if (ret != 0) return false;
+
+ dict = PyModule_GetDict(module);
+ pygobject_register_class(dict, "GenConfig", G_TYPE_GEN_CONFIG, py_generic_config_type,
+ Py_BuildValue("(O)", py_generic_config_type->tp_base));
+
+ return true;
+
+}
diff --git a/plugins/pychrysa/glibext/configuration.h b/plugins/pychrysa/glibext/configuration.h
new file mode 100644
index 0000000..e55b3e1
--- /dev/null
+++ b/plugins/pychrysa/glibext/configuration.h
@@ -0,0 +1,66 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * configuration.h - prototypes pour l'équivalent Python du fichier "glibext/configuration.h"
+ *
+ * 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 _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H
+#define _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_config_param_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.glibext.ConfigParam'. */
+bool register_python_config_param(PyObject *);
+
+
+
+/* ----------------------------- PARCOURS DE PARAMETRES ----------------------------- */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_config_param_iterator_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.glibext.ConfigParamIterator'. */
+bool register_python_config_param_iterator(PyObject *);
+
+
+/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_generic_config_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.glibext.GenConfig'. */
+bool register_python_generic_config(PyObject *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H */
diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c
index b62ae7b..9f3d3a8 100644
--- a/plugins/pychrysa/glibext/module.c
+++ b/plugins/pychrysa/glibext/module.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* module.c - intégration du répertoire glibext en tant que module
*
- * Copyright (C) 2012 Cyrille Bagard
+ * Copyright (C) 2012-2014 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -25,8 +25,7 @@
#include "module.h"
-#include "bufferline.h"
-#include "codebuffer.h"
+#include "configuration.h"
@@ -44,24 +43,50 @@
bool add_glibext_module_to_python_module(PyObject *super)
{
- bool result;
- PyObject *module;
+ bool result; /* Bilan à retourner */
+ PyObject *module; /* Sous-module mis en place */
int ret; /* Bilan d'un appel */
- static PyMethodDef py_glibext_methods[] = {
- { NULL }
+ static PyModuleDef py_chrysalide_glibext_module = {
+
+ .m_base = PyModuleDef_HEAD_INIT,
+
+ .m_name = "pychrysalide.glibext",
+ .m_doc = "Python module for Chrysalide.glibext",
+
+ .m_size = -1,
+
};
- module = Py_InitModule("pychrysalide.glibext", py_glibext_methods);
+ result = false;
+
+ module = PyModule_Create(&py_chrysalide_glibext_module);
if (module == NULL) return false;
+ ret = PyState_AddModule(super, &py_chrysalide_glibext_module);
+ if (ret != 0) goto agmtpm_exit;
+
+ ret = _PyImport_FixupBuiltin(module, "pychrysalide.glibext");
+ if (ret != 0) goto agmtpm_exit;
+
Py_INCREF(module);
- ret = PyModule_AddObject(super, "pychrysalide.glibext", module);
+ ret = PyModule_AddObject(super, "glibext", module);
+ if (ret != 0) goto agmtpm_exit;
+
+ result = true;
+
+ result &= register_python_config_param(module);
+ result &= register_python_config_param_iterator(module);
+ result &= register_python_generic_config(module);
+
+ agmtpm_exit:
- result = (ret == 0);
+ if (!result)
+ {
+ printf("something went wrong in %s...\n", __FUNCTION__);
+ /* ... */
- result &= register_python_buffer_line(module);
- result &= register_python_code_buffer(module);
+ }
return result;
diff --git a/plugins/pychrysa/glibext/module.h b/plugins/pychrysa/glibext/module.h
index fe13d4c..ddcab15 100644
--- a/plugins/pychrysa/glibext/module.h
+++ b/plugins/pychrysa/glibext/module.h
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* module.h - prototypes pour l'intégration du répertoire glibext en tant que module
*
- * Copyright (C) 2012 Cyrille Bagard
+ * Copyright (C) 2012-2014 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYOIDA_GLIBEXT_MODULE_H
-#define _PLUGINS_PYOIDA_GLIBEXT_MODULE_H
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_H
#include <Python.h>
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c
index 865c0fc..1835b18 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -57,7 +57,6 @@
-
static PyMethodDef SpamMethods[] = {
{NULL, NULL, 0, NULL} /* Sentinel */
};
@@ -351,8 +350,15 @@ PyMODINIT_FUNC initpychrysa(void)
#include "../../revision.h"
+
+#include <core/core.h>
+
+
+
#include "analysis/module.h"
#include "arch/module.h"
+#include "core/module.h"
+#include "glibext/module.h"
@@ -458,6 +464,12 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
if (pygobject_init(-1, -1, -1) == NULL)
return NULL;
+ if (!load_all_basic_components())
+ return NULL;
+
+
+
+
/**
* Pour une raison non identifiée, si le module n'est pas préchargé,
* le flot d'exécution plante dans la fonction insertdict() de Objects/dictobject.c:818.
@@ -472,6 +484,8 @@ PyMODINIT_FUNC PyInit_pychrysalide(void)
status &= add_analysis_module_to_python_module(result);
status &= add_arch_module_to_python_module(result);
+ status &= add_core_module_to_python_module(result);
+ status &= add_glibext_module_to_python_module(result);
printf("status :: %d\n", status);
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, &param, -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, &param, -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 */
diff --git a/src/main.c b/src/main.c
index b9764ca..0fdfe31 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
}