src/c2html.c

Thu, 23 Jan 2014 14:17:06 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 23 Jan 2014 14:17:06 +0100
changeset 22
f463693b5eeb
parent 21
537aec525835
child 23
f44a185b678b
permissions
-rw-r--r--

added command line parameters for header and footer file

     1 #include <errno.h>
     3 #include "c2html.h"
     5 inputfile_t *inputfilebuffer(size_t capacity) {
     6     inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t));
     7     inputfile->lines = (char**) malloc(capacity * sizeof(char*));
     8     inputfile->capacity = capacity;
     9     inputfile->count = 0;
    10     inputfile->maxlinewidth = 0;
    12     return inputfile;
    13 }
    15 void addline(inputfile_t *inputfile, char* line, size_t width) {
    16     char *l = (char*) malloc(width+1);
    17     memcpy(l, line, width);
    18     l[width] = 0;
    19     if (inputfile->count >= inputfile->capacity) {
    20         inputfile->capacity <<= 1;
    21         inputfile->lines = realloc(inputfile->lines, inputfile->capacity);
    22     }
    23     inputfile->lines[inputfile->count] = l;
    24     inputfile->maxlinewidth =
    25         width > inputfile->maxlinewidth ? width : inputfile->maxlinewidth;
    26     inputfile->count++;
    27 }
    29 void freeinputfilebuffer(inputfile_t *inputfile) {
    30     for (int i = 0 ; i < inputfile->count ; i++) {
    31         free(inputfile->lines[i]);
    32     }
    33     free(inputfile->lines);
    34     free(inputfile);
    35 }
    37 inputfile_t *readinput(char *filename) {
    39     int fd = open(filename, O_RDONLY);
    40     if (fd == -1) return NULL;
    42     inputfile_t *inputfile = inputfilebuffer(512);
    44     char buf[INPUTBUF_SIZE];
    45     ssize_t r;
    47     size_t maxlinewidth = 256;
    48     char *line = (char*) malloc(maxlinewidth);
    49     size_t col = 0;
    51     while ((r = read(fd, buf, INPUTBUF_SIZE)) > 0) {
    52         for (size_t i = 0 ; i < r ; i++) {
    53             if (col >= maxlinewidth-4) {
    54                 maxlinewidth <<= 1;
    55                 line = realloc(line, maxlinewidth);
    56             }
    58             if (buf[i] == '\n') {
    59                 line[col++] = '\n';
    60                 line[col] = 0;
    61                 addline(inputfile, line, col);
    62                 col = 0;
    63             } else {
    64                 line[col++] = buf[i];
    65             }
    66         }
    67     }
    69     free(line);
    71     close(fd);
    73     return inputfile;
    74 }
    76 void printhelp() {
    77     printf("Formats source code using HTML.\n\nUsage:\n"
    78         "  c2html [Options] FILE\n\n"
    79         " Options:\n"
    80         "  -h                    Prints this help message\n"
    81         "  -j                    Highlight Java instead of C source code\n"
    82         "  -o <output>           Output file (stdout, if not specified)\n"
    83         "  -H <header>           Prepend header file\n"
    84         "  -F <footer>           Append footer file\n"
    85         "  -p                    Disable highlighting (plain text)\n"
    86         "\n");
    89 }
    91 int lnint(size_t lnc) {
    92     int w = 1, p = 1;
    93     while ((p*=10) < lnc) w++;
    94     return w;
    95 }
    97 int copyfile(char *filename, FILE *dest) {
    98     if (!filename) {
    99         return 0;
   100     }
   102     FILE *src = fopen(filename, "r");
   103     if (src) {
   104         char buf[4096];
   105         int r;
   106         while ((r = fread(buf, 1, 4096, src)) > 0) {
   107             fwrite(buf, 1, r, dest);
   108         }
   109         fclose(src);
   110         return 0;
   111     } else {
   112         return errno;
   113     }
   114 }
   116 int main(int argc, char** argv) {
   117     int retcode = EXIT_SUCCESS;
   119     settings_t settings;
   120     memset(&settings, 0, sizeof(settings));
   121     settings.highlight = 1;
   123     highlighter_t highlighter;
   124     memset(&highlighter, 0, sizeof(highlighter));
   125     highlighter.isdirective = iscdirective;
   126     highlighter.istype = isctype;
   127     highlighter.keywords = ckeywords;
   128     highlighter.parser = cparseline;
   130     char optc;
   131     while ((optc = getopt(argc, argv, "hjo:pH:F:")) != -1) {
   132         switch (optc) {
   133             case 'o':
   134                 if (!(optarg[0] == '-' && optarg[1] == 0)) {
   135                     settings.outfilename = optarg;
   136                 }
   137                 break;
   138             case 'F':
   139                 settings.footerfile = optarg;
   140                 break;
   141             case 'H':
   142                 settings.headerfile = optarg;
   143                 break;
   144             case 'j':
   145                 highlighter.isdirective = isjdirective;
   146                 highlighter.istype = isjtype;
   147                 highlighter.keywords = jkeywords;
   148                 highlighter.parser = jparseline;
   149                 break;
   150             case 'p':
   151                 settings.highlight = 0;
   152                 break;
   153             case 'h':
   154                 printhelp();
   155                 return 0;
   156             default:
   157                 return 1;
   158         }
   159     }
   161     if (optind != argc-1) {
   162         printhelp();
   163         return 1;
   164     } else {
   165         settings.infilename = argv[optind];
   166         FILE *fout;
   167         if (settings.outfilename) {
   168             fout = fopen(settings.outfilename, "w");
   169             if (!fout) {
   170                 perror("Error opening output file");
   171                 return errno;
   172             }
   173         } else {
   174             fout = stdout;
   175         }
   177         if (copyfile(settings.headerfile, fout)) {
   178             perror("Error opening header file");
   179             retcode = errno;
   180             goto prog_end;
   181         }
   183         inputfile_t *inputfile = readinput(settings.infilename);
   184         if (inputfile) {
   185             char *line;
   186             if (settings.highlight) {
   187                 line = (char*) malloc(inputfile->maxlinewidth*64);
   188             } else {
   189                 line = NULL;
   190             }
   191             fprintf(fout, "<pre>\n");
   192             int lnw = lnint(inputfile->count);
   193             for (int i = 0 ; i < inputfile->count ; i++) {
   194                 if (settings.highlight) {
   195                     highlighter.parser(inputfile->lines[i], line, &highlighter);
   196                 } else {
   197                     line = inputfile->lines[i];
   198                 }
   199                 fprintf(fout, "<span class=\"c2html-lineno\">%*d:</span> %s",
   200                     lnw, i+1, line);
   201             }
   202             if (settings.highlight) {
   203                 free(line);
   204             }
   205             fprintf(fout, "</pre>\n");
   207             freeinputfilebuffer(inputfile);
   209             if (copyfile(settings.footerfile, fout)) {
   210                 perror("Error opening footer file");
   211                 retcode = errno;
   212             }
   213         } else {
   214             perror("Error opening input file");
   215             retcode = errno;
   216         }
   218         prog_end:        
   219         if (fout != stdout) {
   220             fclose(fout);
   221         }
   223         return retcode;
   224     }
   225 }

mercurial