git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Riesen" <raa.lkml@gmail.com>
To: "Git Mailing List" <git@vger.kernel.org>
Cc: "Junio C Hamano" <junkio@cox.net>
Subject: [PATCH] Allow config files to be included
Date: Fri, 16 Feb 2007 15:42:30 +0100	[thread overview]
Message-ID: <81b0412b0702160642h69b632f0w6c1decc4ec04c24a@mail.gmail.com> (raw)
In-Reply-To: <20070216143952.GA2478@steel.home>

The syntax is:

    [include "filename"]

which is somewhat branch/remote-alike. There are a few differences, though:
filenames happen to be long, so a backslash is supported to split the
names into multiple lines. No bare LF allowed, so this is illegal:
    [include "path/
    name"]
On the other hand, this is allowed:
    [include "path/\
    name"]

Backslash is just to quote characters (as in shell).
Only one quoted string allowed, so this is bad too:

    [include "path/" "name"]

Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
---

This is a resend, I have no idea what happened to original,
but it never appeared on vger. And this will probably horribly
garbled by gmail. Will see.

Alex Riesen, Thu, Feb 15, 2007 12:35:57 +0100:
> I suggest to ignore /etc/gitconfig completely if ~/.gitconfig exists,
> but allow inclusion of /etc/gitconfig from ~/.gitconfig (there are
> very singular and preciuos exceptions).

 config.c |  103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 100 insertions(+), 3 deletions(-)

diff --git a/config.c b/config.c
index d821071..b42a7ea 100644
--- a/config.c
+++ b/config.c
@@ -12,6 +12,57 @@
 static FILE *config_file;
 static const char *config_file_name;
 static int config_linenr;
+
+struct fileinfo
+{
+       char *name;
+       int linenr;
+       FILE *file;
+       struct fileinfo *prev;
+};
+static struct fileinfo *config_stack = NULL;
+
+static void include_file(const char *filename)
+{
+       struct fileinfo *prev;
+       FILE *file;
+       file = fopen(filename, "r");
+       if (!file) {
+               error("ignored \"%s\": %s", filename, strerror(errno));
+               return;
+       }
+       prev = malloc(sizeof(*prev));
+       prev->name = (char *)config_file_name;
+       prev->linenr = config_linenr;
+       prev->file = config_file;
+       prev->prev = config_stack;
+       config_stack = prev;
+
+       config_file = file;
+       config_file_name = xstrdup(filename);
+       config_linenr = 0;
+}
+
+static FILE *pop_file(void)
+{
+       struct fileinfo *prev;
+
+       if (!config_stack)
+               /* The last file on stack does not belong to us.
+                * Free the names and close all included files. */
+               return NULL;
+
+       free((void*)config_file_name);
+       fclose(config_file);
+       config_file = config_stack->file;
+       config_file_name = config_stack->name;
+       config_linenr = 0;
+       prev = config_stack->prev;
+       free(config_stack);
+       config_stack = prev;
+       return config_file;
+}
+
 static int get_next_char(void)
 {
        int c;
@@ -31,13 +82,51 @@ static int get_next_char(void)
                if (c == '\n')
                        config_linenr++;
                if (c == EOF) {
-                       config_file = NULL;
+                       config_file = pop_file();
                        c = '\n';
                }
        }
        return c;
 }

+static int parse_include(void)
+{
+       char name[PATH_MAX];
+       int quote = 0, len = 0;
+
+       for (;;) {
+               int c = get_next_char();
+               if (len >= sizeof(name))
+                       return -1;
+               if (c == '"') {
+                       quote++;
+                       continue;
+               }
+               if (c == '\n')
+                       /* do not allow bare \n anywhere in path */
+                       return -1;
+               if (quote == 1) {
+                       if (c == '\\') {
+                               c = get_next_char();
+                               if (c == '\n')
+                                       continue;
+                       }
+                       name[len++] = c;
+               }
+               if (quote == 2 && c == ']') {
+                       do
+                               c = get_next_char();
+                       while (c != '\n');
+                       break;
+               }
+               if ((quote < 1 || quote >= 2) && !isspace(c) )
+                       return -1;
+       }
+       name[len] = '\0';
+       include_file(name);
+       return 0;
+}
+
 static char *parse_value(void)
 {
        static char value[1024];
@@ -181,8 +270,13 @@ static int get_base_var(char *name)
                int c = get_next_char();
                if (c == EOF)
                        return -1;
+               if (!isalpha(c) && !strncmp(name, "include", baselen) &&
+                   config_file) {
+                       ungetc(c, config_file);
+                       return parse_include();
+               }
                if (c == ']')
-                       return baselen;
+                       return baselen ? baselen: -1;
                if (isspace(c))
                        return get_extended_base_var(name, baselen, c);
                if (!iskeychar(c) && c != '.')
@@ -216,8 +310,11 @@ static int git_parse_file(config_fn_t fn)
                }
                if (c == '[') {
                        baselen = get_base_var(var);
-                       if (baselen <= 0)
+                       if (baselen < 0)
                                break;
+                       if (!baselen)
+                               /* [include "..."]*/
+                               continue;
                        var[baselen++] = '.';
                        var[baselen] = 0;
                        continue;
--
1.5.0.138.g36f81

  parent reply	other threads:[~2007-02-16 14:43 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-14  9:09 /etc/gitconfig Andy Parkins
2007-02-14 10:30 ` /etc/gitconfig Peter Baumann
2007-02-14 11:48   ` [PATCH] config: read system-wide defaults from /etc/gitconfig Johannes Schindelin
2007-02-14 16:30     ` Junio C Hamano
2007-02-14 17:45       ` Johannes Schindelin
2007-02-14 17:57         ` Junio C Hamano
2007-02-14 18:02           ` Johannes Schindelin
2007-02-14 18:12             ` Junio C Hamano
2007-02-14 18:19               ` Nicolas Pitre
2007-02-14 19:06                 ` Junio C Hamano
2007-02-15 10:19       ` Andy Parkins
2007-02-15 11:26         ` Junio C Hamano
     [not found]         ` <20070215113557.GB2282@steel.home>
     [not found]           ` <20070216143952.GA2478@steel.home>
2007-02-16 14:42             ` Alex Riesen [this message]
2007-02-16 14:45               ` [PATCH] Allow config files to be included Alex Riesen
2007-02-14 18:10     ` [PATCH] config: read system-wide defaults from /etc/gitconfig Han-Wen Nienhuys
2007-02-14 19:07       ` Junio C Hamano
2007-02-14 19:25         ` Johannes Schindelin
2007-02-14 19:43           ` Junio C Hamano
2007-02-14 19:54             ` Johannes Schindelin
2007-02-14 22:39               ` Johannes Schindelin
2007-02-15  5:27               ` Junio C Hamano
2007-02-15  8:46                 ` Junio C Hamano
2007-02-15  9:59                   ` Eric Wong
2007-02-15 10:03                     ` Eric Wong
2007-02-15 10:36                     ` Junio C Hamano
2007-02-15 10:43                 ` Johannes Schindelin
2007-02-15 11:25                   ` Junio C Hamano
2007-02-15 12:05                     ` Johannes Schindelin
2007-02-19  1:47                     ` Jakub Narebski
2007-02-14 10:40 ` /etc/gitconfig Uwe Kleine-König

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=81b0412b0702160642h69b632f0w6c1decc4ec04c24a@mail.gmail.com \
    --to=raa.lkml@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=junkio@cox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).