Commits

Armin Ronacher committed c6322a2

Cleanin up memory management and start work on default support

Comments (0)

Files changed (6)

 
 result_t* init_result()
 {
-    return (result_t*) calloc(1, sizeof(result_t));
+    result_t *rv = (result_t*) calloc(1, sizeof(result_t));
+    ASSERT_NOOM(rv);
+    return rv;
 }
 
 void free_result(result_t* result)
 {
+    if (!result)
+        return;
     free(result->revision);
     free(result->branch);
     free(result);
     _options = options;
 }
 
-int result_set_revision(result_t* result, const char *revision, int len)
+options_t* new_options(const char *format)
+{
+    options_t *rv = calloc(sizeof(options_t), 1);
+    ASSERT_NOOM(rv);
+    rv->format = strdup(format);
+    ASSERT_NOOM(rv->format);
+    return rv;
+}
+
+void free_options(options_t* options)
+{
+    if (!options)
+        return;
+    free(options->format);
+    free(options->default_branch);
+    free(options->default_revision);
+    free(options->default_unknown);
+    free(options->default_modified);
+    free(options);
+}
+
+void result_set_revision(result_t* result, const char *revision, int len)
 {
     if (result->revision)
         free(result->revision);
-    if (len == -1)
+    if (len < 0)
         result->revision = strdup(revision);
     else {
         result->revision = malloc(len);
-        if (!result->revision)
-            return 0;
+        ASSERT_NOOM(result->revision);
         strncpy(result->revision, revision, len);
     }
-    return !!result->revision;
 }
 
-int result_set_branch(result_t* result, const char *branch)
+void result_set_branch(result_t* result, const char *branch)
 {
     if (result->branch)
         free(result->branch);
     result->branch = strdup(branch);
-    return !!result->branch;
+    ASSERT_NOOM(result->branch);
 }
 
 vccontext_t* init_context(const char *name,
     int show_revision;                  /* show current revision? */
     int show_unknown;                   /* show ? if unknown files? */
     int show_modified;                  /* show ! if local changes? */
+    char* default_branch;
+    char* default_revision;
+    char* default_unknown;
+    char* default_modified;
 } options_t;
 
 typedef struct {
     int modified;                       /* any local changes? */
 } result_t;
 
-int result_set_revision(result_t* result, const char *revision, int len);
-int result_set_branch(result_t* result, const char *branch);
+void result_set_revision(result_t* result, const char *revision, int len);
+void result_set_branch(result_t* result, const char *branch);
 
 typedef struct vccontext_t vccontext_t;
 struct vccontext_t {
 };
 
 void set_options(options_t*);
+options_t* new_options(const char*);
+void free_options(options_t*);
 vccontext_t* init_context(const char *name,
                           options_t* options,
                           int (*probe)(vccontext_t*),
 
 void dump_hex(const char* data, char* buf, int datasize);
 
+/* assert not out of memory :) */
+#define ASSERT_NOOM(x) do { \
+    if (!x) exit(2); \
+} while (0)
+
 #endif
         }
         else {
             /* non-branch sticky tag or sticky date */            
-           result_set_branch(result, "(unknown)");
         }
     }
     return result;
             if (strncmp(prefix, buf, prefixlen) == 0) {
                 /* yep, we're on a known branch */
                 debug("read a head ref from .git/HEAD: '%s'", buf);
-                if (result_set_branch(result, buf + prefixlen))
-                    found_branch = 1;
+                result_set_branch(result, buf + prefixlen);
+                found_branch = 1;
             }
             else {
                 /* if it's not a branch name, assume it is a commit ID */
                 debug(".git/HEAD doesn't look like a head ref: unknown branch");
-                result_set_branch(result, "(unknown)");
                 result_set_revision(result, buf, 12);
             }
             if (context->options->show_revision && found_branch) {
 
 #define DEFAULT_FORMAT "[%n:%b%m%u] "
 
-void parse_args(int argc, char** argv, options_t* options)
+int parse_args(int argc, char** argv, options_t* options)
 {
     int opt;
     while ((opt = getopt(argc, argv, "hf:d")) != -1) {
         switch (opt) {
             case 'f':
-                options->format = optarg;
+                options->format = strdup(optarg);
+                ASSERT_NOOM(options->format);
                 break;
             case 'd':
                 options->debug = 1;
                 printf("Environment Variables:\n"
                 " VCPROMPT_FORMAT\n"
                 );
-                exit(1);
+                return 1;
         }
     }
+    return 0;
 }
 
 void parse_format(options_t* options)
     options->show_modified = 0;
 
     char* format = options->format;
+    const char* next_default = NULL;
     size_t len = strlen(format);
     for (i = 0; i < len; i++) {
         if (format[i] == '%') {
     char* format = getenv("VCPROMPT_FORMAT");
     if (format == NULL)
         format = DEFAULT_FORMAT;
-    options_t options = {
-        .debug         = 0,
-        .format        = format,
-        .show_branch   = 0,
-        .show_revision = 0,
-        .show_unknown  = 0,
-        .show_modified = 0,
-    };
 
-    parse_args(argc, argv, &options);
-    parse_format(&options);
-    set_options(&options);
+    result_t* result = NULL;
+    options_t *options = new_options(format);
+    if (!options)
+        return 1;
+
+    /* might abort early in case the helpscreen is shown */
+    if (parse_args(argc, argv, options))
+        goto close_and_cleanup;
+
+    parse_format(options);
+    set_options(options);
 
     vccontext_t* contexts[] = {
-        get_cvs_context(&options),
-        get_git_context(&options),
-        get_hg_context(&options),
-        get_svn_context(&options),
+        get_cvs_context(options),
+        get_git_context(options),
+        get_hg_context(options),
+        get_svn_context(options),
     };
     int num_contexts = sizeof(contexts) / sizeof(vccontext_t*);
 
-    result_t* result = NULL;
     vccontext_t* context = NULL;
 
     /* Starting in the current dir, walk up the directory tree until
     context = probe_parents(contexts, num_contexts);
 
     /* Nobody claimed it: bail now without printing anything. */
-    if (context == NULL) {
-        return 0;
-    }
+    if (context == NULL)
+        goto close_and_cleanup;
 
     /* Analyze the working copy metadata and print the result. */
     result = context->get_info(context);
     if (result != NULL) {
-        print_result(context, &options, result);
-        free_result(result);
-        if (options.debug)
+        print_result(context, options, result);
+        if (options->debug)
             putc('\n', stdout);
     }
+
+close_and_cleanup:
+    free_result(result);
+    free_options(options);
     return 0;
 }

tests/test-simple

     assert_vcprompt "cvs notag" "cvs:trunk" "%n:%b"
 
     echo "Nsometag" > CVS/Tag
-    assert_vcprompt "cvs nobranch" "cvs:(unknown)" "%n:%b"
+    assert_vcprompt "cvs nobranch" "cvs:" "%n:%b"
 
     echo "Tfoo" > CVS/Tag
     assert_vcprompt "cvs branch" "foo"
     assert_vcprompt "git broken 2" "" "%n:%b"
 
     echo 3f786850e387550fdab836ed7e6dc881de23001b > .git/HEAD
-    assert_vcprompt "git nobranch" "(unknown)"
-    assert_vcprompt "git nobranch (show rev)" "(unknown):3f786850e387" "%b:%r"
+    assert_vcprompt "git nobranch" ""
+    assert_vcprompt "git nobranch (show rev)" ":3f786850e387" "%b:%r"
 
     echo "ref: refs/heads/foo" > .git/HEAD
     assert_vcprompt "git branch" "git:foo" "%n:%b"
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.