int indent_level;
int indent_sizes[20];
+`indent_sizes[0]` will always be zero - this simplifies some code.
+
#### Newlines
Newlines can optionally be reported. Newlines within a block comment
there are some delayed tokens and if so we need to advance the state
information and return one token.
+###### internal functions
+ static int state_indent(struct token_state *state)
+ {
+ if (state->node == NULL)
+ return state->col;
+ return state->node->indent - state->node->needs_strip + state->col;
+ }
+
###### white space
if (is_newline(ch) || (at_son(state) && ch <= ' ')) {
int newlines = 0;
}
if (at_eon(state)) {
newlines += 1;
- if (state->node->next &&
- state->node->next->indent > state->node->indent)
- state->col = state->node->next->indent;
- else
- state->col = state->node->indent;
} else
unget_char(state);
state->delayed_lines = newlines;
###### delayed tokens
if (state->check_indent || state->delayed_lines) {
- if (state->col < state->indent_sizes[state->indent_level]) {
+ if (state_indent(state) < state->indent_sizes[state->indent_level]) {
if (!state->out_next &&
!(ignored & (1<<TK_newline))) {
state->out_next = 1;
tk.num = TK_out;
return tk;
}
- if (state->col > state->indent_sizes[state->indent_level] &&
+ if (state_indent(state) > state->indent_sizes[state->indent_level] &&
state->indent_level < sizeof(state->indent_sizes)-1) {
state->indent_level += 1;
- state->indent_sizes[state->indent_level] = state->col;
- state->delayed_lines -= 1;
+ state->indent_sizes[state->indent_level] = state_indent(state);
+ if (state->delayed_lines)
+ state->delayed_lines -= 1;
tk.num = TK_in;
return tk;
}
###### internal functions
- static int do_strip(struct token_state *state)
+ static void do_strip(struct token_state *state)
{
int indent = 0;
if (state->node->needs_strip) {
n -= 4;
}
}
- return indent;
}
static wint_t get_char(struct token_state *state)
if (state->node == NULL)
return WEOF;
state->line = state->node->line_no;
- state->col = do_strip(state);
+ do_strip(state);
+ state->col = state->node->needs_strip;
state->strip_offset = state->offset;
}
state->col += 1;
} else if (is_newline(next)) {
state->line += 1;
- state->col = do_strip(state);
+ do_strip(state);
+ state->col = state->node->needs_strip;
} else if (next == '\t') {
state->col = indent_tab(state->col);
}
memset(state, 0, sizeof(*state));
state->node = code;
state->line = code->line_no;
- state->col = do_strip(state);
+ do_strip(state);
+ state->col = state->node->needs_strip;
state->strip_offset = state->offset;
state->conf = conf;
return state;
{ "ignore-block-comment", 0, NULL, 'C'},
{ "ignore-indent", 0, NULL, 'i'},
{ "file", 1, NULL, 'f'},
+ { "section", 1, NULL, 's'},
{ NULL, 0, NULL, 0},
};
- static const char options[] = "W:w:n:NIMSzclCif:";
+ static const char options[] = "W:w:n:NIMSzclCif:s:";
struct section *table, *s, *prev;
int opt;
+ char *section_name = NULL;
+ int section_found = 0;
setlocale(LC_ALL,"");
while ((opt = getopt_long(argc, argv, options, long_options, NULL))
case 'l': conf.ignored |= 1 << TK_newline; break;
case 'i': conf.ignored |= 1 << TK_in; break;
case 'f': filename = optarg; break;
+ case 's': section_name = optarg; break;
default: fprintf(stderr, "scanner: unknown option '%c'.\n",
opt);
exit(1);
for (s = table; s;
(code_free(s->code), prev = s, s = s->next, free(prev))) {
+ if (section_name &&
+ (s->section.len != strlen(section_name) ||
+ strncmp(s->section.txt, section_name, s->section.len) != 0))
+ continue;
+ if (section_name)
+ section_found = 1;
printf("Tokenizing: %.*s\n", s->section.len,
s->section.txt);
state = token_open(s->code, &conf);
}
if (conf.words_marks != known)
free(conf.words_marks);
+ if (section_name && !section_found) {
+ fprintf(stderr, "scanner: section %s not found\n", section_name);
+ errs = 1;
+ }
exit(!!errs);
}
###### File: scanner.mk