Skip to content

Commit 2345884

Browse files
committed
Fix error return from parse(), fix lists, set debug compile flag
1 parent efcedbd commit 2345884

File tree

3 files changed

+101
-54
lines changed

3 files changed

+101
-54
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11

22
mdtex: parser.c
3-
gcc --std=c11 -o mdtex parser.c
3+
gcc --std=c11 -g -o mdtex parser.c

parser.c

Lines changed: 95 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,34 @@
55
#include <sys/mman.h>
66
#include <sys/stat.h>
77

8+
#define MIN(x,y) ((x) < (y) ? (x) : (y))
9+
810
#define PAGE_SIZE 512
911

1012
typedef enum
1113
{
12-
NONE,
13-
HEADER,
14-
15-
BOLD,
16-
UNDERLINE,
17-
ITALIC,
18-
19-
LIST_ITEM,
20-
UNORDERED_LIST_ITEM,
21-
22-
HEADING_1,
23-
HEADING_2,
24-
HEADING_3,
25-
HEADING_4,
26-
HEADING_5,
27-
HEADING_6,
14+
NONE = 0,
15+
HEADER = 1,
16+
17+
BOLD = 2,
18+
UNDERLINE = 3,
19+
ITALIC = 4,
20+
21+
LIST_ITEM_1 = 5,
22+
LIST_ITEM_2 = 6,
23+
LIST_ITEM_3 = 7,
24+
LIST_ITEM_4 = 8,
25+
UNORDERED_LIST_ITEM_1 = 9,
26+
UNORDERED_LIST_ITEM_2 = 10,
27+
UNORDERED_LIST_ITEM_3 = 11,
28+
UNORDERED_LIST_ITEM_4 = 12,
29+
30+
HEADING_1 = 13,
31+
HEADING_2 = 14,
32+
HEADING_3 = 15,
33+
HEADING_4 = 16,
34+
HEADING_5 = 17,
35+
HEADING_6 = 18,
2836

2937
LINK,
3038
CODE,
@@ -41,6 +49,7 @@ typedef struct {
4149
typedef struct
4250
{
4351
char *author;
52+
char *matriculation_number;
4453
char *date;
4554
} DocInfo;
4655

@@ -104,6 +113,9 @@ parse_header (Element *header_element, DocInfo *info)
104113
} else if (strncmp (c, "author", 6) == 0) {
105114
dest = &info->author;
106115
c += 6;
116+
} else if (strncmp (c, "matriculation_number", 20)) {
117+
dest = &info->matriculation_number;
118+
c += 20;
107119
}
108120

109121
if (*c != '"')
@@ -148,21 +160,48 @@ parse_header (Element *header_element, DocInfo *info)
148160
return 1;
149161
}
150162

163+
/**
164+
* Checks if only whitespaces preceed that character by returning
165+
* the number of whitespace characters before \n + 1, so you can check
166+
* for truthiness, but have to subtract 1 if you need the number of
167+
* whitespaces
168+
*
169+
* @param start Start of the char buffer
170+
* @param c Current character
171+
*/
172+
int
173+
is_start_of_line (char *start, char *c)
174+
{
175+
int index = 0;
176+
177+
while ((c - index) != start) {
178+
index++;
179+
180+
if (*(c - index) == '\n')
181+
return index;
182+
183+
if (*(c - index) != ' ' && *(c - index) != '\t')
184+
return 0;
185+
}
186+
187+
return index;
188+
}
189+
151190
int
152-
parse (int fd, int len, const char *error)
191+
parse (int fd, int len, const char **error)
153192
{
154193
char *c, *file;
155194
DocInfo doc_info;
156195
Token current_token;
157196
Element *list;
158197
Element *current_element;
159-
int is_start_of_line = 1, row, col;
198+
int row, col;
160199

161200
#define next_element() \
162201
current_element++; \
163202
current_element->data = c; \
164203
if (!current_element) { \
165-
error = "Max elements exceeded"; \
204+
*error = "Max elements exceeded"; \
166205
return 0; \
167206
}
168207

@@ -176,6 +215,7 @@ parse (int fd, int len, const char *error)
176215
}
177216

178217
#define next_char() advance_char (&c, &col, &row)
218+
#define is_start() is_start_of_line (file, c)
179219

180220
list = (Element *) calloc (PAGE_SIZE, sizeof (Element));
181221
current_element = list;
@@ -188,9 +228,6 @@ parse (int fd, int len, const char *error)
188228
return 0;
189229

190230
do {
191-
if (is_start_of_line)
192-
skip_whitespaces ();
193-
194231
switch (*c) {
195232
case '{':
196233
// only parse if it's the very first element
@@ -204,7 +241,7 @@ parse (int fd, int len, const char *error)
204241

205242
while (next_char () != '}') {
206243
if (*c == '\0') {
207-
error = "Header not terminated";
244+
*error = "Header not terminated";
208245
return 0;
209246
}
210247

@@ -220,7 +257,7 @@ parse (int fd, int len, const char *error)
220257
char *linebreak, *cur, *ret, *prev;
221258
int prev_len;
222259

223-
if (!is_start_of_line)
260+
if (!is_start ())
224261
break;
225262

226263
if (current_element->len < 1)
@@ -255,30 +292,35 @@ parse (int fd, int len, const char *error)
255292
}
256293
break;
257294
case '*':
258-
finish_none_element ();
295+
{
296+
int whitespaces;
259297

260-
if (is_start_of_line) {
261-
current_element->type = LIST_ITEM;
262-
next_char ();
263-
skip_whitespaces ();
264-
next_element ();
265-
} else {
266-
current_element->type = BOLD;
267-
current_element->data = c + 1;
298+
finish_none_element ();
268299

269-
while (next_char () != '*') {
270-
if (!*c) {
271-
error = "Bold not terminated";
272-
return 0;
300+
if ((whitespaces = is_start ())) {
301+
int index = 0;
302+
303+
current_element->type = LIST_ITEM_1 + MIN (whitespaces - 1, 3);
304+
next_char ();
305+
skip_whitespaces ();
306+
next_element ();
307+
} else {
308+
current_element->type = BOLD;
309+
current_element->data = c + 1;
310+
311+
while (next_char () != '*') {
312+
if (!*c) {
313+
*error = "Bold not terminated";
314+
return 0;
315+
}
316+
317+
current_element->len++;
273318
}
274319

275-
current_element->len++;
320+
next_char ();
321+
next_element ();
276322
}
277-
278-
next_char ();
279-
next_element ();
280323
}
281-
282324
break;
283325
case '`':
284326
finish_none_element ();
@@ -297,7 +339,7 @@ parse (int fd, int len, const char *error)
297339

298340
while (next_char () != '`') {
299341
if (!*c) {
300-
error = "Code literal not terminated";
342+
*error = "Code literal not terminated";
301343
return 0;
302344
}
303345

@@ -315,7 +357,7 @@ parse (int fd, int len, const char *error)
315357

316358
while (next_char () != '$') {
317359
if (!*c) {
318-
error = "Math literal not terminated";
360+
*error = "Math literal not terminated";
319361
return 0;
320362
}
321363

@@ -329,7 +371,7 @@ parse (int fd, int len, const char *error)
329371
case '#':
330372
finish_none_element ();
331373

332-
if (is_start_of_line) {
374+
if (is_start ()) {
333375
current_element->type = HEADING_1;
334376
while (next_char () == '#')
335377
(*(int *) (&current_element->type))++;
@@ -353,7 +395,7 @@ parse (int fd, int len, const char *error)
353395

354396
while (next_char () != '_') {
355397
if (!*c) {
356-
error = "Italic not terminated";
398+
*error = "Italic not terminated";
357399
return 0;
358400
}
359401

@@ -367,16 +409,14 @@ parse (int fd, int len, const char *error)
367409
current_element->len++;
368410
break;
369411
}
370-
371-
is_start_of_line = *c == '\n';
372412
} while (next_char ());
373413

374414
finish_none_element ();
375415

376416
// if first element is header parse it and fill our doc info
377417
if (list->type == HEADER) {
378418
if (!parse_header (list, &doc_info)) {
379-
error = "Malformed document header";
419+
*error = "Malformed document header";
380420
return 0;
381421
}
382422
}
@@ -400,8 +440,11 @@ main (int argc, char **argv)
400440
char *path;
401441
int fd;
402442
struct stat st;
403-
char error[512];
404-
443+
// const char error[512];
444+
const char *error;
445+
446+
error = malloc (512);
447+
405448
path = argv[1];
406449

407450
if (!path)
@@ -419,7 +462,7 @@ main (int argc, char **argv)
419462
exit (1);
420463
}
421464

422-
if (!parse (fd, st.st_size, error)) {
465+
if (!parse (fd, st.st_size, &error)) {
423466
fprintf (stderr, "Parsing failed: %s\n", error);
424467
exit (1);
425468
}

test.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ Aufgabe 1
1010

1111
blah
1212

13-
# Subtitle
13+
## Subtitle
1414

1515
Das ist ein Text, mit *fetter* Schrift.
1616

1717
* List 1
18+
* sublist item 1
19+
* sublist item 2
20+
* sublist item 3
1821
* List 2
22+
* sublist item abc
1923

2024
$ a -> b and c or d $
2125

0 commit comments

Comments
 (0)