diff options
author | Xavier Mendez <me@jmendeth.com> | 2014-10-20 00:23:24 +0200 |
---|---|---|
committer | Xavier Mendez <me@jmendeth.com> | 2014-10-20 00:23:24 +0200 |
commit | 4b700ce16e21bf0d25b7a3a089ac5cf550573224 (patch) | |
tree | 1e2cbb33e5f66ca5e2d9e3c50cb7a8b0b855392c | |
parent | 0af706e37c7f362b22b2a7b2686504370215b941 (diff) | |
download | rust-hoedown-4b700ce16e21bf0d25b7a3a089ac5cf550573224.tar.gz |
bin-refactor: Refactor!
-rw-r--r-- | bin/hoedown.c | 280 | ||||
-rw-r--r-- | bin/smartypants.c | 153 |
2 files changed, 407 insertions, 26 deletions
diff --git a/bin/hoedown.c b/bin/hoedown.c index 6a77d57..5aac21a 100644 --- a/bin/hoedown.c +++ b/bin/hoedown.c @@ -130,50 +130,300 @@ print_help(const char *basename) } +/* OPTION PARSING */ + +struct option_data { + char *basename; + int done; + + /* time reporting */ + int show_time; + + /* I/O */ + size_t iunit; + size_t ounit; + const char *filename; + + /* renderer */ + enum renderer_type renderer; + int toc_level; + hoedown_html_flags html_flags; + + /* parsing */ + hoedown_extensions extensions; + size_t max_nesting; +}; + +int +parse_short_option(char opt, char *next, void *opaque) +{ + struct option_data *data = opaque; + long int num; + int isNum = next ? parseint(next, &num) : 0; + + if (opt == 'h') { + print_help(data->basename); + data->done = 1; + return 0; + } + + if (opt == 'v') { + print_version(); + data->done = 1; + return 0; + } + + if (opt == 'T') { + data->show_time = 1; + return 1; + } + + /* options requiring value */ + /* FIXME: add validation */ + + if (opt == 'n' && isNum) { + data->max_nesting = num; + return 2; + } + + if (opt == 't' && isNum) { + data->toc_level = num; + return 2; + } + + if (opt == 'i' && isNum) { + data->iunit = num; + return 2; + } + + if (opt == 'o' && isNum) { + data->ounit = num; + return 2; + } + + fprintf(stderr, "Wrong option '-%c' found.\n", opt); + return 0; +} + +int +parse_category_option(char *opt, struct option_data *data) +{ + size_t i; + const char *name = strprefix(opt, category_prefix); + if (!name) return 0; + + for (i = 0; i < count_of(categories_info); i++) { + struct extension_category_info *category = &categories_info[i]; + if (strcmp(name, category->option_name)==0) { + data->extensions |= category->flags; + return 1; + } + } + + return 0; +} + +int +parse_flag_option(char *opt, struct option_data *data) +{ + size_t i; + + for (i = 0; i < count_of(extensions_info); i++) { + struct extension_info *extension = &extensions_info[i]; + if (strcmp(opt, extension->option_name)==0) { + data->extensions |= extension->flag; + return 1; + } + } + + for (i = 0; i < count_of(html_flags_info); i++) { + struct html_flag_info *html_flag = &html_flags_info[i]; + if (strcmp(opt, html_flag->option_name)==0) { + data->html_flags |= html_flag->flag; + return 1; + } + } + + return 0; +} + +int +parse_negative_option(char *opt, struct option_data *data) +{ + size_t i; + const char *name = strprefix(opt, negative_prefix); + if (!name) return 0; + + for (i = 0; i < count_of(categories_info); i++) { + struct extension_category_info *category = &categories_info[i]; + if (strcmp(name, category->option_name)==0) { + data->extensions &= ~(category->flags); + return 1; + } + } + + for (i = 0; i < count_of(extensions_info); i++) { + struct extension_info *extension = &extensions_info[i]; + if (strcmp(name, extension->option_name)==0) { + data->extensions &= ~(extension->flag); + return 1; + } + } + + for (i = 0; i < count_of(html_flags_info); i++) { + struct html_flag_info *html_flag = &html_flags_info[i]; + if (strcmp(name, html_flag->option_name)==0) { + data->html_flags &= ~(html_flag->flag); + return 1; + } + } + + return 0; +} + +int +parse_long_option(char *opt, char *next, void *opaque) +{ + struct option_data *data = opaque; + long int num; + int isNum = next ? parseint(next, &num) : 0; + + if (strcmp(opt, "help")==0) { + print_help(data->basename); + data->done = 1; + return 0; + } + + if (strcmp(opt, "version")==0) { + print_version(); + data->done = 1; + return 0; + } + + if (strcmp(opt, "time")==0) { + data->show_time = 1; + return 1; + } + + /* FIXME: validation */ + + if (strcmp(opt, "max-nesting")==0 && isNum) { + data->max_nesting = num; + return 2; + } + if (strcmp(opt, "toc-level")==0 && isNum) { + data->toc_level = num; + return 2; + } + if (strcmp(opt, "input-unit")==0 && isNum) { + data->iunit = num; + return 2; + } + if (strcmp(opt, "output-unit")==0 && isNum) { + data->ounit = num; + return 2; + } + + if (strcmp(opt, "html")==0) { + data->renderer = RENDERER_HTML; + return 1; + } + if (strcmp(opt, "html-toc")==0) { + data->renderer = RENDERER_HTML_TOC; + return 1; + } + + if (parse_category_option(opt, data) || parse_flag_option(opt, data) || parse_negative_option(opt, data)) + return 1; + + fprintf(stderr, "Wrong option '--%s' found.\n", opt); + return 0; +} + +int +parse_argument(int argn, char *arg, int is_forced, void *opaque) +{ + struct option_data *data = opaque; + + if (argn == 0) { + /* Input file */ + if (strcmp(arg, "-")!=0 || is_forced) data->filename = arg; + return 1; + } + + fprintf(stderr, "Too many arguments.\n"); + return 0; +} + + /* MAIN LOGIC */ int main(int argc, char **argv) { + struct option_data data; /*struct timespec start, end;*/ + FILE *file = stdin; hoedown_buffer *ib, *ob; - FILE *in = NULL; hoedown_renderer *renderer = NULL; - void (*renderer_free)(hoedown_renderer*) = NULL; + void (*renderer_free)(hoedown_renderer *) = NULL; hoedown_document *document; /* Parse options */ - /* TODO */ + data.basename = argv[0]; + data.done = 0; + data.show_time = 0; + data.iunit = DEF_IUNIT; + data.ounit = DEF_OUNIT; + data.filename = NULL; + data.renderer = RENDERER_HTML; + data.toc_level = 0; + data.html_flags = 0; + data.extensions = 0; + data.max_nesting = DEF_MAX_NESTING; + + argc = parse_options(argc, argv, parse_short_option, parse_long_option, parse_argument, &data); + if (data.done) return 0; + if (!argc) return 1; + + /* Open input file, if needed */ + if (data.filename) { + file = fopen(data.filename, "r"); + if (!file) { + fprintf(stderr, "Unable to open input file \"%s\": %s\n", data.filename, strerror(errno)); + return 5; + } + } /* Read everything */ - ib = hoedown_buffer_new(iunit); + ib = hoedown_buffer_new(data.iunit); - while (!feof(in)) { - if (ferror(in)) { + while (!feof(file)) { + if (ferror(file)) { fprintf(stderr, "I/O errors found while reading input.\n"); return 5; } - hoedown_buffer_grow(ib, ib->size + iunit); - ib->size += fread(ib->data + ib->size, 1, iunit, in); + hoedown_buffer_grow(ib, ib->size + data.iunit); + ib->size += fread(ib->data + ib->size, 1, data.iunit, file); } - if (in != stdin) fclose(in); + if (file != stdin) fclose(file); /* Create the renderer */ - switch (renderer_type) { + switch (data.renderer) { case RENDERER_HTML: - renderer = hoedown_html_renderer_new(html_flags, toc_level); + renderer = hoedown_html_renderer_new(data.html_flags, data.toc_level); renderer_free = hoedown_html_renderer_free; break; case RENDERER_HTML_TOC: - renderer = hoedown_html_toc_renderer_new(toc_level); + renderer = hoedown_html_toc_renderer_new(data.toc_level); renderer_free = hoedown_html_renderer_free; break; }; /* Perform Markdown rendering */ - ob = hoedown_buffer_new(ounit); - document = hoedown_document_new(renderer, extensions, max_nesting); + ob = hoedown_buffer_new(data.ounit); + document = hoedown_document_new(renderer, data.extensions, data.max_nesting); /*clock_gettime(CLOCK_MONOTONIC, &start);*/ hoedown_document_render(document, ob, ib->data, ib->size); @@ -183,7 +433,7 @@ main(int argc, char **argv) (void)fwrite(ob->data, 1, ob->size, stdout); /* Show rendering time */ - if (show_time) { + if (data.show_time) { /*TODO: enable this long long elapsed = (end.tv_sec - start.tv_sec)*1e9 + (end.tv_nsec - start.tv_nsec); if (elapsed < 1e9) diff --git a/bin/smartypants.c b/bin/smartypants.c index 127dc1c..de0512e 100644 --- a/bin/smartypants.c +++ b/bin/smartypants.c @@ -13,7 +13,8 @@ /* PRINT HELP */ void -print_help(const char *basename) { +print_help(const char *basename) +{ /* usage */ printf("Usage: %s [OPTION]... [FILE]\n\n", basename); @@ -37,34 +38,164 @@ print_help(const char *basename) { } +/* OPTION PARSING */ + +struct option_data { + char *basename; + int done; + + /* time reporting */ + int show_time; + + /* I/O */ + size_t iunit; + size_t ounit; + const char *filename; +}; + +int +parse_short_option(char opt, char *next, void *opaque) +{ + struct option_data *data = opaque; + long int num; + int isNum = next ? parseint(next, &num) : 0; + + if (opt == 'h') { + print_help(data->basename); + data->done = 1; + return 0; + } + + if (opt == 'v') { + print_version(); + data->done = 1; + return 0; + } + + if (opt == 'T') { + data->show_time = 1; + return 1; + } + + /* options requiring value */ + /* FIXME: add validation */ + + if (opt == 'i' && isNum) { + data->iunit = num; + return 2; + } + + if (opt == 'o' && isNum) { + data->ounit = num; + return 2; + } + + fprintf(stderr, "Wrong option '-%c' found.\n", opt); + return 0; +} + +int +parse_long_option(char *opt, char *next, void *opaque) +{ + struct option_data *data = opaque; + long int num; + int isNum = next ? parseint(next, &num) : 0; + + if (strcmp(opt, "help")==0) { + print_help(data->basename); + data->done = 1; + return 0; + } + + if (strcmp(opt, "version")==0) { + print_version(); + data->done = 1; + return 0; + } + + if (strcmp(opt, "time")==0) { + data->show_time = 1; + return 1; + } + + /* FIXME: validation */ + + if (strcmp(opt, "input-unit")==0 && isNum) { + data->iunit = num; + return 2; + } + if (strcmp(opt, "output-unit")==0 && isNum) { + data->ounit = num; + return 2; + } + + fprintf(stderr, "Wrong option '--%s' found.\n", opt); + return 0; +} + +int +parse_argument(int argn, char *arg, int is_forced, void *opaque) +{ + struct option_data *data = opaque; + + if (argn == 0) { + /* Input file */ + if (strcmp(arg, "-")!=0 || is_forced) data->filename = arg; + return 1; + } + + fprintf(stderr, "Too many arguments.\n"); + return 0; +} + + /* MAIN LOGIC */ int main(int argc, char **argv) { + struct option_data data; /*struct timespec start, end;*/ + FILE *file = stdin; hoedown_buffer *ib, *ob; - FILE *in = NULL; - ib = hoedown_buffer_new(iunit); /* Parse options */ - /*TODO*/ + data.basename = argv[0]; + data.done = 0; + data.show_time = 0; + data.iunit = DEF_IUNIT; + data.ounit = DEF_OUNIT; + data.filename = NULL; + + argc = parse_options(argc, argv, parse_short_option, parse_long_option, parse_argument, &data); + if (data.done) return 0; + if (!argc) return 1; + + /* Open input file, if needed */ + if (data.filename) { + file = fopen(data.filename, "r"); + if (!file) { + fprintf(stderr, "Unable to open input file \"%s\": %s\n", data.filename, strerror(errno)); + return 5; + } + } /* Read everything */ + ib = hoedown_buffer_new(data.iunit); - while (!feof(in)) { - if (ferror(in)) { + while (!feof(file)) { + if (ferror(file)) { fprintf(stderr, "I/O errors found while reading input.\n"); return 5; } - hoedown_buffer_grow(ib, ib->size + iunit); - ib->size += fread(ib->data + ib->size, 1, iunit, in); + hoedown_buffer_grow(ib, ib->size + data.iunit); + ib->size += fread(ib->data + ib->size, 1, data.iunit, file); } - if (in != stdin) fclose(in); + if (file != stdin) fclose(file); /* Perform SmartyPants processing */ - ob = hoedown_buffer_new(ounit); + ob = hoedown_buffer_new(data.ounit); /*clock_gettime(CLOCK_MONOTONIC, &start);*/ hoedown_html_smartypants(ob, ib->data, ib->size); @@ -74,7 +205,7 @@ main(int argc, char **argv) (void)fwrite(ob->data, 1, ob->size, stdout); /* Show rendering time */ - if (show_time) { + if (data.show_time) { /*TODO: enable this long long elapsed = (end.tv_sec - start.tv_sec)*1e9 + (end.tv_nsec - start.tv_nsec); if (elapsed < 1e9) |