src/c2html.c

changeset 55
bf54085ce341
parent 53
5e47a26a16f0
child 57
eba880c1705c
     1.1 --- a/src/c2html.c	Wed Aug 31 12:58:48 2016 +0200
     1.2 +++ b/src/c2html.c	Wed Aug 31 14:41:56 2016 +0200
     1.3 @@ -27,47 +27,21 @@
     1.4   *
     1.5   */
     1.6  
     1.7 -#include <unistd.h>
     1.8 -
     1.9  #include "c2html.h"
    1.10 -#include "highlighter.h"
    1.11  
    1.12  #include "ucx/list.h"
    1.13 +#include "ucx/utils.h"
    1.14  
    1.15 -static int appendfile(const char *filename, FILE *fout,
    1.16 -        char *copybuf, size_t copybuflen, const char *errmsg) {
    1.17 -    FILE *headerfile = fopen(filename, "r");
    1.18 -    if (!headerfile) {
    1.19 -        perror(errmsg);
    1.20 -        if (fout != stdout) {
    1.21 -            fclose(fout);
    1.22 -        }
    1.23 -        return 1;
    1.24 +#define try_write(wfnc, str, n, buf, written, maxlen) \
    1.25 +    {                                              \
    1.26 +        size_t m = maxlen-written;                    \
    1.27 +        written += wfnc(str, 1, n > m ? m : n, buf);  \
    1.28      }
    1.29 -    ucx_stream_copy(headerfile, fout,
    1.30 -            (read_func) fread, (write_func) fwrite,
    1.31 -            copybuf, copybuflen, (size_t)-1);
    1.32 -    fclose(headerfile);
    1.33 -    return 0;
    1.34 -}
    1.35  
    1.36 -static void printhelp() {
    1.37 -    printf("Formats source code using HTML.\n\nUsage:\n"
    1.38 -        "  c2html [Options] FILE\n\n"
    1.39 -        " Options:\n"
    1.40 -        "  -h                    Prints this help message\n"
    1.41 -        "  -j                    Highlight Java instead of C source code\n"
    1.42 -        "  -o <output>           Output file (stdout, if not specified)\n"
    1.43 -        "  -H <header>           Prepend header file\n"
    1.44 -        "  -F <footer>           Append footer file\n"
    1.45 -        "  -p                    Disable highlighting (plain text)\n"
    1.46 -        "  -l                    Disable line numbers\n"
    1.47 -        "  -V, -v                Prints version and exits\n"
    1.48 -        "\n");
    1.49 -}
    1.50 -
    1.51 -static void formatlines(highlighter_func highlighter,
    1.52 -        UcxList *in, write_func out, void *stream, int showlineno) {
    1.53 +static size_t formatlines(c2html_highlighter_func highlighter, UcxList *in,
    1.54 +        void *outbuf, write_func wfnc, size_t maxlen, int showlineno) {
    1.55 +    /* total written bytes */
    1.56 +    size_t written = 0;
    1.57      
    1.58      /* compute width of line numbering */
    1.59      int lnw = 0;
    1.60 @@ -77,16 +51,15 @@
    1.61      }
    1.62      
    1.63      /* start monospace formatting */
    1.64 -    out("<pre>\n", 1, 6, stream);
    1.65 +    try_write(wfnc, "<pre>\n", 6, outbuf, written, maxlen);
    1.66  
    1.67      /* process lines */
    1.68      size_t lineno = 0;
    1.69 -    HighlighterData *hd = new_highlighter_data();
    1.70 +    c2html_highlighter_data* hd = malloc(sizeof(c2html_highlighter_data));
    1.71 +    hd->multiline_comment = 0;
    1.72 +    hd->primary_buffer = ucx_buffer_new(NULL, 256, UCX_BUFFER_AUTOEXTEND);
    1.73 +    hd->secondary_buffer = ucx_buffer_new(NULL, 32, UCX_BUFFER_AUTOEXTEND);
    1.74      UcxBuffer *line = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
    1.75 -    if(!line || !hd) {
    1.76 -        perror("Error allocating buffer for output");
    1.77 -        return;
    1.78 -    }
    1.79      
    1.80      UCX_FOREACH(sourceline, in) {
    1.81          /* increase line number and clean line buffer */
    1.82 @@ -104,163 +77,63 @@
    1.83          highlighter(sourceline->data, line, hd);
    1.84          
    1.85          /* write code line */
    1.86 -        out(line->space, 1, line->size, stream);
    1.87 +        try_write(wfnc, line->space, line->size, outbuf, written, maxlen);
    1.88 +        
    1.89 +        if (written == maxlen) break;
    1.90      }
    1.91      
    1.92      /* end monospace formatting */
    1.93 -    out("</pre>\n", 1, 7, stream);
    1.94 +    try_write(wfnc, "</pre>\n", 7, outbuf, written, maxlen);
    1.95      
    1.96      /* cleanup and return */
    1.97 -    free_highlighter_data(hd);
    1.98 +    ucx_buffer_free(hd->primary_buffer);
    1.99 +    ucx_buffer_free(hd->secondary_buffer);
   1.100 +    free(hd);
   1.101      ucx_buffer_free(line);
   1.102 +    
   1.103 +    return written;
   1.104  }
   1.105  
   1.106 -#define FILEBUF_SIZE 4096
   1.107 +size_t c2html_formatn(void* inputbuffer, read_func rfnc,
   1.108 +        char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc,
   1.109 +        size_t maxlen, c2html_highlighter_func hltr, int showln) {
   1.110 +    
   1.111 +    UcxBuffer *content = ucx_buffer_new(NULL, ibuflen*2, UCX_BUFFER_AUTOEXTEND);
   1.112 +    ucx_stream_copy(inputbuffer, content, rfnc, (write_func) ucx_buffer_write,
   1.113 +            ibuf, ibuflen, (size_t)-1);
   1.114  
   1.115 -enum source_type {
   1.116 -    SOURCE_C,
   1.117 -    SOURCE_JAVA,
   1.118 -    SOURCE_PLAIN
   1.119 -};
   1.120 -
   1.121 -int main(int argc, char** argv) {
   1.122 -
   1.123 -    /* Default settings */
   1.124 -    Settings settings;
   1.125 -    memset(&settings, 0, sizeof(settings));
   1.126 -    settings.showlinenumbers = 1;
   1.127 -    enum source_type sourcetype = SOURCE_C;
   1.128 -
   1.129 -    /* Parse command line */
   1.130 -    char optc;
   1.131 -    while ((optc = getopt(argc, argv, "hljo:pH:F:vV")) != -1) {
   1.132 -        switch (optc) {
   1.133 -            case 'o':
   1.134 -                if (!(optarg[0] == '-' && optarg[1] == 0)) {
   1.135 -                    settings.outfilename = optarg;
   1.136 -                }
   1.137 -                break;
   1.138 -            case 'F':
   1.139 -                settings.footerfile = optarg;
   1.140 -                break;
   1.141 -            case 'H':
   1.142 -                settings.headerfile = optarg;
   1.143 -                break;
   1.144 -            case 'j':
   1.145 -                sourcetype = SOURCE_JAVA;
   1.146 -                break;
   1.147 -            case 'p':
   1.148 -                sourcetype = SOURCE_PLAIN;
   1.149 -                break;
   1.150 -            case 'l':
   1.151 -                settings.showlinenumbers = 0;
   1.152 -                break;
   1.153 -            case 'h':
   1.154 -                printhelp();
   1.155 -                return EXIT_SUCCESS;
   1.156 -            case 'v':
   1.157 -            case 'V':
   1.158 -#ifdef VERSION_DEVELOP
   1.159 -                printf("%d.%d (unstable)\n", VERSION_MAJOR, VERSION_MINOR);
   1.160 -#else
   1.161 -                printf("%d.%d\n", VERSION_MAJOR, VERSION_MINOR);
   1.162 -#endif
   1.163 -                return EXIT_SUCCESS;
   1.164 -            default:
   1.165 -                return EXIT_FAILURE;
   1.166 +    UcxList *lines = ucx_list_append(NULL, content->space);
   1.167 +    for (size_t i = 1 ; i < content->size ; i++) {
   1.168 +        if (content->space[i] == '\r') {
   1.169 +            content->space[i] = '\n'; i++;
   1.170 +        }
   1.171 +        if (content->space[i] == '\n' && i+1 < content->size) {
   1.172 +            ucx_list_append(lines, content->space+i+1);
   1.173          }
   1.174      }
   1.175 -
   1.176 -    if (optind != argc-1) {
   1.177 -        printhelp();
   1.178 -        return EXIT_FAILURE;
   1.179 -    } else {
   1.180 -        /* Choose highlighter */
   1.181 -        highlighter_func hltr = NULL;
   1.182 -        switch (sourcetype) {
   1.183 -            case SOURCE_C:
   1.184 -                hltr = c_highlighter;
   1.185 -                break;
   1.186 -            case SOURCE_JAVA:
   1.187 -                hltr = java_highlighter;
   1.188 -                break;
   1.189 -            case SOURCE_PLAIN:
   1.190 -                hltr = plain_highlighter;
   1.191 -                break;
   1.192 -            default: /* should be unreachable */
   1.193 -                fprintf(stderr, "error in enum source_type\n");
   1.194 -                return EXIT_FAILURE;
   1.195 -        }
   1.196 -        
   1.197 -        /* Open output file */
   1.198 -        settings.infilename = argv[optind];
   1.199 -        FILE *fout;
   1.200 -        if (settings.outfilename) {
   1.201 -            fout = fopen(settings.outfilename, "w");
   1.202 -            if (!fout) {
   1.203 -                perror("Error opening output file");
   1.204 -                return EXIT_FAILURE;
   1.205 -            }
   1.206 -        } else {
   1.207 -            fout = stdout;
   1.208 -        }
   1.209 -        
   1.210 -        /* Allocate file buffer  */
   1.211 -        char *filebuf = malloc(FILEBUF_SIZE);
   1.212 -        if (!filebuf) {
   1.213 -            perror("Error allocating file buffer");
   1.214 -            return EXIT_FAILURE;
   1.215 -        }
   1.216 -        
   1.217 -        /* Prepend header file */
   1.218 -        if (appendfile(settings.headerfile, fout, filebuf, FILEBUF_SIZE,
   1.219 -                "Error opening header file")) {
   1.220 -            return EXIT_FAILURE;
   1.221 -        }
   1.222 -
   1.223 -        /* Process input file */
   1.224 -        FILE *inputfile = fopen(settings.infilename, "r");
   1.225 -        if (inputfile) {
   1.226 -            UcxBuffer *content = ucx_buffer_new(NULL,
   1.227 -                    FILEBUF_SIZE*2, UCX_BUFFER_AUTOEXTEND);
   1.228 -            {
   1.229 -                ucx_stream_copy(inputfile, content, (read_func) fread,
   1.230 -                        (write_func) ucx_buffer_write,
   1.231 -                        filebuf, FILEBUF_SIZE, (size_t)-1);
   1.232 -            }
   1.233 -            fclose(inputfile);
   1.234 -            
   1.235 -            UcxList *inputlines = ucx_list_append(NULL, content->space);
   1.236 -            for (size_t i = 1 ; i < content->size ; i++) {
   1.237 -                if (content->space[i] == '\r') {
   1.238 -                    content->space[i] = '\n'; i++;
   1.239 -                }
   1.240 -                if (content->space[i] == '\n' && i+1 < content->size) {
   1.241 -                    ucx_list_append(inputlines, content->space+i+1);
   1.242 -                }
   1.243 -            }
   1.244 -            
   1.245 -            formatlines(hltr, inputlines,
   1.246 -                    (write_func) fwrite, fout, settings.showlinenumbers);
   1.247 -            
   1.248 -            ucx_buffer_free(content);
   1.249 -        } else {
   1.250 -            perror("Error opening input file");
   1.251 -            if (fout != stdout) {
   1.252 -                fclose(fout);
   1.253 -            }
   1.254 -            return EXIT_FAILURE;
   1.255 -        }
   1.256 -        
   1.257 -        /* Append footer file */
   1.258 -        if (appendfile(settings.footerfile, fout, filebuf, FILEBUF_SIZE,
   1.259 -                "Error opening footer file")) {
   1.260 -            return EXIT_FAILURE;
   1.261 -        }
   1.262 -        
   1.263 -        free(filebuf);
   1.264 -
   1.265 -        return EXIT_SUCCESS;
   1.266 -    }
   1.267 +    
   1.268 +    size_t n = formatlines(hltr, lines, outputbuffer, wfnc, maxlen, showln);
   1.269 +    
   1.270 +    ucx_buffer_free(content);
   1.271 +    return n;
   1.272  }
   1.273  
   1.274 +size_t c2html_format(void* inputbuffer, read_func rfnc,
   1.275 +        char* ibuf, size_t ibuflen, void* outputbuffer, write_func wfnc,
   1.276 +        c2html_highlighter_func hltr, int showln) {
   1.277 +    return c2html_formatn(inputbuffer, rfnc, ibuf, ibuflen,
   1.278 +            outputbuffer, wfnc, (size_t)-1, hltr, showln);
   1.279 +}
   1.280 +
   1.281 +size_t c2html_format_file(FILE* inputfile, char *ibuf, size_t ibuflen,
   1.282 +        void* outputbuffer, write_func wfnc,
   1.283 +        c2html_highlighter_func hltr, int showln) {
   1.284 +    return c2html_format(inputfile, (read_func) fread, ibuf, ibuflen,
   1.285 +            outputbuffer, wfnc, hltr, showln);
   1.286 +}
   1.287 +
   1.288 +void c2html_fformat_file(FILE *inputfile, char *ibuf, size_t ibuflen,
   1.289 +        FILE* outputfile, c2html_highlighter_func hltr, int showln) {
   1.290 +    c2html_format(inputfile, (read_func) fread, ibuf, ibuflen,
   1.291 +            outputfile, (write_func) fwrite, hltr, showln);
   1.292 +}

mercurial