src/c2html.c

Thu, 23 Jan 2014 14:44:20 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 23 Jan 2014 14:44:20 +0100
changeset 23
f44a185b678b
parent 22
f463693b5eeb
child 24
e43dee5892f4
permissions
-rw-r--r--

fixed licenses

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2014 Mike Becker. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  *
    28  */
    29 #include <errno.h>
    31 #include "c2html.h"
    33 inputfile_t *inputfilebuffer(size_t capacity) {
    34     inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t));
    35     inputfile->lines = (char**) malloc(capacity * sizeof(char*));
    36     inputfile->capacity = capacity;
    37     inputfile->count = 0;
    38     inputfile->maxlinewidth = 0;
    40     return inputfile;
    41 }
    43 void addline(inputfile_t *inputfile, char* line, size_t width) {
    44     char *l = (char*) malloc(width+1);
    45     memcpy(l, line, width);
    46     l[width] = 0;
    47     if (inputfile->count >= inputfile->capacity) {
    48         inputfile->capacity <<= 1;
    49         inputfile->lines = realloc(inputfile->lines, inputfile->capacity);
    50     }
    51     inputfile->lines[inputfile->count] = l;
    52     inputfile->maxlinewidth =
    53         width > inputfile->maxlinewidth ? width : inputfile->maxlinewidth;
    54     inputfile->count++;
    55 }
    57 void freeinputfilebuffer(inputfile_t *inputfile) {
    58     for (int i = 0 ; i < inputfile->count ; i++) {
    59         free(inputfile->lines[i]);
    60     }
    61     free(inputfile->lines);
    62     free(inputfile);
    63 }
    65 inputfile_t *readinput(char *filename) {
    67     int fd = open(filename, O_RDONLY);
    68     if (fd == -1) return NULL;
    70     inputfile_t *inputfile = inputfilebuffer(512);
    72     char buf[INPUTBUF_SIZE];
    73     ssize_t r;
    75     size_t maxlinewidth = 256;
    76     char *line = (char*) malloc(maxlinewidth);
    77     size_t col = 0;
    79     while ((r = read(fd, buf, INPUTBUF_SIZE)) > 0) {
    80         for (size_t i = 0 ; i < r ; i++) {
    81             if (col >= maxlinewidth-4) {
    82                 maxlinewidth <<= 1;
    83                 line = realloc(line, maxlinewidth);
    84             }
    86             if (buf[i] == '\n') {
    87                 line[col++] = '\n';
    88                 line[col] = 0;
    89                 addline(inputfile, line, col);
    90                 col = 0;
    91             } else {
    92                 line[col++] = buf[i];
    93             }
    94         }
    95     }
    97     free(line);
    99     close(fd);
   101     return inputfile;
   102 }
   104 void printhelp() {
   105     printf("Formats source code using HTML.\n\nUsage:\n"
   106         "  c2html [Options] FILE\n\n"
   107         " Options:\n"
   108         "  -h                    Prints this help message\n"
   109         "  -j                    Highlight Java instead of C source code\n"
   110         "  -o <output>           Output file (stdout, if not specified)\n"
   111         "  -H <header>           Prepend header file\n"
   112         "  -F <footer>           Append footer file\n"
   113         "  -p                    Disable highlighting (plain text)\n"
   114         "\n");
   117 }
   119 int lnint(size_t lnc) {
   120     int w = 1, p = 1;
   121     while ((p*=10) < lnc) w++;
   122     return w;
   123 }
   125 int copyfile(char *filename, FILE *dest) {
   126     if (!filename) {
   127         return 0;
   128     }
   130     FILE *src = fopen(filename, "r");
   131     if (src) {
   132         char buf[4096];
   133         int r;
   134         while ((r = fread(buf, 1, 4096, src)) > 0) {
   135             fwrite(buf, 1, r, dest);
   136         }
   137         fclose(src);
   138         return 0;
   139     } else {
   140         return errno;
   141     }
   142 }
   144 int main(int argc, char** argv) {
   145     int retcode = EXIT_SUCCESS;
   147     settings_t settings;
   148     memset(&settings, 0, sizeof(settings));
   149     settings.highlight = 1;
   151     highlighter_t highlighter;
   152     memset(&highlighter, 0, sizeof(highlighter));
   153     highlighter.isdirective = iscdirective;
   154     highlighter.istype = isctype;
   155     highlighter.keywords = ckeywords;
   156     highlighter.parser = cparseline;
   158     char optc;
   159     while ((optc = getopt(argc, argv, "hjo:pH:F:")) != -1) {
   160         switch (optc) {
   161             case 'o':
   162                 if (!(optarg[0] == '-' && optarg[1] == 0)) {
   163                     settings.outfilename = optarg;
   164                 }
   165                 break;
   166             case 'F':
   167                 settings.footerfile = optarg;
   168                 break;
   169             case 'H':
   170                 settings.headerfile = optarg;
   171                 break;
   172             case 'j':
   173                 highlighter.isdirective = isjdirective;
   174                 highlighter.istype = isjtype;
   175                 highlighter.keywords = jkeywords;
   176                 highlighter.parser = jparseline;
   177                 break;
   178             case 'p':
   179                 settings.highlight = 0;
   180                 break;
   181             case 'h':
   182                 printhelp();
   183                 return 0;
   184             default:
   185                 return 1;
   186         }
   187     }
   189     if (optind != argc-1) {
   190         printhelp();
   191         return 1;
   192     } else {
   193         settings.infilename = argv[optind];
   194         FILE *fout;
   195         if (settings.outfilename) {
   196             fout = fopen(settings.outfilename, "w");
   197             if (!fout) {
   198                 perror("Error opening output file");
   199                 return errno;
   200             }
   201         } else {
   202             fout = stdout;
   203         }
   205         if (copyfile(settings.headerfile, fout)) {
   206             perror("Error opening header file");
   207             retcode = errno;
   208             goto prog_end;
   209         }
   211         inputfile_t *inputfile = readinput(settings.infilename);
   212         if (inputfile) {
   213             char *line;
   214             if (settings.highlight) {
   215                 line = (char*) malloc(inputfile->maxlinewidth*64);
   216             } else {
   217                 line = NULL;
   218             }
   219             fprintf(fout, "<pre>\n");
   220             int lnw = lnint(inputfile->count);
   221             for (int i = 0 ; i < inputfile->count ; i++) {
   222                 if (settings.highlight) {
   223                     highlighter.parser(inputfile->lines[i], line, &highlighter);
   224                 } else {
   225                     line = inputfile->lines[i];
   226                 }
   227                 fprintf(fout, "<span class=\"c2html-lineno\">%*d:</span> %s",
   228                     lnw, i+1, line);
   229             }
   230             if (settings.highlight) {
   231                 free(line);
   232             }
   233             fprintf(fout, "</pre>\n");
   235             freeinputfilebuffer(inputfile);
   237             if (copyfile(settings.footerfile, fout)) {
   238                 perror("Error opening footer file");
   239                 retcode = errno;
   240             }
   241         } else {
   242             perror("Error opening input file");
   243             retcode = errno;
   244         }
   246         prog_end:        
   247         if (fout != stdout) {
   248             fclose(fout);
   249         }
   251         return retcode;
   252     }
   253 }

mercurial