-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchaptercat.c
More file actions
94 lines (89 loc) · 2.92 KB
/
Copy pathchaptercat.c
File metadata and controls
94 lines (89 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char *keyPrefix = "chapterCatAuto";
const char *versionString = "1.0";
int isFragmentInvalid(const char * const fragment) {
return strchr(fragment, ';') != NULL || strchr(fragment, '\n') != NULL;
}
int main(int argc, char* argv[]) {
if(argc < 2 || !strcmp(argv[1], "--help")) {
printf("Usage: %s [specification file name]\n", argv[0]);
return argc < 2;
}
if(!strcmp(argv[1], "--version")) {
puts(versionString);
return 0;
}
FILE *specFile = fopen(argv[1], "r");
if(specFile) {
fseek(specFile, 0L, SEEK_END);
const size_t specFileSize = ftell(specFile);
fseek(specFile, 0L, SEEK_SET);
const size_t specBufferSize = specFileSize + 1;
void *specBuffer = malloc(specBufferSize);
memset(specBuffer, '\0', specBufferSize);
fread(specBuffer, 1, specFileSize, specFile);
fclose(specFile);
char *specBody = specBuffer;
const size_t bufferSize = 16384;
char *buffer = malloc(bufferSize);
memset(buffer, 0, bufferSize);
size_t documentBodySize = 1;
char *documentBody = malloc(1);
documentBody[0] = '\0';
size_t tocBodySize = 1;
char *tocBody = malloc(1);
tocBody[0] = '\0';
int chapterNumber = 0;
do {
char *chapterFilename = strsep(&specBody, ";");
char *chapterName = strsep(&specBody, "\n");
if(chapterFilename == NULL || chapterName == NULL)
break;
else if(isFragmentInvalid(chapterFilename)) {
fprintf(stderr, "Invalid fragment: %s", chapterFilename);
break;
}
else if(isFragmentInvalid(chapterName)) {
fprintf(stderr, "Invalid fragment: %s", chapterName);
break;
}
FILE *chapterFile = fopen(chapterFilename, "r");
if(chapterFile != NULL) {
chapterNumber++;
fseek(chapterFile, 0L, SEEK_END);
const size_t chapterFileSize = ftell(chapterFile);
fseek(chapterFile, 0L, SEEK_SET);
const size_t chapterBufferSize = chapterFileSize + 1;
char *chapterBuffer = malloc(chapterBufferSize);
memset(chapterBuffer, 0, chapterBufferSize);
fread(chapterBuffer, 1, chapterFileSize, chapterFile);
fclose(chapterFile);
snprintf(buffer, bufferSize, "# <span id='%s%i'>%s</span>\n\n", keyPrefix, chapterNumber, chapterName);
documentBodySize += strlen(buffer) + chapterFileSize + 2L;
documentBody = realloc(documentBody, documentBodySize);
strcat(documentBody, buffer);
strncat(documentBody, chapterBuffer, chapterFileSize);
strcat(documentBody, "\n\n");
snprintf(buffer, bufferSize, "- [%s](#%s%i)\n\n", chapterName, keyPrefix, chapterNumber);
tocBodySize += strlen(buffer);
tocBody = realloc(tocBody, tocBodySize);
strcat(tocBody, buffer);
}
else {
fprintf(stderr, "Cannot open file: %s", chapterFilename);
}
} while(1);
printf("%s%s", tocBody, documentBody);
free(tocBody);
free(buffer);
free(documentBody);
free(specBuffer);
return 0;
}
else {
fprintf(stderr, "Error: Failed to open specification file.\n");
return 1;
}
}