src/c2html.c

Thu, 23 Jan 2014 09:19:37 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 23 Jan 2014 09:19:37 +0100
changeset 21
537aec525835
parent 20
ebbf0776c1bc
child 22
f463693b5eeb
permissions
-rw-r--r--

structured source code

     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  */
    30 #include <stdio.h>
    31 #include <stdlib.h>
    32 #include <string.h>
    33 #include <fcntl.h>
    34 #include <unistd.h>
    35 #include <ctype.h>
    37 #include "javacodegen.h"
    38 #include "ccodegen.h"
    40 #define INPUTBUF_SIZE 2048
    42 typedef struct {
    43     char* outfilename;
    44     char* infilename;
    45     int highlight;
    46 } settings_t;
    48 typedef struct {
    49     size_t count;
    50     size_t capacity;
    51     size_t maxlinewidth;
    52     char** lines;
    53 } inputfile_t;
    55 inputfile_t *inputfilebuffer(size_t capacity) {
    56     inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t));
    57     inputfile->lines = (char**) malloc(capacity * sizeof(char*));
    58     inputfile->capacity = capacity;
    59     inputfile->count = 0;
    60     inputfile->maxlinewidth = 0;
    62     return inputfile;
    63 }
    65 void addline(inputfile_t *inputfile, char* line, size_t width) {
    66     char *l = (char*) malloc(width+1);
    67     memcpy(l, line, width);
    68     l[width] = 0;
    69     if (inputfile->count >= inputfile->capacity) {
    70         inputfile->capacity <<= 1;
    71         inputfile->lines = realloc(inputfile->lines, inputfile->capacity);
    72     }
    73     inputfile->lines[inputfile->count] = l;
    74     inputfile->maxlinewidth =
    75         width > inputfile->maxlinewidth ? width : inputfile->maxlinewidth;
    76     inputfile->count++;
    77 }
    79 void freeinputfilebuffer(inputfile_t *inputfile) {
    80     for (int i = 0 ; i < inputfile->count ; i++) {
    81         free(inputfile->lines[i]);
    82     }
    83     free(inputfile->lines);
    84     free(inputfile);
    85 }
    87 inputfile_t *readinput(char *filename) {
    89     int fd = open(filename, O_RDONLY);
    90     if (fd == -1) return NULL;
    92     inputfile_t *inputfile = inputfilebuffer(512);
    94     char buf[INPUTBUF_SIZE];
    95     ssize_t r;
    97     size_t maxlinewidth = 256;
    98     char *line = (char*) malloc(maxlinewidth);
    99     size_t col = 0;
   101     while ((r = read(fd, buf, INPUTBUF_SIZE)) > 0) {
   102         for (size_t i = 0 ; i < r ; i++) {
   103             if (col >= maxlinewidth-4) {
   104                 maxlinewidth <<= 1;
   105                 line = realloc(line, maxlinewidth);
   106             }
   108             if (buf[i] == '\n') {
   109                 line[col++] = '\n';
   110                 line[col] = 0;
   111                 addline(inputfile, line, col);
   112                 col = 0;
   113             } else {
   114                 line[col++] = buf[i];
   115             }
   116         }
   117     }
   119     free(line);
   121     close(fd);
   123     return inputfile;
   124 }
   126 void printhelp() {
   127     printf("Formats source code using HTML.\n\nUsage:\n"
   128         "  c2html [Options] FILE\n\n"
   129         " Options:\n"
   130         "  -h                    Prints this help message\n"
   131         "  -j                    Highlight Java instead of C source code\n"
   132         "  -o <output>           Output file (stdout, if not specified)\n"
   133         "  -p                    Disable highlighting (plain text)\n"
   134         "\n");
   137 }
   139 int lnint(size_t lnc) {
   140     int w = 1, p = 1;
   141     while ((p*=10) < lnc) w++;
   142     return w;
   143 }
   145 int main(int argc, char** argv) {
   146     settings_t settings;
   147     settings.outfilename = NULL;
   148     settings.highlight = 1;
   150     highlighter_t highlighter;
   151     memset(&highlighter, 0, sizeof(highlighter));
   152     highlighter.isdirective = iscdirective;
   153     highlighter.istype = isctype;
   154     highlighter.keywords = ckeywords;
   155     highlighter.parser = cparseline;
   157     char optc;
   158     while ((optc = getopt(argc, argv, "hjo:p")) != -1) {
   159         switch (optc) {
   160             case 'o':
   161                 if (!(optarg[0] == '-' && optarg[1] == 0)) {
   162                     settings.outfilename = optarg;
   163                 }
   164                 break;
   165             case 'j':
   166                 highlighter.isdirective = isjdirective;
   167                 highlighter.istype = isjtype;
   168                 highlighter.keywords = jkeywords;
   169                 highlighter.parser = jparseline;
   170                 break;
   171             case 'p':
   172                 settings.highlight = 0;
   173                 break;
   174             case 'h':
   175                 printhelp();
   176                 return 0;
   177             default:
   178                 return 1;
   179         }
   180     }
   182     if (optind != argc-1) {
   183         printhelp();
   184         return 1;
   185     } else {
   186         settings.infilename = argv[optind];
   188         inputfile_t *inputfile = readinput(settings.infilename);
   189         if (inputfile) {
   190             FILE *fout;
   191             char *line;
   192             if (settings.highlight) {
   193                 line = (char*) malloc(inputfile->maxlinewidth*64);
   194             } else {
   195                 line = NULL;
   196             }
   197             if (settings.outfilename) {
   198                 fout = fopen(settings.outfilename, "w");
   199             } else {
   200                 fout = stdout;
   201             }
   202             fprintf(fout, "<pre>\n");
   203             int lnw = lnint(inputfile->count);
   204             for (int i = 0 ; i < inputfile->count ; i++) {
   205                 if (settings.highlight) {
   206                     highlighter.parser(inputfile->lines[i], line, &highlighter);
   207                 } else {
   208                     line = inputfile->lines[i];
   209                 }
   210                 fprintf(fout, "<span class=\"c2html-lineno\">%*d:</span> %s",
   211                     lnw, i+1, line);
   212             }
   213             if (settings.highlight) {
   214                 free(line);
   215             }
   216             fprintf(fout, "</pre>\n");
   218             if (fout != stdout) {
   219                 fclose(fout);
   220             }
   222             freeinputfilebuffer(inputfile);
   223         }
   225         return 0;
   226     }
   227 }

mercurial