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;