cleanup: protected -> hidden: cleanup symbol table
[babeltrace.git] / converter / babeltrace.c
index c377935edb4eee708113d50dd86ac5e6c54edb1a..fd6586a5a1e020eb80d168ef19b689f9db987dcd 100644 (file)
 #include <unistd.h>
 #include <inttypes.h>
 #include <fts.h>
+#include <string.h>
 
 #include <babeltrace/ctf-ir/metadata.h>        /* for clocks */
 
 #define DEFAULT_FILE_ARRAY_SIZE        1
-static char *opt_input_format;
-static char *opt_output_format;
+static char *opt_input_format, *opt_output_format;
+/* Pointer into const argv */
+static const char *opt_input_format_arg, *opt_output_format_arg;
 
 static const char *opt_input_path;
 static const char *opt_output_path;
 
 static struct format *fmt_read;
 
+static
 void strlower(char *str)
 {
        while (*str) {
-               *str = tolower(*str);
+               *str = tolower((int) *str);
                str++;
        }
 }
@@ -70,7 +73,7 @@ enum {
        OPT_FIELDS,
        OPT_NO_DELTA,
        OPT_CLOCK_OFFSET,
-       OPT_CLOCK_RAW,
+       OPT_CLOCK_CYCLES,
        OPT_CLOCK_SECONDS,
        OPT_CLOCK_DATE,
        OPT_CLOCK_GMT,
@@ -79,8 +82,8 @@ enum {
 
 static struct poptOption long_options[] = {
        /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
-       { "input-format", 'i', POPT_ARG_STRING, &opt_input_format, OPT_NONE, NULL, NULL },
-       { "output-format", 'o', POPT_ARG_STRING, &opt_output_format, OPT_NONE, NULL, NULL },
+       { "input-format", 'i', POPT_ARG_STRING, &opt_input_format_arg, OPT_NONE, NULL, NULL },
+       { "output-format", 'o', POPT_ARG_STRING, &opt_output_format_arg, OPT_NONE, NULL, NULL },
        { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
        { "list", 'l', POPT_ARG_NONE, NULL, OPT_LIST, NULL, NULL },
        { "verbose", 'v', POPT_ARG_NONE, NULL, OPT_VERBOSE, NULL, NULL },
@@ -89,7 +92,7 @@ static struct poptOption long_options[] = {
        { "fields", 'f', POPT_ARG_STRING, NULL, OPT_FIELDS, NULL, NULL },
        { "no-delta", 0, POPT_ARG_NONE, NULL, OPT_NO_DELTA, NULL, NULL },
        { "clock-offset", 0, POPT_ARG_STRING, NULL, OPT_CLOCK_OFFSET, NULL, NULL },
-       { "clock-raw", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_RAW, NULL, NULL },
+       { "clock-cycles", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_CYCLES, NULL, NULL },
        { "clock-seconds", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_SECONDS, NULL, NULL },
        { "clock-date", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_DATE, NULL, NULL },
        { "clock-gmt", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_GMT, NULL, NULL },
@@ -128,7 +131,7 @@ static void usage(FILE *fp)
        fprintf(fp, "  -f, --fields name1<,name2,...> Print additional fields:\n");
        fprintf(fp, "                                     all, trace, trace:domain, trace:procname,\n");
        fprintf(fp, "                                     trace:vpid, loglevel.\n");
-       fprintf(fp, "      --clock-raw                Disregard internal clock offset (use raw value)\n");
+       fprintf(fp, "      --clock-cycles             Timestamp in cycles\n");
        fprintf(fp, "      --clock-offset seconds     Clock offset in seconds\n");
        fprintf(fp, "      --clock-seconds            Print the timestamps as [sec.ns]\n");
        fprintf(fp, "                                 (default is: [hh:mm:ss.ns])\n");
@@ -258,12 +261,13 @@ static int parse_options(int argc, char **argv)
                case OPT_NO_DELTA:
                        opt_delta_field = 0;
                        break;
-               case OPT_CLOCK_RAW:
-                       opt_clock_raw = 1;
+               case OPT_CLOCK_CYCLES:
+                       opt_clock_cycles = 1;
                        break;
                case OPT_CLOCK_OFFSET:
                {
-                       char *str, *endptr;
+                       const char *str;
+                       char *endptr;
 
                        str = poptGetOptArg(pc);
                        if (!str) {
@@ -321,9 +325,10 @@ end:
  * path, and add them to the context. The packet_seek parameter can be
  * NULL: this specify to use the default format packet_seek.
  *
- * Return: 0 on success, nonzero on failure.
+ * Return: 0 on success, < 0 on failure, > 0 on partial failure.
  * Unable to open toplevel: failure.
- * Unable to open some subdirectory or file: warn and continue;
+ * Unable to open some subdirectory or file: warn and continue (partial
+ * failure);
  */
 int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
                const char *format_str,
@@ -335,7 +340,7 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
        GArray *trace_ids;
        char lpath[PATH_MAX];
        char * const paths[2] = { lpath, NULL };
-       int ret = -1;
+       int ret = 0;
 
        /*
         * Need to copy path, because fts_open can change it.
@@ -355,6 +360,7 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
 
        while ((node = fts_read(tree))) {
                int dirfd, metafd;
+               int closeret;
 
                if (!(node->fts_info & FTS_D))
                        continue;
@@ -363,27 +369,31 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
                if (dirfd < 0) {
                        fprintf(stderr, "[error] [Context] Unable to open trace "
                                "directory file descriptor.\n");
-                       ret = dirfd;
+                       ret = 1;        /* partial error */
                        goto error;
                }
                metafd = openat(dirfd, "metadata", O_RDONLY);
                if (metafd < 0) {
-                       ret = close(dirfd);
-                       if (ret < 0) {
+                       closeret = close(dirfd);
+                       if (closeret < 0) {
                                perror("close");
+                               ret = -1;       /* failure */
                                goto error;
                        }
+                       continue;
                } else {
                        int trace_id;
 
-                       ret = close(metafd);
-                       if (ret < 0) {
+                       closeret = close(metafd);
+                       if (closeret < 0) {
                                perror("close");
+                               ret = -1;       /* failure */
                                goto error;
                        }
-                       ret = close(dirfd);
-                       if (ret < 0) {
+                       closeret = close(dirfd);
+                       if (closeret < 0) {
                                perror("close");
+                               ret = -1;       /* failure */
                                goto error;
                        }
 
@@ -394,6 +404,7 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path,
                                fprintf(stderr, "[warning] [Context] opening trace \"%s\" from %s "
                                        "for reading.\n", node->fts_accpath, path);
                                /* Allow to skip erroneous traces. */
+                               ret = 1;        /* partial error */
                                continue;
                        }
                        g_array_append_val(trace_ids, trace_id);
@@ -404,9 +415,9 @@ error:
        /*
         * Return an error if no trace can be opened.
         */
-       if (ret == 0 && trace_ids->len == 0) {
+       if (trace_ids->len == 0) {
                fprintf(stderr, "[error] Cannot open any trace for reading.\n\n");
-               ret = -ENOENT;
+               ret = -ENOENT;          /* failure */
        }
        g_array_free(trace_ids, TRUE);
        return ret;
@@ -452,7 +463,7 @@ error_iter:
 
 int main(int argc, char **argv)
 {
-       int ret;
+       int ret, partial_error = 0;
        struct format *fmt_write;
        struct trace_descriptor *td_write;
        struct bt_context *ctx;
@@ -468,10 +479,22 @@ int main(int argc, char **argv)
        printf_verbose("Verbose mode active.\n");
        printf_debug("Debug mode active.\n");
 
-       if (opt_input_format)
+       if (opt_input_format_arg) {
+               opt_input_format = strdup(opt_input_format_arg);
+               if (!opt_input_format) {
+                       partial_error = 1;
+                       goto end;
+               }
                strlower(opt_input_format);
-       if (opt_output_format)
+       }
+       if (opt_output_format_arg) {
+               opt_output_format = strdup(opt_output_format_arg);
+               if (!opt_output_format) {
+                       partial_error = 1;
+                       goto end;
+               }
                strlower(opt_output_format);
+       }
 
        printf_verbose("Converting from directory: %s\n", opt_input_path);
        printf_verbose("Converting from format: %s\n",
@@ -481,31 +504,47 @@ int main(int argc, char **argv)
        printf_verbose("Converting to format: %s\n",
                opt_output_format ? : "text <default>");
 
-       if (!opt_input_format)
-               opt_input_format = "ctf";
-       if (!opt_output_format)
-               opt_output_format = "text";
+       if (!opt_input_format) {
+               opt_input_format = strdup("ctf");
+               if (!opt_input_format) {
+                       partial_error = 1;
+                       goto end;
+               }
+       }
+       if (!opt_output_format) {
+               opt_output_format = strdup("text");
+               if (!opt_output_format) {
+                       partial_error = 1;
+                       goto end;
+               }
+       }
        fmt_read = bt_lookup_format(g_quark_from_static_string(opt_input_format));
        if (!fmt_read) {
                fprintf(stderr, "[error] Format \"%s\" is not supported.\n\n",
                        opt_input_format);
-               exit(EXIT_FAILURE);
+               partial_error = 1;
+               goto end;
        }
        fmt_write = bt_lookup_format(g_quark_from_static_string(opt_output_format));
        if (!fmt_write) {
                fprintf(stderr, "[error] format \"%s\" is not supported.\n\n",
                        opt_output_format);
-               exit(EXIT_FAILURE);
+               partial_error = 1;
+               goto end;
        }
 
        ctx = bt_context_create();
 
        ret = bt_context_add_traces_recursive(ctx, opt_input_path,
                        opt_input_format, NULL);
-       if (ret) {
+       if (ret < 0) {
                fprintf(stderr, "[error] opening trace \"%s\" for reading.\n\n",
                        opt_input_path);
                goto error_td_read;
+       } else if (ret > 0) {
+               fprintf(stderr, "[warning] errors occurred when opening trace \"%s\" for reading, continuing anyway.\n\n",
+                       opt_input_path);
+               partial_error = 1;
        }
 
        td_write = fmt_write->open_trace(opt_output_path, O_RDWR, NULL, NULL);
@@ -526,7 +565,7 @@ int main(int argc, char **argv)
        bt_context_put(ctx);
        printf_verbose("finished converting. Output written to:\n%s\n",
                        opt_output_path ? : "<stdout>");
-       exit(EXIT_SUCCESS);
+       goto end;
 
        /* Error handling */
 error_copy_trace:
@@ -534,5 +573,14 @@ error_copy_trace:
 error_td_write:
        bt_context_put(ctx);
 error_td_read:
-       exit(EXIT_FAILURE);
+       partial_error = 1;
+
+       /* teardown and exit */
+end:
+       free(opt_input_format);
+       free(opt_output_format);
+       if (partial_error)
+               exit(EXIT_FAILURE);
+       else
+               exit(EXIT_SUCCESS);
 }
This page took 0.02773 seconds and 4 git commands to generate.