[pacman-dev] [PATCH] Fix parsing included files w/ sections
Dan McGee
dpmcgee at gmail.com
Wed Jan 11 17:00:06 EST 2012
On Wed, Jan 11, 2012 at 12:52 PM, Olivier Brunel
<i.am.jack.mail at gmail.com> wrote:
> When parsing Include directives, a new section_t is now
> used, to ensure it won't "mess" with the current one (since
> included files can define new sections, which would result
> in an invalid "change" of the current section) This new
> section starts "in" the current one (so included files are
> parsed as expected, and don't need to open any section);
> IOW sections propagate down the include chain, not back up.
>
> This also solves the bug (?) when two repos with the same name are declared,
> which could happen in the same file or, more likely, through Include-s.
> Now only one db will be registered, with all servers in it (it used to
> be as many dbs with the same name as there were sections).
IOW? bug (?)? "quotes" around "random" words? I know I'm nitpicking,
but this is not always the most readable English, especially to
non-native speakers (even I had to look up what IOW was).
Imagine coming back to a commit message in two years- if there is
anything in it that wouldn't make sense, you need to reword/rewrite
it. That is the purpose of commit messages.
> Signed-off-by: Olivier Brunel <i.am.jack.mail at gmail.com>
> ---
> src/pacman/conf.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++------
> 1 files changed, 47 insertions(+), 7 deletions(-)
>
> diff --git a/src/pacman/conf.c b/src/pacman/conf.c
> index 2ff16d2..eb3374e 100644
> --- a/src/pacman/conf.c
> +++ b/src/pacman/conf.c
> @@ -628,6 +628,18 @@ struct section_t {
> alpm_list_t *servers;
> };
>
> +static alpm_db_t *get_db(const char *dbname)
> +{
> + alpm_list_t *i;
> + for(i = alpm_option_get_syncdbs(config->handle); i; i = i->next) {
> + alpm_db_t *db = i->data;
> + if(strcmp(alpm_db_get_name(db), dbname) == 0) {
> + return db;
> + }
> + }
> + return NULL;
> +}
Rather than copying this straight out of src/pacman/sync.c, why don't
you make it visible to the entire compilation unit in util.c/util.h
(this file) and remove the now unneeded version from sync.c? (for a
more public function, a longer name might be nice too; something like
'get_sync_db' just to be as clear as possible).
> +
> /**
> * Wrap up a section once we have reached the end of it. This should be called
> * when a subsequent section is encountered, or when we have reached the end of
> @@ -650,13 +662,17 @@ static int finish_section(struct section_t *section, int parse_options)
> goto cleanup;
> }
>
> - /* if we are not looking at options sections only, register a db */
> - db = alpm_db_register_sync(config->handle, section->name, section->siglevel);
> + /* if we are not looking at options sections only, get the db */
> + db = get_db(section->name);
> if(db == NULL) {
> - pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
> - section->name, alpm_strerror(alpm_errno(config->handle)));
> - ret = 1;
> - goto cleanup;
> + /* not registered yet, let's do it */
The "let's do it" part is not really necessary; I say this because we
also try to avoid contractions if possible.
> + db = alpm_db_register_sync(config->handle, section->name, section->siglevel);
> + if(db == NULL) {
> + pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"),
> + section->name, alpm_strerror(alpm_errno(config->handle)));
> + ret = 1;
> + goto cleanup;
> + }
> }
>
> for(i = section->servers; i; i = alpm_list_next(i)) {
> @@ -780,6 +796,7 @@ static int _parseconfig(const char *file, struct section_t *section,
> glob_t globbuf;
> int globret;
> size_t gindex;
> + struct section_t inc_section;
>
> if(value == NULL) {
> pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"),
> @@ -816,10 +833,33 @@ static int _parseconfig(const char *file, struct section_t *section,
> file, linenum, value);
> break;
> default:
> + /* create new section_t for the includes -- to keep ours unaffected */
> for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) {
> + /* we use a different section_t for includes, so they can't mess up
> + * the current one. This section starts "in" the current section ofc */
ofc?
> + inc_section->name = strdup (section->name);
> + inc_section->is_options = section->is_options;
> + inc_section->siglevel = section->siglevel;
> + inc_section->servers = NULL;
> pm_printf(ALPM_LOG_DEBUG, "config file %s, line %d: including %s\n",
> file, linenum, globbuf.gl_pathv[gindex]);
> - _parseconfig(globbuf.gl_pathv[gindex], section, parse_options, depth + 1);
> + _parseconfig(globbuf.gl_pathv[gindex], inc_section, parse_options, depth + 1);
> + /* now, if this is a repo ... */
> + if(!parse_options && !section->is_options) {
> + if (section->siglevel == inc_section->siglevel
> + && strcmp(section->name, inc_section->name) == 0) {
This logic seems very very suspect to me; and likely wrong. For example:
[myrepo]
SigLevel = DatabaseRequired PackageOptional
Server = foobar.com
Include = /path/to/myrepo.override
----> (jump to new file)
Server = example.com
SigLevel = PackageRequred
----> EOF, jump back
You're going to lose my updated siglevel configuration in all of this;
I'm not even sure what is going to happen.
I also don't like the assumption that repos have only "Server" as
their main setting, I have a few plans to add more options to this in
the future and don't want parsing to rely on the fact that right now
only "Server" and "SigLevel" appear there, if possible.
> + /* ... still the same one, we'll just import servers */
> + alpm_list_t *i;
> + for(i = inc_section->servers; i; i = alpm_list_next(i)) {
> + section->servers = alpm_list_add(section->servers, i->data);
> + }
> + alpm_list_free(inc_section->servers);
> + free(inc_section->name);
> + } else {
> + /* ... a different one, so let's "finish" it */
> + finish_section(inc_section, parse_options);
> + }
> + }
> }
> break;
> }
> --
> 1.7.8.3
More information about the pacman-dev
mailing list