]> ocean-lang.org Git - ocean/blob - csrc/boot-strap/md2c.c
mdcode, md2c - extract C code from a literate markdown program
[ocean] / csrc / boot-strap / md2c.c
1 #line 119 "../mdcode.mdc"
2 #include <unistd.h>
3 #include <stdlib.h>
4
5 #include "mdcode.h"
6
7 #line 849 "../mdcode.mdc"
8 #include <fcntl.h>
9 #include <errno.h>
10 #include <sys/mman.h>
11 #include <string.h>
12 #include <stdio.h>
13
14 #line 771 "../mdcode.mdc"
15 static void code_print(FILE *out, struct code_node *node,
16                        char *fname)
17 {
18         for (; node; node = node->next) {
19                 char *c = node->code.txt;
20                 int len = node->code.len;
21                 int undent = 0;
22
23                 if (!len)
24                         continue;
25
26                 fprintf(out, "#line %d \"%s\"\n",
27                         node->line_no, fname);
28                 if (*c == ' ' || *c == '\t')
29                         undent = 1;
30                 while (len && *c) {
31                         fprintf(out, "%*s", node->indent, "");
32                         if (undent) {
33                                 if (*c == '\t' && len > 1) {
34                                         c++;
35                                         len--;
36                                 } else if (strncmp(c, "    ", 4) == 0 && len > 4) {
37                                         c += 4;
38                                         len-= 4;
39                                 }
40                         }
41                         do {
42                                 fputc(*c, out);
43                                 c++;
44                                 len--;
45                         } while (len && c[-1] != '\n');
46                 }
47         }
48 }
49
50 #line 821 "../mdcode.mdc"
51 static void copy_fname(char *name, int space, struct text t)
52 {
53         char *sec = t.txt;
54         int len = t.len;
55         name[0] = 0;
56         if (len < 5 || strncmp(sec, "File:", 5) != 0)
57                 return;
58         sec += 5;
59         len -= 5;
60         while (len && sec[0] == ' ') {
61                 sec++;
62                 len--;
63         }
64         if (len >= space)
65                 len = space - 1;
66         strncpy(name, sec, len);
67         name[len] = 0;
68 }
69
70 #line 857 "../mdcode.mdc"
71 static int errs;
72 static void pr_err(char *msg)
73 {
74         errs++;
75         fprintf(stderr, "%s\n", msg);
76 }
77
78 int main(int argc, char *argv[])
79 {
80         int fd;
81         size_t len;
82         char *file;
83         struct section *table, *s, *prev;
84
85         errs = 0;
86         if (argc != 2) {
87                 fprintf(stderr, "Usage: mdcode file.mdc\n");
88                 exit(2);
89         }
90         fd = open(argv[1], O_RDONLY);
91         if (fd < 0) {
92                 fprintf(stderr, "mdcode: cannot open %s: %s\n",
93                         argv[1], strerror(errno));
94                 exit(1);
95         }
96         len = lseek(fd, 0, 2);
97         file = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
98         table = code_extract(file, file+len, pr_err);
99
100         for (s = table; s;
101                 (code_free(s->code), prev = s, s = s->next, free(prev))) {
102                 FILE *fl;
103                 char fname[1024];
104                 if (strncmp(s->section.txt, "Example:", 8) == 0)
105                         continue;
106                 if (strncmp(s->section.txt, "File:", 5) != 0) {
107                         fprintf(stderr, "Unreferenced section is not a file name: %.*s\n",
108                                 s->section.len, s->section.txt);
109                         errs++;
110                         continue;
111                 }
112                 copy_fname(fname, sizeof(fname), s->section);
113                 if (fname[0] == 0) {
114                         fprintf(stderr, "Missing file name at:%.*s\n",
115                                 s->section.len, s->section.txt);
116                         errs++;
117                         continue;
118                 }
119                 fl = fopen(fname, "w");
120                 if (!fl) {
121                         fprintf(stderr, "Cannot create %s: %s\n",
122                                 fname, strerror(errno));
123                         errs++;
124                         continue;
125                 }
126                 code_print(fl, s->code, argv[1]);
127                 fclose(fl);
128         }
129         exit(!!errs);
130 }
131
132 #line 126 "../mdcode.mdc"
133