src/c2html.c

changeset 39
ac35daceb24c
parent 38
77c158821738
child 40
903b46fc4214
     1.1 --- a/src/c2html.c	Tue Aug 23 12:06:46 2016 +0200
     1.2 +++ b/src/c2html.c	Tue Aug 23 13:49:38 2016 +0200
     1.3 @@ -28,77 +28,9 @@
     1.4   */
     1.5  #include "c2html.h"
     1.6  
     1.7 -inputfile_t *inputfilebuffer(size_t capacity) {
     1.8 -    inputfile_t *inputfile = (inputfile_t*) malloc(sizeof(inputfile_t));
     1.9 -    inputfile->lines = (char**) malloc(capacity * sizeof(char*));
    1.10 -    inputfile->capacity = capacity;
    1.11 -    inputfile->count = 0;
    1.12 -    inputfile->maxlinewidth = 0;
    1.13 -
    1.14 -    return inputfile;
    1.15 -}
    1.16 -
    1.17 -void addline(inputfile_t *inputfile, char* line, size_t width) {
    1.18 -    char *l = (char*) malloc(width+1);
    1.19 -    memcpy(l, line, width);
    1.20 -    l[width] = 0;
    1.21 -    if (inputfile->count >= inputfile->capacity) {
    1.22 -        inputfile->capacity <<= 1;
    1.23 -        inputfile->lines = realloc(inputfile->lines,
    1.24 -            sizeof(char*)*inputfile->capacity);
    1.25 -    }
    1.26 -    inputfile->lines[inputfile->count] = l;
    1.27 -    inputfile->maxlinewidth =
    1.28 -        width > inputfile->maxlinewidth ? width : inputfile->maxlinewidth;
    1.29 -    inputfile->count++;
    1.30 -}
    1.31 -
    1.32 -void freeinputfilebuffer(inputfile_t *inputfile) {
    1.33 -    for (int i = 0 ; i < inputfile->count ; i++) {
    1.34 -        free(inputfile->lines[i]);
    1.35 -    }
    1.36 -    free(inputfile->lines);
    1.37 -    free(inputfile);
    1.38 -}
    1.39 -
    1.40 -inputfile_t *readinput(char *filename) {
    1.41 -
    1.42 -    int fd = open(filename, O_RDONLY);
    1.43 -    if (fd == -1) return NULL;
    1.44 -
    1.45 -    inputfile_t *inputfile = inputfilebuffer(512);
    1.46 -
    1.47 -    char buf[INPUTBUF_SIZE];
    1.48 -    ssize_t r;
    1.49 -
    1.50 -    size_t maxlinewidth = 256;
    1.51 -    char *line = (char*) malloc(maxlinewidth);
    1.52 -    size_t col = 0;
    1.53 -
    1.54 -    while ((r = read(fd, buf, INPUTBUF_SIZE)) > 0) {
    1.55 -        for (size_t i = 0 ; i < r ; i++) {
    1.56 -            if (col >= maxlinewidth-4) {
    1.57 -                maxlinewidth <<= 1;
    1.58 -                line = realloc(line, maxlinewidth);
    1.59 -            }
    1.60 -
    1.61 -            if (buf[i] == '\n') {
    1.62 -                line[col++] = '\n';
    1.63 -                line[col] = 0;
    1.64 -                addline(inputfile, line, col);
    1.65 -                col = 0;
    1.66 -            } else {
    1.67 -                line[col++] = buf[i];
    1.68 -            }
    1.69 -        }
    1.70 -    }
    1.71 -
    1.72 -    free(line);
    1.73 -
    1.74 -    close(fd);
    1.75 -
    1.76 -    return inputfile;
    1.77 -}
    1.78 +#include "ucx/buffer.h"
    1.79 +#include "ucx/list.h"
    1.80 +#include "ucx/utils.h"
    1.81  
    1.82  void printhelp() {
    1.83      printf("Formats source code using HTML.\n\nUsage:\n"
    1.84 @@ -115,12 +47,6 @@
    1.85          "\n");
    1.86  }
    1.87  
    1.88 -int lnint(size_t lnc) {
    1.89 -    int w = 1, p = 1;
    1.90 -    while ((p*=10) < lnc) w++;
    1.91 -    return w;
    1.92 -}
    1.93 -
    1.94  int copyfile(char *filename, FILE *dest) {
    1.95      if (!filename) {
    1.96          return 0;
    1.97 @@ -136,60 +62,71 @@
    1.98          fclose(src);
    1.99          return 0;
   1.100      } else {
   1.101 -        return -1;
   1.102 +        return 1;
   1.103      }
   1.104  }
   1.105  
   1.106  #define WRITECONST(stream, out, cstr) out(cstr, 1, sizeof(cstr)-1, stream)
   1.107  int formatfile(
   1.108          highlighter_t *highlighter,
   1.109 -        inputfile_t *in,
   1.110 -        fmt_write_func out,
   1.111 +        UcxList *in,
   1.112 +        write_func out,
   1.113          void *stream,
   1.114 -        _Bool showln) {
   1.115 -    // formats an input file and writes the result to out
   1.116 +        int showlineno) {
   1.117 +    size_t lines = ucx_list_size(in);
   1.118      
   1.119 -    char *line = malloc(in->maxlinewidth*64);
   1.120 +    UcxBuffer *line = ucx_buffer_new(NULL, 1024, UCX_BUFFER_AUTOEXTEND);
   1.121      if(!line) {
   1.122          return 1;
   1.123      }
   1.124      WRITECONST(stream, out, "<pre>\n");
   1.125      
   1.126 -    int lnw = lnint(in->count);
   1.127 -    for (int i = 0 ; i < in->count ; i++) {
   1.128 +    int lnw;
   1.129 +    {
   1.130 +        lnw = 1;
   1.131 +        int p = 1;
   1.132 +        while ((p*=10) < lines) lnw++;
   1.133 +    }
   1.134 +
   1.135 +    size_t lineno = 0;
   1.136 +    UCX_FOREACH(sourceline, in) {
   1.137 +        lineno++;
   1.138 +        /* TODO: backwards compatibility: replace line->space in all occasions
   1.139 +         * and use UcxBuffer functions
   1.140 +         */
   1.141          if (highlighter) {
   1.142 -            highlighter->parser(in->lines[i], line, highlighter);
   1.143 +            highlighter->parser(sourceline->data, line->space, highlighter);
   1.144          } else {
   1.145 -            char *c = in->lines[i];
   1.146 +            char *c = sourceline->data;
   1.147              size_t dp = 0;
   1.148              while (*c) {
   1.149 -                dp = writeescapedchar(line, dp, *c);
   1.150 +                dp = writeescapedchar(line->space, dp, *c);
   1.151                  c++;
   1.152              }
   1.153 -            line[dp] = '\0';
   1.154 +            line->space[dp] = '\0';
   1.155          }
   1.156  
   1.157          // write line number
   1.158 -        if (showln) {
   1.159 +        if (showlineno) {
   1.160              WRITECONST(stream, out, "<span class=\"c2html-lineno\">");
   1.161              char lnbuf[128];
   1.162              int len;
   1.163              // line number link
   1.164              len = snprintf(lnbuf, 128, "<a name=\"l%d\" href=\"#l%d\">",
   1.165 -                i+1, i+1);
   1.166 +                lineno, lineno);
   1.167              out(lnbuf, 1, len, stream);
   1.168              // justified line number
   1.169 -            len = snprintf(lnbuf, 128, "%*d ", lnw, i+1);
   1.170 +            len = snprintf(lnbuf, 128, "%*d ", lnw, lineno);
   1.171              out(lnbuf, 1, len, stream);
   1.172              WRITECONST(stream, out, "</a></span> ");
   1.173          }
   1.174          
   1.175          // write formated (or plain) code line
   1.176 -        out(line, 1, strlen(line), stream);
   1.177 +        out(line->space, 1, strlen(line->space), stream);
   1.178      }
   1.179      
   1.180      WRITECONST(stream, out, "</pre>\n");
   1.181 -    free(line);
   1.182 +    ucx_buffer_free(line);
   1.183      return 0;
   1.184  }
   1.185  
   1.186 @@ -209,15 +146,20 @@
   1.187      highlighter->parser = jparseline;
   1.188  }
   1.189  
   1.190 +enum source_type {
   1.191 +    SOURCE_C,
   1.192 +    SOURCE_JAVA,
   1.193 +    SOURCE_PLAIN
   1.194 +};
   1.195 +
   1.196  int main(int argc, char** argv) {
   1.197      int retcode = EXIT_SUCCESS;
   1.198      
   1.199 -    settings_t settings;
   1.200 +    Settings settings;
   1.201      memset(&settings, 0, sizeof(settings));
   1.202 -    settings.highlight = 1;
   1.203      settings.showlinenumbers = 1;
   1.204      
   1.205 -    int lang = C2HTML_C;
   1.206 +    enum source_type sourcetype = SOURCE_C;
   1.207  
   1.208      char optc;
   1.209      while ((optc = getopt(argc, argv, "hljo:pH:F:vV")) != -1) {
   1.210 @@ -234,10 +176,10 @@
   1.211                  settings.headerfile = optarg;
   1.212                  break;
   1.213              case 'j':
   1.214 -                lang = C2HTML_JAVA;
   1.215 +                sourcetype = SOURCE_JAVA;
   1.216                  break;
   1.217              case 'p':
   1.218 -                settings.highlight = 0;
   1.219 +                sourcetype = SOURCE_PLAIN;
   1.220                  break;
   1.221              case 'l':
   1.222                  settings.showlinenumbers = 0;
   1.223 @@ -282,30 +224,53 @@
   1.224          
   1.225          highlighter_t highlighter;
   1.226          highlighter_t *hptr = &highlighter;
   1.227 -        switch (lang) {
   1.228 -            case C2HTML_C:
   1.229 +        switch (sourcetype) {
   1.230 +            case SOURCE_C:
   1.231                  init_c_highlighter(&highlighter);
   1.232                  break;
   1.233 -            case C2HTML_JAVA:
   1.234 +            case SOURCE_JAVA:
   1.235                  init_java_highlighter(&highlighter);
   1.236                  break;
   1.237 -            default:
   1.238 +            case SOURCE_PLAIN:
   1.239                  hptr = NULL;
   1.240                  break;
   1.241 -        }
   1.242 -        if (!settings.highlight) {
   1.243 -            hptr = NULL;
   1.244 +            default: /* should be unreachable */
   1.245 +                fprintf(stderr, "error in enum source_type\n");
   1.246 +                retcode = EXIT_FAILURE;
   1.247 +                goto prog_end;
   1.248          }
   1.249  
   1.250 -        inputfile_t *inputfile = readinput(settings.infilename);
   1.251 +        FILE *inputfile = fopen(settings.infilename, "r");
   1.252          if (inputfile) {
   1.253 +            UcxBuffer *filebuf = ucx_buffer_new(NULL,
   1.254 +                    2048, UCX_BUFFER_AUTOEXTEND);
   1.255 +            {
   1.256 +                const size_t tmpbufsize = 512;
   1.257 +                char *tmpbuf = malloc(tmpbufsize);
   1.258 +                ucx_stream_copy(inputfile, filebuf, (read_func) fread,
   1.259 +                        (write_func) ucx_buffer_write,
   1.260 +                        tmpbuf, tmpbufsize, (size_t)-1);
   1.261 +                free(tmpbuf);
   1.262 +            }
   1.263 +            fclose(inputfile);
   1.264 +            
   1.265 +            UcxList *inputlines = ucx_list_append(NULL, filebuf->space);
   1.266 +            for (size_t i = 1 ; i < filebuf->size ; i++) {
   1.267 +                if (filebuf->space[i] == '\r') {
   1.268 +                    filebuf->space[i] = '\n'; i++;
   1.269 +                }
   1.270 +                if (filebuf->space[i] == '\n' && i+1 < filebuf->size) {
   1.271 +                    ucx_list_append(inputlines, filebuf->space+i+1);
   1.272 +                }
   1.273 +            }
   1.274 +            
   1.275              formatfile(
   1.276                      hptr,
   1.277 -                    inputfile,
   1.278 -                    (fmt_write_func)fwrite,
   1.279 +                    inputlines,
   1.280 +                    (write_func) fwrite,
   1.281                      fout,
   1.282                      settings.showlinenumbers);
   1.283 -            freeinputfilebuffer(inputfile);
   1.284 +            ucx_buffer_free(filebuf);
   1.285          } else {
   1.286              perror("Error opening input file");
   1.287              retcode = EXIT_FAILURE;

mercurial