X-Git-Url: https://ocean-lang.org/code/?a=blobdiff_plain;ds=sidebyside;f=csrc%2Fmdcode.mdc;h=e1498cea31ab05c22628861fc301c3af7d947bdb;hb=6b0b9db85bba00a1a416b2af14f5c2aa2a5eaf5e;hp=ac34a54c027fb353ea42ffcb4feb4608d144d57c;hpb=27711a085eae65366c023323b15857131c6d8ad8;p=ocean diff --git a/csrc/mdcode.mdc b/csrc/mdcode.mdc index ac34a54..e1498ce 100644 --- a/csrc/mdcode.mdc +++ b/csrc/mdcode.mdc @@ -330,21 +330,31 @@ However when adding a link, we might be able to include it in the last Now we need a lookup table to be able to find sections by name. Something that provides an `n*log(N)` search time is probably justified, but for now I want a minimal stand-alone program so a -linked list managed by insertion-sort will do. As a comparison -function it is easiest to sort based on length before content. So -sections won't be in standard lexical order, but that isn't important. +linked list managed by insertion-sort will do. + +The text compare function will likely be useful for any clients of our +library, so we may as well export it. If we cannot find a section, we simply want to create it. This allows sections and references to be created in any order. Sections with no references or no content will cause a warning eventually. +#### exported functions + + int text_cmp(struct text a, struct text b); + #### internal functions - static int text_cmp(struct text a, struct text b) + int text_cmp(struct text a, struct text b) { - if (a.len != b.len) + int len = a.len; + if (len > b.len) + len = b.len; + int cmp = strncmp(a.txt, b.txt, len); + if (cmp) + return cmp; + else return a.len - b.len; - return strncmp(a.txt, b.txt, a.len); } static struct psection *section_find(struct psection **list, struct text name) @@ -531,7 +541,7 @@ There are two sorts of end markers: the presence of a particular string, or the absence of an indent. We will use a string to represent a presence, and a `NULL` to represent the absence. -While looking at code we don't think about paragraphs are all - just +While looking at code we don't think about paragraphs at all - just look for a line that starts with the right thing. Every line that is still code then needs to be examined to see if it is a section reference. @@ -547,6 +557,11 @@ number of spaces (counting 8 for tabs) after the natural indent of the code (which is a tab or 4 spaces). We use a separate function `count_spaces` for that. +If there are completely blank linkes (no indent) at the end of the found code, +these should be considered to be spacing between the code and the next section, +and so no included in the code. When a marker is used to explicitly mark the +end of the code, we don't need to check for these blank lines. + #### internal functions static int count_space(char *sol, char *p) @@ -623,6 +638,12 @@ for that. struct text txt; txt.txt = start; txt.len = pos - start; + /* strip trailing blank lines */ + while (!marker && txt.len > 2 && + start[txt.len-1] == '\n' && + start[txt.len-2] == '\n') + txt.len -= 1; + code_add_text(sect, txt, start_line, marker == NULL); } @@ -779,8 +800,8 @@ This could go wrong if the first line of a code block marked by _`` ``` ``_ is indented. To overcome this we would need to record some extra state in each `code_node`. For now we won't bother. -The indents we insert will all be spaces. This might not work well -for `Makefiles`. +The indents we insert will mostly be spaces. All-spaces doesn't work +for `Makefiles`, so if the indent is 8 or more, we use a TAB first. ##### internal functions @@ -797,7 +818,10 @@ for `Makefiles`. fprintf(out, "#line %d \"%s\"\n", node->line_no, fname); while (len && *c) { - fprintf(out, "%*s", node->indent, ""); + if (node->indent >= 8) + fprintf(out, "\t%*s", node->indent - 8, ""); + else + fprintf(out, "%*s", node->indent, ""); if (node->needs_strip) { if (*c == '\t' && len > 1) { c++; @@ -890,13 +914,19 @@ we are done. int fd; size_t len; char *file; + struct text section = {NULL, 0}; struct section *table, *s, *prev; errs = 0; - if (argc != 2) { - fprintf(stderr, "Usage: mdcode file.mdc\n"); + if (argc != 2 && argc != 3) { + fprintf(stderr, "Usage: mdcode file.mdc [section]\n"); exit(2); } + if (argc == 3) { + section.txt = argv[2]; + section.len = strlen(argv[2]); + } + fd = open(argv[1], O_RDONLY); if (fd < 0) { fprintf(stderr, "mdcode: cannot open %s: %s\n", @@ -913,16 +943,23 @@ we are done. char fname[1024]; char *spc = strnchr(s->section.txt, s->section.len, ' '); - if (spc > s->section.txt && spc[-1] == ':' && - strncmp(s->section.txt, "File: ", 6) != 0) - /* Ignore this section */ - continue; - if (strncmp(s->section.txt, "File: ", 6) != 0) { + if (spc > s->section.txt && spc[-1] == ':') { + if (strncmp(s->section.txt, "File: ", 6) != 0 && + (section.txt == NULL || + text_cmp(s->section, section) != 0)) + /* Ignore this section */ + continue; + } else { fprintf(stderr, "Code in unreferenced section that is not ignored or a file name: %.*s\n", s->section.len, s->section.txt); errs++; continue; } + if (section.txt) { + if (text_cmp(s->section, section) == 0) + code_node_print(stdout, s->code, argv[1]); + break; + } copy_fname(fname, sizeof(fname), s->section); if (fname[0] == 0) { fprintf(stderr, "Missing file name at:%.*s\n", @@ -942,4 +979,3 @@ we are done. } exit(!!errs); } -