Using new-style gitignore scripts

This commit is contained in:
Graham Nelson 2022-04-23 14:08:38 +01:00
parent e6a2631e0c
commit 517341513a
39 changed files with 4438 additions and 4245 deletions

View file

@ -21,6 +21,7 @@ see //foundation: A Brief Guide to Foundation//.
@e defined_constant_CLASS
@e enumeration_set_CLASS
@e footnote_CLASS
@e gitignore_state_CLASS
@e hash_table_entry_CLASS
@e hash_table_entry_usage_CLASS
@e language_function_CLASS
@ -28,10 +29,7 @@ see //foundation: A Brief Guide to Foundation//.
@e macro_CLASS
@e macro_tokens_CLASS
@e macro_usage_CLASS
@e makefile_macro_CLASS
@e makefile_macro_parameter_CLASS
@e makefile_variable_CLASS
@e makefile_variable_set_CLASS
@e makefile_specifics_CLASS
@e nonterminal_variable_CLASS
@e para_macro_CLASS
@e paragraph_CLASS
@ -115,6 +113,7 @@ DECLARE_CLASS(colouring_rule)
DECLARE_CLASS(defined_constant)
DECLARE_CLASS(enumeration_set)
DECLARE_CLASS(footnote)
DECLARE_CLASS(gitignore_state)
DECLARE_CLASS(hash_table_entry_usage)
DECLARE_CLASS(hash_table_entry)
DECLARE_CLASS(language_function)
@ -122,10 +121,7 @@ DECLARE_CLASS(language_type)
DECLARE_CLASS(macro_tokens)
DECLARE_CLASS(macro_usage)
DECLARE_CLASS(macro)
DECLARE_CLASS(makefile_macro)
DECLARE_CLASS(makefile_macro_parameter)
DECLARE_CLASS(makefile_variable)
DECLARE_CLASS(makefile_variable_set)
DECLARE_CLASS(makefile_specifics)
DECLARE_CLASS(nonterminal_variable)
DECLARE_CLASS(para_macro)
DECLARE_CLASS(paragraph_tagging)

View file

@ -405,8 +405,16 @@ void Analyser::write_makefile(web *W, filename *F, module_search *I) {
}
void Analyser::write_gitignore(web *W, filename *F) {
filename *prototype = Filenames::in(W->md->path_to_web, I"gitignorescript.txt");
pathname *P = W->md->path_to_web;
text_stream *short_name = Pathnames::directory_name(P);
if ((Str::len(short_name) == 0) ||
(Str::eq(short_name, I".")) || (Str::eq(short_name, I"..")))
short_name = I"web";
TEMPORARY_TEXT(leafname)
WRITE_TO(leafname, "%S.giscript", short_name);
filename *prototype = Filenames::in(P, leafname);
DISCARD_TEXT(leafname)
if (!(TextFiles::exists(prototype)))
prototype = Filenames::in(path_to_inweb_materials, I"gitignorescript.txt");
prototype = Filenames::in(path_to_inweb_materials, I"default.giscript");
Git::write_gitignore(W, prototype, F);
}

View file

@ -2,57 +2,32 @@
Constructing a suitable gitignore file for a simple inweb project.
@ This section offers just one function, which constructs a |.gitignore|
file by following a "prototype".
@ This is an extremely simple use of //foundation: Preprocessor//.
=
typedef struct gitignore_state {
struct web *for_web;
struct text_stream to_gitignore;
int last_line_was_blank; /* used to suppress runs of multiple blank lines */
CLASS_DEFINITION
} gitignore_state;
void Git::write_gitignore(web *W, filename *prototype, filename *F) {
gitignore_state MS;
MS.for_web = W;
MS.last_line_was_blank = TRUE;
text_stream *OUT = &(MS.to_gitignore);
if (STREAM_OPEN_TO_FILE(OUT, F, ISO_ENC) == FALSE)
Errors::fatal_with_file("unable to write tangled file", F);
WRITE("# This gitignore was automatically written by inweb -gitignore\n");
WRITE("# and is not intended for human editing\n\n");
TextFiles::read(prototype, FALSE, "can't open prototype file",
TRUE, Git::copy_gitignore_line, NULL, &MS);
STREAM_CLOSE(OUT);
WRITE_TO(STDOUT, "Wrote gitignore file '%f' from script '%f'\n", F, prototype);
linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
Preprocessor::reserve_macro(L, I"basics", NULL, Git::basics_expander);
gitignore_state *specifics = CREATE(gitignore_state);
specifics->for_web = W;
text_stream *header = Str::new();
WRITE_TO(header, "# This gitignore was automatically written by inweb -gitignore\n");
WRITE_TO(header, "# and is not intended for human editing\n\n");
WRITE_TO(STDOUT, "(Read script from %f)\n", prototype);
Preprocessor::preprocess(prototype, F, header, L, STORE_POINTER_gitignore_state(specifics));
}
@ =
void Git::copy_gitignore_line(text_stream *line, text_file_position *tfp, void *X) {
gitignore_state *MS = (gitignore_state *) X;
text_stream *OUT = &(MS->to_gitignore);
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, line, L" *#%c*")) { Regexp::dispose_of(&mr); return; }
if (Regexp::match(&mr, line, L" *{basics} *")) @<Expand basics@>;
Regexp::dispose_of(&mr);
@<And otherwise copy the line straight through@>;
void Git::basics_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
filename *prototype = Filenames::in(path_to_inweb_materials, I"default.giscript");
TextFiles::read(prototype, FALSE, "can't open basic .gitignore file",
TRUE, Preprocessor::scan_line, NULL, PPS);
WRITE_TO(STDOUT, "(Read basics.giscript from inweb/");
Pathnames::to_text_relative(STDOUT, path_to_inweb, path_to_inweb_materials);
WRITE_TO(STDOUT, ")\n");
}
@<Expand basics@> =
filename *prototype =
Filenames::in(path_to_inweb_materials, I"gitignorescript.txt");
TextFiles::read(prototype, FALSE, "can't open make settings file",
TRUE, Git::copy_gitignore_line, NULL, MS);
Regexp::dispose_of(&mr);
return;
@<And otherwise copy the line straight through@> =
if (Str::len(line) == 0) {
if (MS->last_line_was_blank == FALSE) WRITE("\n");
MS->last_line_was_blank = TRUE;
} else {
MS->last_line_was_blank = FALSE;
WRITE("%S\n", line);
}

View file

@ -12,222 +12,196 @@ makefile but with the possibility of using some higher-level features, and we
translate that it into an actual makefile (which is usually longer and less
easy to read).
@h State.
@d MAX_MAKEFILE_REPEAT_DEPTH 8
@
=
typedef struct makefile_repeat {
int repeat_scope; /* during a repeat, either |MAKEFILE_TOOL_MOM| or |MAKEFILE_MODULE_MOM| */
struct text_stream *repeat_tag;
struct text_stream *repeat_with;
struct text_stream *repeat_in;
int repeat_is_block;
struct text_stream *repeat_saved_dest;
} makefile_repeat;
typedef struct makefile_state {
typedef struct makefile_specifics {
struct web *for_web;
struct text_stream *dest;
struct makefile_macro *defining; /* a "define" body being scanned */
int repeat_sp;
int shadow_sp;
struct makefile_repeat repeat_data[MAX_MAKEFILE_REPEAT_DEPTH];
int suppress_newline; /* at the end of this line */
int last_line_was_blank; /* used to suppress runs of multiple blank lines */
struct dictionary *tools_dictionary;
struct dictionary *webs_dictionary;
struct dictionary *modules_dictionary;
struct module_search *search_path;
struct makefile_variable_set *global_variables;
struct makefile_variable_set *stack_frame;
struct linked_list *known_macros; /* of |makefile_macro| */
} makefile_state;
CLASS_DEFINITION
} makefile_specifics;
void Makefiles::write(web *W, filename *prototype, filename *F, module_search *I) {
struct text_stream makefile;
if (STREAM_OPEN_TO_FILE(&makefile, F, ISO_ENC) == FALSE)
Errors::fatal_with_file("unable to write tangled file", F);
linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
Preprocessor::reserve_macro(L, I"platform-settings", NULL, Makefiles::platform_settings_expander);
Preprocessor::reserve_macro(L, I"identity-settings", NULL, Makefiles::identity_settings_expander);
Preprocessor::reserve_macro(L, I"component",
I"symbol: SYMBOL webname: WEBNAME path: PATH set: SET type: TYPE",
Makefiles::component_expander);
Preprocessor::reserve_macro(L, I"dependent-files",
I"?tool: TOOL ?module: MODULES ?tool-and-modules: BOTH",
Makefiles::dependent_files_expander);
Preprocessor::reserve_repeat_macro(L, I"components", I"type: TYPE ?set: SET",
Makefiles::components_expander);
makefile_specifics *specifics = CREATE(makefile_specifics);
specifics->for_web = W;
specifics->tools_dictionary = Dictionaries::new(16, FALSE);
specifics->webs_dictionary = Dictionaries::new(16, FALSE);
specifics->modules_dictionary = Dictionaries::new(16, FALSE);
specifics->search_path = I;
text_stream *header = Str::new();
WRITE_TO(header, "# This makefile was automatically written by inweb -makefile\n");
WRITE_TO(header, "# and is not intended for human editing\n\n");
WRITE_TO(STDOUT, "(Read script from %f)\n", prototype);
text_stream *OUT = &makefile;
makefile_state MS;
MS.dest = OUT;
MS.for_web = W;
MS.suppress_newline = FALSE;
MS.last_line_was_blank = TRUE;
MS.defining = NULL;
MS.repeat_sp = 0;
MS.shadow_sp = 0;
MS.tools_dictionary = Dictionaries::new(16, FALSE);
MS.webs_dictionary = Dictionaries::new(16, FALSE);
MS.modules_dictionary = Dictionaries::new(16, FALSE);
MS.search_path = I;
MS.global_variables = Makefiles::new_variable_set(NULL);
MS.stack_frame = MS.global_variables;
MS.known_macros = Makefiles::list_of_reserved_macros();
WRITE("# This makefile was automatically written by inweb -makefile\n");
WRITE("# and is not intended for human editing\n\n");
TextFiles::read(prototype, FALSE, "can't open prototype file",
TRUE, Makefiles::scan_makefile_line, NULL, &MS);
STREAM_CLOSE(OUT);
Preprocessor::preprocess(prototype, F, header, L, STORE_POINTER_makefile_specifics(specifics));
}
@h Scanner.
=
void Makefiles::scan_makefile_line(text_stream *line, text_file_position *tfp, void *X) {
makefile_state *MS = (makefile_state *) X;
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, line, L" *#%c*")) { Regexp::dispose_of(&mr); return; } // Skip comment lines
if (Regexp::match(&mr, line, L" *{define: *(%C+) (%c*)} *")) @<Begin a definition@>;
if (Regexp::match(&mr, line, L" *{end-define} *")) @<End a definition@>;
if (MS->defining) @<Continue a definition@>;
Regexp::dispose_of(&mr);
Makefiles::expand(line, tfp, MS);
if (MS->suppress_newline == FALSE) {
text_stream *OUT = MS->dest;
if (Str::len(line) == 0) {
if (MS->last_line_was_blank == FALSE) WRITE("\n");
MS->last_line_was_blank = TRUE;
} else {
MS->last_line_was_blank = FALSE;
WRITE("\n");
}
void Makefiles::identity_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics);
text_stream *OUT = PPS->dest;
WRITE("INWEB = "); Makefiles::pathname_slashed(OUT, path_to_inweb); WRITE("/Tangled/inweb\n");
pathname *path_to_intest = Pathnames::down(Pathnames::up(path_to_inweb), I"intest");
WRITE("INTEST = "); Makefiles::pathname_slashed(OUT, path_to_intest); WRITE("/Tangled/intest\n");
if (specifics->for_web) {
WRITE("MYNAME = %S\n", Pathnames::directory_name(specifics->for_web->md->path_to_web));
WRITE("ME = "); Makefiles::pathname_slashed(OUT, specifics->for_web->md->path_to_web);
WRITE("\n");
PPS->last_line_was_blank = FALSE;
}
MS->suppress_newline = FALSE;
}
@<Begin a definition@> =
if (MS->defining)
Errors::in_text_file("nested definitions are not allowed", tfp);
text_stream *name = mr.exp[0];
text_stream *parameter_specification = mr.exp[1];
MS->defining = Makefiles::new_macro(MS->known_macros, name, parameter_specification, tfp);
Regexp::dispose_of(&mr);
return;
void Makefiles::component_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics);
text_stream *OUT = PPS->dest;
@<Continue a definition@> =
Makefiles::add_line_to_macro(MS->defining, line, tfp);
Regexp::dispose_of(&mr);
return;
@<End a definition@> =
if (MS->defining == NULL)
Errors::in_text_file("{end-define} without {define: ...}", tfp);
MS->defining = NULL;
Regexp::dispose_of(&mr);
return;
@ =
void Makefiles::expand(text_stream *text, text_file_position *tfp, makefile_state *MS) {
TEMPORARY_TEXT(before_matter)
TEMPORARY_TEXT(braced_matter)
TEMPORARY_TEXT(after_matter)
int bl = 0, after_times = FALSE;
for (int i = 0; i < Str::len(text); i++) {
wchar_t c = Str::get_at(text, i);
if (after_times) PUT_TO(after_matter, c);
else if (c == '{') {
bl++;
if (bl > 1) PUT_TO(braced_matter, c);
} else if (c == '}') {
bl--;
if (bl == 0) after_times = TRUE;
else PUT_TO(braced_matter, c);
} else {
if (bl < 0) Errors::in_text_file("too many '}'s", tfp);
if (bl == 0) PUT_TO(before_matter, c);
else PUT_TO(braced_matter, c);
}
}
if (bl > 0) Errors::in_text_file("too many '{'s", tfp);
if (after_times) {
@<Expand a macro@>;
text_stream *symbol = parameter_values[0];
text_stream *webname = parameter_values[1];
text_stream *path = parameter_values[2];
text_stream *set = parameter_values[3];
text_stream *category = parameter_values[4];
int marker = -1;
dictionary *D = NULL;
if (Str::eq(category, I"tool")) {
marker = MAKEFILE_TOOL_MOM;
D = specifics->tools_dictionary;
} else if (Str::eq(category, I"web")) {
marker = MAKEFILE_WEB_MOM;
D = specifics->webs_dictionary;
} else if (Str::eq(category, I"module")) {
marker = MAKEFILE_MODULE_MOM;
D = specifics->modules_dictionary;
} else {
WRITE_TO(MS->dest, "%S", text);
Errors::in_text_file("category should be 'tool', 'module' or 'web'", tfp);
}
if (D) {
WRITE("%SLEAF = %S\n", symbol, webname);
WRITE("%SWEB = %S\n", symbol, path);
WRITE("%SMAKER = $(%SWEB)/%S.mk\n", symbol, symbol, webname);
WRITE("%SX = $(%SWEB)/Tangled/%S\n", symbol, symbol, webname);
PPS->last_line_was_blank = FALSE;
web_md *Wm = Reader::load_web_md(Pathnames::from_text(path), NULL, specifics->search_path, TRUE);
Wm->as_module->module_name = Str::duplicate(symbol);
Wm->as_module->module_tag = Str::duplicate(set);
Wm->as_module->origin_marker = marker;
Dictionaries::create(D, symbol);
Dictionaries::write_value(D, symbol, Wm);
}
DISCARD_TEXT(before_matter)
DISCARD_TEXT(braced_matter)
DISCARD_TEXT(after_matter)
}
@<Expand a macro@> =
text_stream *identifier = braced_matter;
text_stream *parameter_settings = NULL;
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, identifier, L"(%C+) (%c*)")) {
identifier = mr.exp[0];
parameter_settings = mr.exp[1];
}
if (Str::eq(identifier, I"repeat")) {
if (Str::is_whitespace(after_matter)) identifier = I"repeat-block";
else identifier = I"repeat-span";
}
if (Str::eq(identifier, I"end-repeat")) {
if ((MS->repeat_sp > 0) && (MS->repeat_data[MS->repeat_sp-1].repeat_is_block))
identifier = I"end-block";
else
identifier = I"end-span";
}
void Makefiles::dependent_files_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics);
text_stream *OUT = PPS->dest;
if (Makefiles::acceptable_variable_name(identifier)) {
Makefiles::expand(before_matter, tfp, MS);
if (MS->repeat_sp > 0) {
WRITE_TO(MS->dest, "{%S}", identifier);
text_stream *tool = parameter_values[0];
text_stream *modules = parameter_values[1];
text_stream *both = parameter_values[2];
if (Str::len(tool) > 0) {
if (Dictionaries::find(specifics->tools_dictionary, tool)) {
web_md *Wm = Dictionaries::read_value(specifics->tools_dictionary, tool);
Makefiles::pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename);
} else if (Dictionaries::find(specifics->webs_dictionary, tool)) {
web_md *Wm = Dictionaries::read_value(specifics->webs_dictionary, tool);
Makefiles::pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename);
} else {
makefile_variable *var = Makefiles::find_variable_in(identifier, MS->stack_frame);
if (var) {
WRITE_TO(MS->dest, "%S", var->value);
} else {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown variable '%S'", identifier);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
}
Makefiles::expand(after_matter, tfp, MS);
} else {
makefile_macro *mm = Makefiles::find_macro(MS->known_macros, identifier);
if (mm == NULL) {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown macro '%S'", identifier);
WRITE_TO(erm, "unknown tool '%S' to find dependencies for", tool);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
} else if (Str::len(modules) > 0) {
if (Dictionaries::find(specifics->modules_dictionary, modules)) {
web_md *Wm = Dictionaries::read_value(specifics->modules_dictionary, modules);
Makefiles::pattern(OUT, Wm->sections_md, Wm->contents_filename);
} else {
if (mm->suppress_whitespace_when_expanding) {
while (Characters::is_whitespace(Str::get_last_char(before_matter)))
Str::delete_last_character(before_matter);
while (Characters::is_whitespace(Str::get_first_char(after_matter)))
Str::delete_first_character(after_matter);
}
Makefiles::expand(before_matter, tfp, MS);
int divert_if_repeating = TRUE;
if ((mm) &&
((mm->reserved_macro_meaning == REPEAT_BLOCK_RMM) ||
(mm->reserved_macro_meaning == REPEAT_SPAN_RMM))) {
MS->shadow_sp++;
}
if ((mm) &&
((mm->reserved_macro_meaning == END_BLOCK_RMM) ||
(mm->reserved_macro_meaning == END_SPAN_RMM))) {
MS->shadow_sp--;
if (MS->shadow_sp == 0) divert_if_repeating = FALSE;
}
if ((divert_if_repeating) && (MS->repeat_sp > 0)) {
WRITE_TO(MS->dest, "{%S}", braced_matter);
} else {
Makefiles::expand_macro(MS, mm, parameter_settings, tfp);
if (mm->suppress_newline_after_expanding) MS->suppress_newline = TRUE;
}
Makefiles::expand(after_matter, tfp, MS);
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown module '%S' to find dependencies for", modules);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
} else if (Str::len(both) > 0) {
if (Dictionaries::find(specifics->tools_dictionary, both)) {
web_md *Wm = Dictionaries::read_value(specifics->tools_dictionary, both);
Makefiles::pattern(OUT, Wm->sections_md, Wm->contents_filename);
} else if (Dictionaries::find(specifics->webs_dictionary, both)) {
web_md *Wm = Dictionaries::read_value(specifics->webs_dictionary, both);
Makefiles::pattern(OUT, Wm->sections_md, Wm->contents_filename);
} else {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown tool '%S' to find dependencies for", both);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
} else {
Makefiles::pattern(OUT, specifics->for_web->md->sections_md, specifics->for_web->md->contents_filename);
}
WRITE("\n");
PPS->last_line_was_blank = FALSE;
}
void Makefiles::platform_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
filename *prototype = Filenames::in(path_to_inweb, I"platform-settings.mk");
text_stream *INWEBPLATFORM = Str::new();
TextFiles::read(prototype, FALSE, "can't open platform settings file",
TRUE, Makefiles::seek_INWEBPLATFORM, NULL, INWEBPLATFORM);
if (Str::len(INWEBPLATFORM) == 0) {
Errors::in_text_file(
"found platform settings file, but it does not set INWEBPLATFORM", tfp);
} else {
pathname *P = Pathnames::down(path_to_inweb, I"Materials");
P = Pathnames::down(P, I"platforms");
WRITE_TO(INWEBPLATFORM, ".mkscript");
filename *F = Filenames::in(P, INWEBPLATFORM);
TextFiles::read(F, FALSE, "can't open platform definitions file",
TRUE, Preprocessor::scan_line, NULL, PPS);
WRITE_TO(STDOUT, "(Read definitions file '%S' from ", INWEBPLATFORM);
Pathnames::to_text_relative(STDOUT, path_to_inweb, P);
WRITE_TO(STDOUT, ")\n");
}
}
void Makefiles::components_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
rep->loop_var_name = I"SYMBOL";
text_stream *category = parameter_values[0];
text_stream *set = parameter_values[1];
if (Str::len(set) == 0) set = I"all";
if (Str::eq(category, I"tool")) {
int marker = MAKEFILE_TOOL_MOM;
@<Make the web iterations@>;
} else if (Str::eq(category, I"web")) {
int marker = MAKEFILE_WEB_MOM;
@<Make the web iterations@>;
} else if (Str::eq(category, I"module")) {
int marker = MAKEFILE_MODULE_MOM;
@<Make the web iterations@>;
} else {
Errors::in_text_file("category should be 'tool', 'module' or 'web'", tfp);
}
}
@<Make the web iterations@> =
module *M;
LOOP_OVER(M, module) {
if ((M->origin_marker == marker) &&
((Str::eq(set, I"all")) || (Str::eq(set, M->module_tag)))) {
text_stream *value = M->module_name;
ADD_TO_LINKED_LIST(Str::duplicate(value), text_stream, rep->iterations);
}
}
Regexp::dispose_of(&mr);
@ =
void Makefiles::pathname_slashed(OUTPUT_STREAM, pathname *P) {
@ -277,60 +251,6 @@ void Makefiles::pattern(OUTPUT_STREAM, linked_list *L, filename *F) {
}
DISCARD_TEXT(tester)
@ And finally, the following handles repetitions both of blocks and of spans:
=
void Makefiles::repeat(text_stream *matter,
int as_lines, text_file_position *tfp, makefile_repeat *rep, makefile_state *MS) {
int over = rep->repeat_scope;
text_stream *tag = rep->repeat_tag;
MS->stack_frame = Makefiles::new_variable_set(MS->stack_frame);
text_stream *loop_var_name = I"NAME";
if (Str::len(rep->repeat_with) > 0) loop_var_name = rep->repeat_with;
makefile_variable *loop_var = Makefiles::ensure_variable(loop_var_name, MS->stack_frame);
if (Str::len(rep->repeat_in) > 0) {
match_results mr = Regexp::create_mr();
while (Regexp::match(&mr, rep->repeat_in, L"(%c*?),(%c*)")) {
text_stream *value = mr.exp[0];
Str::trim_white_space(value);
@<Iterate with this value@>;
Str::clear(rep->repeat_in);
Str::copy(rep->repeat_in, mr.exp[1]);
}
Regexp::dispose_of(&mr);
text_stream *value = rep->repeat_in;
Str::trim_white_space(value);
@<Iterate with this value@>;
} else {
module *M;
LOOP_OVER(M, module) {
if ((M->origin_marker == over) &&
((Str::eq(tag, I"all")) || (Str::eq(tag, M->module_tag)))) {
text_stream *value = M->module_name;
@<Iterate with this value@>;
}
}
}
MS->stack_frame = MS->stack_frame->outer;
}
@<Iterate with this value@> =
loop_var->value = value;
if (as_lines) {
TEMPORARY_TEXT(line)
LOOP_THROUGH_TEXT(pos, matter) {
if (Str::get(pos) == '\n') {
Makefiles::scan_makefile_line(line, tfp, (void *) MS);
Str::clear(line);
} else {
PUT_TO(line, Str::get(pos));
}
}
DISCARD_TEXT(line)
} else {
Makefiles::expand(matter, tfp, MS);
}
@ This is used to scan the platform settings file for a definition line in the
shape INWEBPLATFORM = PLATFORM, in order to find out what PLATFORM the make file
will be used on.
@ -343,501 +263,3 @@ void Makefiles::seek_INWEBPLATFORM(text_stream *line, text_file_position *tfp, v
Regexp::dispose_of(&mr);
}
@h Variables.
=
typedef struct makefile_variable {
struct text_stream *name;
struct text_stream *value;
CLASS_DEFINITION
} makefile_variable;
typedef struct makefile_variable_set {
struct linked_list *variables; /* of |makefile_variable| */
struct makefile_variable_set *outer;
CLASS_DEFINITION
} makefile_variable_set;
makefile_variable_set *Makefiles::new_variable_set(makefile_variable_set *outer) {
makefile_variable_set *set = CREATE(makefile_variable_set);
set->variables = NEW_LINKED_LIST(makefile_variable);
set->outer = outer;
return set;
}
makefile_variable *Makefiles::find_variable_in_one(text_stream *name, makefile_variable_set *set) {
if (set == NULL) return NULL;
makefile_variable *var;
LOOP_OVER_LINKED_LIST(var, makefile_variable, set->variables)
if (Str::eq(name, var->name))
return var;
return NULL;
}
makefile_variable *Makefiles::find_variable_in(text_stream *name, makefile_variable_set *set) {
while (set) {
makefile_variable *var = Makefiles::find_variable_in_one(name, set);
if (var) return var;
set = set->outer;
}
return NULL;
}
makefile_variable *Makefiles::ensure_variable(text_stream *name, makefile_variable_set *in_set) {
if (in_set == NULL) internal_error("variable without set");
makefile_variable *var = Makefiles::find_variable_in_one(name, in_set);
if (var == NULL) {
var = CREATE(makefile_variable);
var->name = Str::duplicate(name);
var->value = I"";
ADD_TO_LINKED_LIST(var, makefile_variable, in_set->variables);
}
return var;
}
int Makefiles::acceptable_variable_name(text_stream *name) {
LOOP_THROUGH_TEXT(pos, name) {
wchar_t c = Str::get(pos);
if ((c >= '0') && (c <= '9')) continue;
if ((c >= 'A') && (c <= 'Z')) continue;
if (c == '_') continue;
return FALSE;
}
return TRUE;
}
@h Macros.
A typical macro definition looks like this:
= (text)
{define: link to: TO from: FROM ?options: OPTS}
clang $(CCOPTS) -g -o {TO} {FROM} {OPTS}
{end-define}
=
And here is a usage of it:
= (text)
{link from: frog.o to: frog.c}
=
This doesn't specify "options: ...", but doesn't have to, because that's optional --
note the question mark in the macro declaration. But it does specify "from: ..."
and "to: ...", which are compulsory. Parameters are always named, as this example
suggests, and can be given in any order so long as all the non-optional ones are
present.
This usage results in the following line in the final makefile:
= (text)
clang $(CCOPTS) -g -o frog.c frog.o
=
Note the difference between |$(CCOPTS)|, which is a make variable, and the braced
tokens |{TO}|, |{FROM}| and |{OPTS}|, which are makescript variables. In makescripts,
the only material treated as special is material in braces |{...}|.
@ The above definition has three parameters, one optional, but only one line. There
are (for now, anyway) hard but harmlessly large limits on the number of these:
@d MAX_MAKEFILE_MACRO_PARAMETERS 8
@d MAX_MAKEFILE_MACRO_LINES 128
=
typedef struct makefile_macro {
struct text_stream *identifier;
struct makefile_macro_parameter *parameters[MAX_MAKEFILE_MACRO_PARAMETERS];
int no_parameters;
struct text_stream *lines[MAX_MAKEFILE_MACRO_LINES];
int no_lines;
int reserved_macro_meaning;
int suppress_newline_after_expanding;
int suppress_whitespace_when_expanding;
CLASS_DEFINITION
} makefile_macro;
typedef struct makefile_macro_parameter {
struct text_stream *name;
struct text_stream *definition_token;
int optional;
CLASS_DEFINITION
} makefile_macro_parameter;
@ New macro declaration lines are processed here, and added to a list |L| of
valid macros:
=
makefile_macro *Makefiles::new_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification, text_file_position *tfp) {
if (Makefiles::find_macro(L, name))
Errors::in_text_file("a macro with this name already exists", tfp);
makefile_macro *new_macro = CREATE(makefile_macro);
new_macro->identifier = Str::duplicate(name);
new_macro->no_parameters = 0;
new_macro->no_lines = 0;
new_macro->reserved_macro_meaning = UNRESERVED_RMM;
new_macro->suppress_newline_after_expanding = TRUE;
new_macro->suppress_whitespace_when_expanding = TRUE;
match_results mr2 = Regexp::create_mr();
while (Regexp::match(&mr2, parameter_specification, L" *(%C+): *(%C+) *(%c*)")) {
text_stream *par_name = mr2.exp[0];
text_stream *token_name = mr2.exp[1];
Str::clear(parameter_specification);
Str::copy(parameter_specification, mr2.exp[2]);
if (new_macro->no_parameters >= MAX_MAKEFILE_MACRO_PARAMETERS) {
Errors::in_text_file("too many parameters in this definition", tfp);
} else {
@<Add parameter to macro@>;
}
}
Regexp::dispose_of(&mr2);
if (Str::is_whitespace(parameter_specification) == FALSE)
Errors::in_text_file("parameter list for this definition is malformed", tfp);
ADD_TO_LINKED_LIST(new_macro, makefile_macro, L);
return new_macro;
}
@<Add parameter to macro@> =
makefile_macro_parameter *new_parameter = CREATE(makefile_macro_parameter);
new_parameter->name = Str::duplicate(par_name);
new_parameter->definition_token = Str::duplicate(token_name);
new_parameter->optional = FALSE;
if (Str::get_first_char(new_parameter->name) == '?') {
new_parameter->optional = TRUE;
Str::delete_first_character(new_parameter->name);
}
new_macro->parameters[new_macro->no_parameters++] = new_parameter;
@ We can then add lines to the definition:
=
void Makefiles::add_line_to_macro(makefile_macro *mm, text_stream *line, text_file_position *tfp) {
if (mm->no_lines >= MAX_MAKEFILE_MACRO_LINES) {
Errors::in_text_file("too many lines in this definition", tfp);
} else {
mm->lines[mm->no_lines++] = Str::duplicate(line);
}
}
@ A few macros are "reserved", that is, have built-in meanings and are not
declared by any makescript but by us. (These have no lines, only parameters.)
@e UNRESERVED_RMM from 0
@e PLATFORM_SETTINGS_RMM
@e IDENTITY_SETTINGS_RMM
@e COMPONENT_RMM
@e DEPENDENT_FILES_RMM
@e REPEAT_BLOCK_RMM
@e END_BLOCK_RMM
@e REPEAT_SPAN_RMM
@e END_SPAN_RMM
@e SET_RMM
=
linked_list *Makefiles::list_of_reserved_macros(void) {
linked_list *L = NEW_LINKED_LIST(makefile_macro);
Makefiles::reserve_macro(L, I"platform-settings", NULL, PLATFORM_SETTINGS_RMM);
Makefiles::reserve_macro(L, I"identity-settings", NULL, IDENTITY_SETTINGS_RMM);
Makefiles::reserve_macro(L, I"component",
I"symbol: SYMBOL webname: WEBNAME path: PATH set: SET category: CATEGORY",
COMPONENT_RMM);
Makefiles::reserve_macro(L, I"dependent-files",
I"?tool: TOOL ?module: MODULES ?tool-and-modules: BOTH",
DEPENDENT_FILES_RMM);
Makefiles::reserve_macro(L, I"repeat-block",
I"?over: CATEGORY ?set: SET ?with: WITH ?in: IN", REPEAT_BLOCK_RMM);
Makefiles::reserve_macro(L, I"end-block", NULL, END_BLOCK_RMM);
Makefiles::reserve_span_macro(L, I"repeat-span",
I"?over: CATEGORY ?set: SET ?with: WITH ?in: IN", REPEAT_SPAN_RMM);
Makefiles::reserve_span_macro(L, I"end-span", NULL, END_SPAN_RMM);
Makefiles::reserve_span_macro(L, I"set",
I"name: NAME value: VALUE", SET_RMM);
return L;
}
void Makefiles::reserve_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification, int rmm) {
makefile_macro *reserved = Makefiles::new_macro(L, name,
Str::duplicate(parameter_specification), NULL);
reserved->reserved_macro_meaning = rmm;
}
void Makefiles::reserve_span_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification, int rmm) {
makefile_macro *reserved = Makefiles::new_macro(L, name,
Str::duplicate(parameter_specification), NULL);
reserved->reserved_macro_meaning = rmm;
reserved->suppress_newline_after_expanding = FALSE;
reserved->suppress_whitespace_when_expanding = FALSE;
}
@ Finding a macro in a list. (We could use a dictionary for efficiency, but really,
it's unlikely there are ever more than a few macros.)
=
makefile_macro *Makefiles::find_macro(linked_list *L, text_stream *name) {
makefile_macro *mm;
LOOP_OVER_LINKED_LIST(mm, makefile_macro, L)
if (Str::eq(mm->identifier, name))
return mm;
return NULL;
}
@ Expanding a macro is the main event, then:
=
void Makefiles::expand_macro(makefile_state *MS, makefile_macro *mm,
text_stream *parameter_settings, text_file_position *tfp) {
text_stream *OUT = MS->dest;
text_stream *parameter_values[MAX_MAKEFILE_MACRO_PARAMETERS];
for (int i=0; i<MAX_MAKEFILE_MACRO_PARAMETERS; i++) parameter_values[i] = NULL;
match_results mr2 = Regexp::create_mr();
while (Regexp::match(&mr2, parameter_settings, L" *(%C+): *(%c*)")) {
text_stream *setting = mr2.exp[0];
text_stream *value = mr2.exp[1];
text_stream *remainder = NULL;
match_results mr3 = Regexp::create_mr();
if (Regexp::match(&mr3, value, L"(%c+?) *(%C+: *%c*)")) {
value = mr3.exp[0];
remainder = mr3.exp[1];
}
int found = FALSE;
for (int i=0; i<mm->no_parameters; i++)
if (Str::eq(setting, mm->parameters[i]->name)) {
found = TRUE;
parameter_values[i] = Str::new();
text_stream *saved = MS->dest;
MS->dest = parameter_values[i];
Makefiles::expand(value, tfp, MS);
MS->dest = saved;
}
if (found == FALSE) {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown parameter '%S'", setting);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
Str::clear(parameter_settings);
Str::copy(parameter_settings, remainder);
Regexp::dispose_of(&mr3);
}
Regexp::dispose_of(&mr2);
if (Str::is_whitespace(parameter_settings) == FALSE)
Errors::in_text_file("parameter list is malformed", tfp);
for (int i=0; i<mm->no_parameters; i++)
if (parameter_values[i] == NULL)
if (mm->parameters[i]->optional == FALSE) {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "compulsory parameter '%S' not given", mm->parameters[i]->name);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
switch (mm->reserved_macro_meaning) {
case UNRESERVED_RMM: @<Expand a textual definition@>; break;
case PLATFORM_SETTINGS_RMM: @<Expand platform settings@>; break;
case IDENTITY_SETTINGS_RMM: @<Expand identity settings@>; break;
case COMPONENT_RMM: @<Expand component declaration@>; break;
case DEPENDENT_FILES_RMM: @<Expand dependent-files@>; break;
case REPEAT_BLOCK_RMM: @<Expand repeat-block@>; break;
case END_BLOCK_RMM: @<Expand end-block@>; break;
case REPEAT_SPAN_RMM: @<Expand repeat-block@>; break;
case END_SPAN_RMM: @<Expand end-block@>; break;
case SET_RMM: @<Expand set@>; break;
default: internal_error("unimplemented reserved macro");
}
}
@<Expand a textual definition@> =
MS->stack_frame = Makefiles::new_variable_set(MS->stack_frame);
for (int i=0; i<mm->no_parameters; i++) {
makefile_variable *var =
Makefiles::ensure_variable(mm->parameters[i]->definition_token, MS->stack_frame);
var->value = parameter_values[i];
}
for (int i=0; i<mm->no_lines; i++)
Makefiles::scan_makefile_line(mm->lines[i], tfp, (void *) MS);
MS->stack_frame = MS->stack_frame->outer;
@<Expand platform settings@> =
filename *prototype = Filenames::in(path_to_inweb, I"platform-settings.mk");
text_stream *INWEBPLATFORM = Str::new();
TextFiles::read(prototype, FALSE, "can't open platform settings file",
TRUE, Makefiles::seek_INWEBPLATFORM, NULL, INWEBPLATFORM);
if (Str::len(INWEBPLATFORM) == 0) {
Errors::in_text_file(
"found platform settings file, but it does not set INWEBPLATFORM", tfp);
} else {
pathname *P = Pathnames::down(path_to_inweb, I"Materials");
P = Pathnames::down(P, I"platforms");
WRITE_TO(INWEBPLATFORM, ".mkscript");
filename *F = Filenames::in(P, INWEBPLATFORM);
TextFiles::read(F, FALSE, "can't open platform definitions file",
TRUE, Makefiles::scan_makefile_line, NULL, MS);
WRITE_TO(STDOUT, "(Read definitions file '%S' from ", INWEBPLATFORM);
Pathnames::to_text_relative(STDOUT, path_to_inweb, P);
WRITE_TO(STDOUT, ")\n");
}
@<Expand identity settings@> =
WRITE("INWEB = "); Makefiles::pathname_slashed(OUT, path_to_inweb); WRITE("/Tangled/inweb\n");
pathname *path_to_intest = Pathnames::down(Pathnames::up(path_to_inweb), I"intest");
WRITE("INTEST = "); Makefiles::pathname_slashed(OUT, path_to_intest); WRITE("/Tangled/intest\n");
if (MS->for_web) {
WRITE("MYNAME = %S\n", Pathnames::directory_name(MS->for_web->md->path_to_web));
WRITE("ME = "); Makefiles::pathname_slashed(OUT, MS->for_web->md->path_to_web);
WRITE("\n");
MS->last_line_was_blank = FALSE;
}
@<Expand component declaration@> =
text_stream *symbol = parameter_values[0];
text_stream *webname = parameter_values[1];
text_stream *path = parameter_values[2];
text_stream *set = parameter_values[3];
text_stream *category = parameter_values[4];
int marker = -1;
dictionary *D = NULL;
if (Str::eq(category, I"tool")) {
marker = MAKEFILE_TOOL_MOM;
D = MS->tools_dictionary;
} else if (Str::eq(category, I"web")) {
marker = MAKEFILE_WEB_MOM;
D = MS->webs_dictionary;
} else if (Str::eq(category, I"module")) {
marker = MAKEFILE_MODULE_MOM;
D = MS->modules_dictionary;
} else {
Errors::in_text_file("category should be 'tool', 'module' or 'web'", tfp);
}
if (D) {
WRITE("%SLEAF = %S\n", symbol, webname);
WRITE("%SWEB = %S\n", symbol, path);
WRITE("%SMAKER = $(%SWEB)/%S.mk\n", symbol, symbol, webname);
WRITE("%SX = $(%SWEB)/Tangled/%S\n", symbol, symbol, webname);
MS->last_line_was_blank = FALSE;
web_md *Wm = Reader::load_web_md(Pathnames::from_text(path), NULL, MS->search_path, TRUE);
Wm->as_module->module_name = Str::duplicate(symbol);
Wm->as_module->module_tag = Str::duplicate(set);
Wm->as_module->origin_marker = marker;
Dictionaries::create(D, symbol);
Dictionaries::write_value(D, symbol, Wm);
}
@<Expand dependent-files@> =
text_stream *tool = parameter_values[0];
text_stream *modules = parameter_values[1];
text_stream *both = parameter_values[2];
if (Str::len(tool) > 0) {
if (Dictionaries::find(MS->tools_dictionary, tool)) {
web_md *Wm = Dictionaries::read_value(MS->tools_dictionary, tool);
Makefiles::pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename);
} else if (Dictionaries::find(MS->webs_dictionary, tool)) {
web_md *Wm = Dictionaries::read_value(MS->webs_dictionary, tool);
Makefiles::pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename);
} else {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown tool '%S' to find dependencies for", tool);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
} else if (Str::len(modules) > 0) {
if (Dictionaries::find(MS->modules_dictionary, modules)) {
web_md *Wm = Dictionaries::read_value(MS->modules_dictionary, modules);
Makefiles::pattern(OUT, Wm->sections_md, Wm->contents_filename);
} else {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown module '%S' to find dependencies for", modules);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
} else if (Str::len(both) > 0) {
if (Dictionaries::find(MS->tools_dictionary, both)) {
web_md *Wm = Dictionaries::read_value(MS->tools_dictionary, both);
Makefiles::pattern(OUT, Wm->sections_md, Wm->contents_filename);
} else if (Dictionaries::find(MS->webs_dictionary, both)) {
web_md *Wm = Dictionaries::read_value(MS->webs_dictionary, both);
Makefiles::pattern(OUT, Wm->sections_md, Wm->contents_filename);
} else {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown tool '%S' to find dependencies for", both);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
} else {
Makefiles::pattern(OUT, MS->for_web->md->sections_md, MS->for_web->md->contents_filename);
}
WRITE("\n");
MS->last_line_was_blank = FALSE;
@<Expand repeat-block@> =
if (MS->repeat_sp >= MAX_MAKEFILE_REPEAT_DEPTH) {
Errors::in_text_file("repetition too deep", tfp);
} else {
text_stream *category = parameter_values[0];
text_stream *set = parameter_values[1];
text_stream *with = parameter_values[2];
text_stream *in = parameter_values[3];
if (Str::len(set) == 0) set = I"all";
if (Str::eq(category, I"tool")) {
int marker = MAKEFILE_TOOL_MOM;
@<Begin a repeat block@>;
} else if (Str::eq(category, I"web")) {
int marker = MAKEFILE_WEB_MOM;
@<Begin a repeat block@>;
} else if (Str::eq(category, I"module")) {
int marker = MAKEFILE_MODULE_MOM;
@<Begin a repeat block@>;
} else if (Str::len(category) > 0) {
Errors::in_text_file("category should be 'tool', 'module' or 'web'", tfp);
} else {
if ((Str::len(with) == 0) || (Str::len(in) == 0))
Errors::in_text_file("should give both with: VAR and in: LIST", tfp);
@<Begin a repeat with@>;
}
}
@<Begin a repeat block@> =
makefile_repeat *rep = &(MS->repeat_data[MS->repeat_sp++]);
MS->shadow_sp = 1;
rep->repeat_scope = marker;
rep->repeat_tag = Str::duplicate(set);
rep->repeat_with = NULL;
rep->repeat_in = NULL;
rep->repeat_is_block = TRUE;
if (mm->reserved_macro_meaning == REPEAT_SPAN_RMM) rep->repeat_is_block = FALSE;
rep->repeat_saved_dest = MS->dest;
MS->dest = Str::new();
@<Begin a repeat with@> =
makefile_repeat *rep = &(MS->repeat_data[MS->repeat_sp++]);
MS->shadow_sp = 1;
rep->repeat_scope = -1;
rep->repeat_tag = NULL;
rep->repeat_with = Str::duplicate(with);
rep->repeat_in = Str::duplicate(in);
rep->repeat_is_block = TRUE;
if (mm->reserved_macro_meaning == REPEAT_SPAN_RMM) rep->repeat_is_block = FALSE;
rep->repeat_saved_dest = MS->dest;
MS->dest = Str::new();
@<Expand end-block@> =
MS->shadow_sp = 0;
if (MS->repeat_sp == 0) Errors::in_text_file("end without repeat", tfp);
else {
makefile_repeat *rep = &(MS->repeat_data[--(MS->repeat_sp)]);
int as_lines = TRUE;
if (mm->reserved_macro_meaning == END_SPAN_RMM) as_lines = FALSE;
text_stream *matter = MS->dest;
MS->dest = rep->repeat_saved_dest;
Makefiles::repeat(matter, as_lines, tfp, rep, MS);
}
@<Expand set@> =
text_stream *name = parameter_values[0];
text_stream *value = parameter_values[1];
if (Makefiles::acceptable_variable_name(name) == FALSE)
Errors::in_text_file("improper variable name", tfp);
makefile_variable *var = Makefiles::ensure_variable(name, MS->stack_frame);
var->value = Str::duplicate(value);

View file

@ -483,19 +483,155 @@ creates a makefile for the web |W| and stores it in |M|. For example,
The makefile is constructed using a prototype file called a "makescript".
Ordinarily the script used will be the one stored in
= (text)
W/makescript.txt
W/W.mkscript
=
or, if no such file exists, the default one stored in Inweb:
= (text)
inweb/Materials/makescript.txt
inweb/Materials/default.mkscript
=
but this can be changed by using |-prototype S|, which tells Inweb to use
|S| as the script. If a |-prototype| is given, then there's no need to
specify any one web for Inweb to use: this allows Inweb to construct more
elaborate makefiles for multi-web projects. (This is how the main makefile
for the Inform project is constructed.)
elaborate makefiles for multi-web projects.
To see how makescripts work, it's easiest simply to look at the default one.
@ A makescript is really just copied out to produce the makefile, except that:
(*) Comment lines, those beginning with |#|, are stripped out.
(*) Material in balanced braces |{ ... }| is expanded into something more
interesting.
@ Makescripts support variables, whose names have to be in capital letters,
perhaps with underscores and digits added. For example:
= (text)
{set name: SUPPORTED_BUILDS value: 6L02, 6L38, 6M62}
...
echo "I support any of {SUPPORTED_BUILDS}."
=
expands to
= (text)
echo "I support any of 6L02, 6L38, 6M62."
=
What happens is that the |set| macro sets the variable |SUPPORTED_BUILDS| and
gives it the value |6L02, 6L38, 6M62|. Anywhere below this in the file,[1]
|{SUPPORTED_BUILDS}| is replaced by that value.
[1] If you set a variable inside a repeat loop, it will exist only in the loop.
@ Makescripts support repetition. For example:
= (text)
{repeat with: BUILD in: 6L02, 6L38, 6M62}
echo "I support {BUILD}."
{end-repeat}
=
produces:
= (text)
echo "I support 6L02."
echo "I support 6L38."
echo "I support 6M62."
=
@ Like |set|, |repeat| is a "macro". This has two parameters, |with:|, naming
the loop variable, and |in:|, giving a comma-separated list of values for it
to run through in order. In some macros parameters are optional, but not these.
Note that variables can be used within the parameters of macros, as in this example:
= (text)
{repeat with: BUILD in: {SUPPORTED_BUILDS}}
echo "I support {BUILD}."
{end-repeat}
=
Loops can be nested, for those who like to live on the edge. So:
= (text)
{repeat with: X in: alpha, beta, gamma}
{repeat with: Y in: 5, 11}
echo "Greetings, Agent {X}-{Y}."
{end-repeat}
{end-repeat}
=
produces:
= (text)
echo "Greetings, Agent alpha-5."
echo "Greetings, Agent alpha-11."
echo "Greetings, Agent beta-5."
echo "Greetings, Agent beta-11."
echo "Greetings, Agent gamma-5."
echo "Greetings, Agent gamma-11."
=
@ You can also define your own macros, as in this example:
= (text)
{define: link to: TO from: FROM ?options: OPTS}
clang $(CCOPTS) -g -o {TO} {FROM} {OPTS}
{end-define}
=
And here is a usage of it:
= (text)
{link from: frog.o to: frog.c}
=
This doesn't specify "options: ...", but doesn't have to, because that's optional --
note the question mark in the macro declaration. But it does specify "from: ..."
and "to: ...", which are compulsory. Parameters are always named, as this example
suggests, and can be given in any order so long as all the non-optional ones are
present.
This usage results in the following line in the final makefile:
= (text)
clang $(CCOPTS) -g -o frog.c frog.o
=
Note the difference between |$(CCOPTS)|, which is a make variable, and the braced
tokens |{TO}|, |{FROM}| and |{OPTS}|, which are makescript variables (which exist
only inside the definition).
@ A few more built-in macros special to makefiles may be useful:
(*) |{platform-settings}| (which has no parameters) includes a file of makescript
material useful for compiling C-based tools on your current operating system or
"platform". It gets this file at |inweb/Materials/platforms/YOURPLATFORM.mkscript|,
where |YOURPLATFORM| may be |macos|, |windows|, |linux| and so on.
(*) |{identity-settings}| (which has no parameters) writes out make declarations
for make variables |INWEB|, |INTEST|, |MYNAME| and |ME|. The first two are paths
to the inweb and intest tools respectivly. |MYNAME| and |ME| are set only if
inweb has been given a specific web |W| to work with at the command line, and
are then expanded to the directory name and web name respectively for |W|. (These
are very often the same name, e.g., |inform7|.)
(*) |{component symbol: SYMBOL webname: WEBNAME path: PATH set: SET type: TYPE}|
is used only in a makescript for a makefile trying to orchestrate complicated
operations on colonies of large numbers of webs. (See the |inform.mkscript|
script in the main Inform repository for an example.) This macro says that one
of the webs it will talk about is called |WEBNAME|, located at |PATH| in the
file system, belongs to a set you want to call |SET|, has the |TYPE| of one
of |tool|, |web| or |module|. (A |tool| is the main web for an executable;
a |module| for one of the modules making up an executable; a |web| for some
other kind of resource tangled by Inweb but which doesn't make an executable.)
(*) |{dependent-files tool: WEBNAME}| then expands to a list of source files
inside the web |WEBNAME| on which its tangled output depends, written in the
usual make-file way, i.e., divided by spaces. |WEBNAME| has to be one which
has already been declared as having |type: tool| in a |{component ...}| line.
(*) And similarly |{dependent-files module: WEBNAME}|.
(*) More elaborately, |{dependent-files tool-and-modules: WEBNAME}| lists the
dependent files not only in the main web for a tool, which also in any of the
modules which it includes.
(*) A form of loop, |{components type: TYPE set: SET} ... {end-components}|
repeats through all the declared components with the given type and set. (The
set is optional: if not given, the repetition is over everything with that type.)
As before, |TYPE| must be one of |tool|, |web| or |module|. Inside the loop,
|{NAME}| expands to the |SYMBOL| which the component was declared with. For
example:
= (text)
.PHONY: versions
versions:
{components type: tool}
$({SYMBOL}X) -version
{end-components}
=
@h Gitignore.
A similar convenience exists for users who want to use the git source control
@ -508,8 +644,16 @@ specifies the files to be ignored. The following does so for a web |W|:
= (text as ConsoleText)
$ inweb/Tangled/inweb W -gitignore W/.gitignore
=
Once again, Inweb does this by working from a script, this time called
|gitignorescript.txt|.
Once again, Inweb does this by working from a script, and the rules are almost
exactly the same as for makefiles except that the file extension is |.giscript|,
not |.mkscript|, and:
(*) The special makefile macros are not available, though |set| and |repeat| are;
(*) The special macro |{basics}| expands to the contents of the file
|inweb/Materials/default.giscript|. This does the same thing as would be done
if the web provided no script of its own; the idea is that you can then list
some additional things to ignore.
@h Ctags.
Each time a web is tangled, Inweb writes a |tags| file to the web's home

View file

@ -1,6 +1,6 @@
# Inweb 7
v7-alpha.1+1A91 'Escape to Danger' (22 April 2022)
v7-alpha.1+1A92 'Escape to Danger' (23 April 2022)
## About Inweb

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,3 @@
Prerelease: alpha.1
Build Date: 22 April 2022
Build Number: 1A91
Build Date: 23 April 2022
Build Number: 1A92

View file

@ -74,7 +74,7 @@ not necessarily.
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">dict_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">next_in_entry</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">dict_entry</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure dictionary is private to this section.</li><li>The structure dict_entry is accessed in 5/ee, 8/bdfw and here.</li></ul>
<ul class="endnotetexts"><li>The structure dictionary is private to this section.</li><li>The structure dict_entry is accessed in 4/prp, 5/ee, 8/bdfw and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Creation. </b>Dictionaries can have arbitrary size, in that they expand as needed, but for
efficiency's sake the caller can set them up with an initial size of her choice.
</p>

View file

@ -74,6 +74,10 @@ here we are.
<span class="definition-keyword">enum</span> <span class="constant-syntax">module_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">module_search_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">pathname_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">preprocessor_macro_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">preprocessor_macro_parameter_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">preprocessor_variable_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">preprocessor_variable_set_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">scan_directory_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">section_md_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">semantic_version_number_holder_CLASS</span>
@ -108,6 +112,10 @@ here we are.
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">module_search</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">module</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">section_md</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">semantic_version_number_holder</span><span class="plain-syntax">)</span>

View file

@ -134,7 +134,7 @@ constraints:
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">tree_type</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure tree_type is private to this section.</li></ul>
<ul class="endnotetexts"><li>The structure tree_type is accessed in 4/prp and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b></p>
<pre class="displayed-code all-displayed-code code-font">

View file

@ -115,7 +115,7 @@ the temporary stream, not some other string which might need fresh allocation.
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::fatal_with_file</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Errors::fatal_with_file</span></span>:<br/>Text Files - <a href="4-tf.html#SP5_1">&#167;5.1</a>, <a href="4-tf.html#SP5_2">&#167;5.2</a>, <a href="4-tf.html#SP5_3_2">&#167;5.3.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP6_1">&#167;6.1</a>, <a href="5-ee.html#SP6_2">&#167;6.2</a>, <a href="5-ee.html#SP6_3">&#167;6.3</a>, <a href="5-ee.html#SP7_2">&#167;7.2</a>, <a href="5-ee.html#SP7_3">&#167;7.3</a><br/>Binary Files - <a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP8">&#167;8</a>, <a href="6-bf.html#SP9">&#167;9</a>, <a href="6-bf.html#SP10">&#167;10</a><br/>Build Files - <a href="8-bf.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::fatal_with_file</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Errors::fatal_with_file</span></span>:<br/>Text Files - <a href="4-tf.html#SP5_1">&#167;5.1</a>, <a href="4-tf.html#SP5_2">&#167;5.2</a>, <a href="4-tf.html#SP5_3_2">&#167;5.3.2</a><br/>Preprocessor - <a href="4-prp.html#SP1">&#167;1</a><br/>Epub Ebooks - <a href="5-ee.html#SP6_1">&#167;6.1</a>, <a href="5-ee.html#SP6_2">&#167;6.2</a>, <a href="5-ee.html#SP6_3">&#167;6.3</a>, <a href="5-ee.html#SP7_2">&#167;7.2</a>, <a href="5-ee.html#SP7_3">&#167;7.3</a><br/>Binary Files - <a href="6-bf.html#SP7">&#167;7</a>, <a href="6-bf.html#SP8">&#167;8</a>, <a href="6-bf.html#SP9">&#167;9</a>, <a href="6-bf.html#SP10">&#167;10</a><br/>Build Files - <a href="8-bf.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">, </span><span class="string-syntax">"%s: fatal error: %s: %f\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">PROGRAM_NAME</span><span class="plain-syntax">, </span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP1" class="function-link"><span class="function-syntax">Errors::issue</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">ERM</span><span class="plain-syntax">, </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>
@ -179,14 +179,14 @@ specify this at three levels of abstraction:
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::in_text_file</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Errors::in_text_file</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">here</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::in_text_file</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Errors::in_text_file</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Preprocessor - <a href="4-prp.html#SP2_1">&#167;2.1</a>, <a href="4-prp.html#SP2_3">&#167;2.3</a>, <a href="4-prp.html#SP3">&#167;3</a>, <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP8">&#167;8</a>, <a href="4-prp.html#SP11">&#167;11</a>, <a href="4-prp.html#SP12">&#167;12</a>, <a href="4-prp.html#SP13">&#167;13</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">here</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">here</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP6" class="function-link"><span class="function-syntax">Errors::at_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">here</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">text_file_filename</span><span class="plain-syntax">, </span><span class="identifier-syntax">here</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">line_count</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP6" class="function-link"><span class="function-syntax">Errors::at_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::in_text_file_S</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Errors::in_text_file_S</span></span>:<br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">here</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Errors::in_text_file_S</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Errors::in_text_file_S</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">here</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">here</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP6" class="function-link"><span class="function-syntax">Errors::at_position_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="identifier-syntax">here</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">text_file_filename</span><span class="plain-syntax">, </span><span class="identifier-syntax">here</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">line_count</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span>

View file

@ -89,7 +89,7 @@ function togglePopup(material_id) {
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\t'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::is_whitespace</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Characters::is_whitespace</span></span>:<br/>Pattern Matching - <a href="4-pm.html#SP13">&#167;13</a><br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Characters::is_whitespace</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Characters::is_whitespace</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a><br/>Pattern Matching - <a href="4-pm.html#SP13">&#167;13</a><br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">' '</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\t'</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
@ -221,7 +221,7 @@ the more obvious accents from it.
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="3-tm.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresscurrent">chr</li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-cst.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="3-tm.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresscurrent">chr</li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-prp.html">prp</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-cst.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -207,7 +207,7 @@ are almost always best avoided.)
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-chr.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresscurrent">cst</li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-ws.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-chr.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresscurrent">cst</li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-prp.html">prp</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-ws.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -195,7 +195,7 @@ are not. They are simply a little faster to access if short.
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">exp_at</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_BRACKETED_SUBEXPRESSIONS</span><span class="plain-syntax">];</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">match_results</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure match_result is private to this section.</li><li>The structure match_results is accessed in 3/cla, 8/ws, 8/wm, 8/bf and here.</li></ul>
<ul class="endnotetexts"><li>The structure match_result is private to this section.</li><li>The structure match_results is accessed in 3/cla, 4/prp, 8/ws, 8/wm, 8/bf and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>Match result objects are inherently ephemeral, and we can expect to be
creating them and throwing them away frequently. This must be done
explicitly. Note that the storage required is on the C stack (unless some
@ -204,7 +204,7 @@ deallocate.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::create_mr</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Regexp::create_mr</span></span>:<br/><a href="4-pm.html#SP14">&#167;14</a><br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::create_mr</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Regexp::create_mr</span></span>:<br/><a href="4-pm.html#SP14">&#167;14</a><br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Preprocessor - <a href="4-prp.html#SP2">&#167;2</a>, <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP11">&#167;11</a>, <a href="4-prp.html#SP12">&#167;12</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">no_matched_texts</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_BRACKETED_SUBEXPRESSIONS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
@ -214,7 +214,7 @@ deallocate.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::dispose_of</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Regexp::dispose_of</span></span>:<br/><a href="4-pm.html#SP10">&#167;10</a>, <a href="4-pm.html#SP14">&#167;14</a><br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mr</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::dispose_of</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Regexp::dispose_of</span></span>:<br/><a href="4-pm.html#SP10">&#167;10</a>, <a href="4-pm.html#SP14">&#167;14</a><br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Preprocessor - <a href="4-prp.html#SP2">&#167;2</a>, <a href="4-prp.html#SP2_1">&#167;2.1</a>, <a href="4-prp.html#SP2_2">&#167;2.2</a>, <a href="4-prp.html#SP2_3">&#167;2.3</a>, <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP11">&#167;11</a>, <a href="4-prp.html#SP12">&#167;12</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mr</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mr</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_BRACKETED_SUBEXPRESSIONS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mr</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">exp</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]) {</span>
@ -229,7 +229,7 @@ deallocate.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::match</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Regexp::match</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Regexp::match</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Regexp::match</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a>, <a href="3-cla.html#SP12">&#167;12</a><br/>Preprocessor - <a href="4-prp.html#SP2">&#167;2</a>, <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP11">&#167;11</a>, <a href="4-prp.html#SP12">&#167;12</a><br/>Web Structure - <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_3_3_2_1">&#167;7.3.3.2.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Web Modules - <a href="8-wm.html#SP9">&#167;9</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_3">&#167;7.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pattern</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mr</span><span class="plain-syntax">) </span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::prepare</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = (</span><a href="4-pm.html#SP11" class="function-link"><span class="function-syntax">Regexp::match_r</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">pattern</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">mr</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)) </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
@ -555,7 +555,7 @@ For example,
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-pm.html#SP14">&#167;14</a> (twice).</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-taa.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresscurrent">pm</li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="5-htm.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-taa.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-prp.html">prp</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresscurrent">pm</li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="5-htm.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -0,0 +1,700 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Preprocessor</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
var popup = document.getElementById(material_id);
popup.classList.toggle("show");
}
</script>
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Octagram.png" width=72 height=72">
</a></h1>
<ul><li><a href="../inweb/index.html">inweb</a></li>
</ul><h2>Foundation Module</h2><ul>
<li><a href="index.html"><span class="selectedlink">foundation</span></a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
</ul><h2>Example Webs</h2><ul>
<li><a href="../goldbach/index.html">goldbach</a></li>
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
<li><a href="../eastertide/index.html">eastertide</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inform/docs/index.html">inform</a></li>
<li><a href="../../../intest/docs/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Preprocessor' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#4">Chapter 4: Text Handling</a></li><li><b>Preprocessor</b></li></ul></div>
<p class="purpose">A simple, general-purpose preprocessor for text files, expanding macros and performing repetitions.</p>
<ul class="toc"><li><a href="4-prp.html#SP1">&#167;1. State</a></li><li><a href="4-prp.html#SP2">&#167;2. Scanner</a></li><li><a href="4-prp.html#SP4">&#167;4. Variables</a></li><li><a href="4-prp.html#SP5">&#167;5. Macros</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. State. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PREPROCESSOR_LOOP_DEPTH</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_var_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iterations</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">text_stream</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">repeat_is_block</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">repeat_saved_dest</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">defining</span><span class="plain-syntax">; </span><span class="comment-syntax"> a "define" body being scanned</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">repeat_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">shadow_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> </span><span class="identifier-syntax">repeat_data</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PREPROCESSOR_LOOP_DEPTH</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_newline</span><span class="plain-syntax">; </span><span class="comment-syntax"> at the end of this line</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_line_was_blank</span><span class="plain-syntax">; </span><span class="comment-syntax"> used to suppress runs of multiple blank lines</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">global_variables</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">stack_frame</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">known_macros</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">preprocessor_macro</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">;</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::preprocess</span><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">header</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">, </span><span class="reserved-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">processed_file</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">STREAM_OPEN_TO_FILE</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">processed_file</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="constant-syntax">ISO_ENC</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP2" class="function-link"><span class="function-syntax">Errors::fatal_with_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"unable to write tangled file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = &amp;</span><span class="identifier-syntax">processed_file</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">header</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">defining</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">global_variables</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::new_variable_set</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">global_variables</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">known_macros</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::list_of_reserved_macros</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">specifics</span><span class="plain-syntax"> = </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-tf.html#SP5" class="function-link"><span class="function-syntax">TextFiles::read</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open prototype file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">, </span><a href="4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">STREAM_CLOSE</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure preprocessor_loop is private to this section.</li><li>The structure preprocessor_state is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Scanner. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::scan_line</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::scan_line</span></span>:<br/><a href="4-prp.html#SP1">&#167;1</a>, <a href="4-prp.html#SP12">&#167;12</a>, <a href="4-prp.html#SP13_1">&#167;13.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">X</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *#%c*"</span><span class="plain-syntax">)) { </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; } </span><span class="comment-syntax"> Skip comment lines</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *{define: *(%C+) (%c*)} *"</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Begin a definition</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *{end-define} *"</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP2_3" class="named-paragraph-link"><span class="named-paragraph">End a definition</span><span class="named-paragraph-number">2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defining</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">Continue a definition</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2_1" class="paragraph-anchor"></a><b>&#167;2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Begin a definition</span><span class="named-paragraph-number">2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defining</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"nested definitions are not allowed"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defining</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">known_macros</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><a href="4-prp.html#SP12" class="function-link"><span class="function-syntax">Preprocessor::default_expander</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2" class="paragraph-anchor"></a><b>&#167;2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Continue a definition</span><span class="named-paragraph-number">2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><a href="4-prp.html#SP8" class="function-link"><span class="function-syntax">Preprocessor::add_line_to_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defining</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_3" class="paragraph-anchor"></a><b>&#167;2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">End a definition</span><span class="named-paragraph-number">2.3</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defining</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"{end-define} without {define: ...}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">defining</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::expand</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::expand</span></span>:<br/><a href="4-prp.html#SP2">&#167;2</a>, <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP11">&#167;11</a>, <a href="4-prp.html#SP13_1">&#167;13.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">after_times</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">after_times</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'{'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'}'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">after_times</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many '}'s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many '{'s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">after_times</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Expand a macro</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand a macro</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%C+) (%c*)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">known_macros</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">Str::is_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">begins_repeat</span><span class="plain-syntax">)) </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">begins_repeat</span><span class="plain-syntax">)) </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_name</span><span class="plain-syntax">, </span><span class="string-syntax">"end-%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">end_name</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_data</span><span class="plain-syntax">[</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">repeat_is_block</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ends_repeat</span><span class="plain-syntax">)) </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ends_repeat</span><span class="plain-syntax">)) </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::acceptable_variable_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"{%S}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::find_variable_in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">var</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"unknown variable '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP10" class="function-link"><span class="function-syntax">Preprocessor::find_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">known_macros</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"unknown macro '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP2" class="function-link"><span class="function-syntax">Characters::is_whitespace</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_last_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">Str::delete_last_character</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP2" class="function-link"><span class="function-syntax">Characters::is_whitespace</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_first_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">Str::delete_first_character</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">divert_if_repeating</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">mm</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">begins_repeat</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shadow_sp</span><span class="plain-syntax">++;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">mm</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ends_repeat</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shadow_sp</span><span class="plain-syntax">--;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">divert_if_repeating</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">divert_if_repeating</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"{%S}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::expand_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">, </span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_newline_after_expanding</span><span class="plain-syntax">) </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Variables. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variables</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">preprocessor_variable</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outer</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::new_variable_set</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::new_variable_set</span></span>:<br/><a href="4-prp.html#SP1">&#167;1</a>, <a href="4-prp.html#SP12">&#167;12</a>, <a href="4-prp.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outer</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">variables</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">outer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">outer</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::find_variable_in_one</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">, </span><span class="identifier-syntax">set</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">variables</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">var</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::find_variable_in</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::find_variable_in</span></span>:<br/><a href="4-prp.html#SP3_1">&#167;3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">set</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::find_variable_in_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">set</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax"> = </span><span class="identifier-syntax">set</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">outer</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::ensure_variable</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::ensure_variable</span></span>:<br/><a href="4-prp.html#SP12">&#167;12</a>, <a href="4-prp.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">in_set</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">in_set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"variable without set"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::find_variable_in_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">in_set</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">""</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">, </span><span class="identifier-syntax">in_set</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">variables</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::acceptable_variable_name</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::acceptable_variable_name</span></span>:<br/><a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &gt;= </span><span class="character-syntax">'0'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt;= </span><span class="character-syntax">'9'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &gt;= </span><span class="character-syntax">'A'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt;= </span><span class="character-syntax">'Z'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'_'</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure preprocessor_variable is accessed in 2/dct, 2/trs, 5/ee, 8/bdfw and here.</li><li>The structure preprocessor_variable_set is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Macros. </b></p>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. </b>The above definition has three parameters, one optional, but only one line. There
are (for now, anyway) hard but harmlessly large limits on the number of these:
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PP_MACRO_LINES</span><span class="plain-syntax"> </span><span class="constant-syntax">128</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameters</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_parameters</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lines</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PP_MACRO_LINES</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_lines</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_newline_after_expanding</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">begins_repeat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ends_repeat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">span</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *);</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">definition_token</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">optional</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure preprocessor_macro is private to this section.</li><li>The structure preprocessor_macro_parameter is accessed in 2/trs and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>New macro declaration lines are processed here, and added to a list <span class="extract"><span class="extract-syntax">L</span></span> of
valid macros:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::new_macro</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::new_macro</span></span>:<br/><a href="4-prp.html#SP2_1">&#167;2.1</a>, <a href="4-prp.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prp.html#SP10" class="function-link"><span class="function-syntax">Preprocessor::find_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"a macro with this name already exists"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_parameters</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lines</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_newline_after_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">begins_repeat</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ends_repeat</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">expander</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expander</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr2</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr2</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *(%C+): *(%C+) *(%c*)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">par_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr2</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr2</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr2</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[2]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_parameters</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many parameters in this definition"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP7_1" class="named-paragraph-link"><span class="named-paragraph">Add parameter to macro</span><span class="named-paragraph-number">7.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">Str::is_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"parameter list for this definition is malformed"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7_1" class="paragraph-anchor"></a><b>&#167;7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add parameter to macro</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">par_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_token</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">token_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">optional</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_first_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">) == </span><span class="character-syntax">'?'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">optional</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">Str::delete_first_character</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_parameters</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP7">&#167;7</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. </b>We can then add lines to the definition:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::add_line_to_macro</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::add_line_to_macro</span></span>:<br/><a href="4-prp.html#SP2_2">&#167;2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lines</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_PP_MACRO_LINES</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many lines in this definition"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lines</span><span class="plain-syntax">[</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">no_lines</span><span class="plain-syntax">++] = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>A few macros are "reserved", that is, have built-in meanings and are not
declared by any makescript but by us. (These have no lines, only parameters.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::list_of_reserved_macros</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::list_of_reserved_macros</span></span>:<br/><a href="4-prp.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_repeat_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"repeat"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"with: WITH in: IN"</span><span class="plain-syntax">, </span><a href="4-prp.html#SP12" class="function-link"><span class="function-syntax">Preprocessor::repeat_expander</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_span_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"set"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"name: NAME value: VALUE"</span><span class="plain-syntax">, </span><a href="4-prp.html#SP12" class="function-link"><span class="function-syntax">Preprocessor::set_expander</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::reserve_macro</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reserved</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">), </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">expander</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">reserved</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::reserve_span_macro</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">reserved</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">expander</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">reserved</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_newline_after_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">reserved</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">reserved</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">reserved</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::reserve_repeat_macro</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"%S-block"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">expander</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">begins_repeat</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"end-%S-block"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><a href="4-prp.html#SP13" class="function-link"><span class="function-syntax">Preprocessor::end_repeat_expander</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ends_repeat</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"%S-span"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_span_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">expander</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">begins_repeat</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"end-%S-span"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_span_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><a href="4-prp.html#SP13" class="function-link"><span class="function-syntax">Preprocessor::end_repeat_expander</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ends_repeat</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. </b>Finding a macro in a list. (We could use a dictionary for efficiency, but really,
it's unlikely there are ever more than a few macros.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::find_macro</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::find_macro</span></span>:<br/><a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Expanding a macro is the main event, then:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::expand_macro</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::expand_macro</span></span>:<br/><a href="4-prp.html#SP3_1">&#167;3.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr2</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr2</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *(%C+): *(%c*)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">setting</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr2</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr2</span><span class="plain-syntax">.</span><span class="identifier-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr3</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr3</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%c+?) *(%C+: *%c*)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr3</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr3</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;mm-&gt;</span><span class="element-syntax">no_parameters</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">setting</span><span class="plain-syntax">, </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">saved</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">saved</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">found</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"unknown parameter '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">setting</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">, </span><span class="identifier-syntax">remainder</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr3</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">Str::is_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"parameter list is malformed"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;mm-&gt;</span><span class="element-syntax">no_parameters</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-&gt;</span><span class="element-syntax">optional</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"compulsory parameter '%S' not given"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-&gt;</span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rep</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">begins_repeat</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">MAX_PREPROCESSOR_LOOP_DEPTH</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"repetition too deep"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rep</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_data</span><span class="plain-syntax">[</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax">++]);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_var_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">"NAME"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">iterations</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_is_block</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax">) </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_is_block</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_saved_dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> (*(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">expander</span><span class="plain-syntax">))(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">rep</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::default_expander</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::default_expander</span></span>:<br/><a href="4-prp.html#SP2_1">&#167;2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rep</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::new_variable_set</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;mm-&gt;</span><span class="element-syntax">no_parameters</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::ensure_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-&gt;</span><span class="element-syntax">definition_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax">&lt;mm-&gt;</span><span class="element-syntax">no_lines</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::scan_line</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">lines</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">outer</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::set_expander</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::set_expander</span></span>:<br/><a href="4-prp.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rep</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::acceptable_variable_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"improper variable name"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::ensure_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">value</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::repeat_expander</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::repeat_expander</span></span>:<br/><a href="4-prp.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rep</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">in</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_var_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">with</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">in</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%c*?),(%c*)"</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP24" class="function-link"><span class="function-syntax">Str::trim_white_space</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">), </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">iterations</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1]);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">in</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP24" class="function-link"><span class="function-syntax">Str::trim_white_space</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">), </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">iterations</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::end_repeat_expander</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::end_repeat_expander</span></span>:<br/><a href="4-prp.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rep</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"end without repeat"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rep</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_data</span><span class="plain-syntax">[--(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax">)]);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">as_lines</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">span</span><span class="plain-syntax">) </span><span class="identifier-syntax">as_lines</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">matter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">repeat_saved_dest</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::new_variable_set</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::ensure_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">loop_var_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">rep</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">iterations</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP13_1" class="named-paragraph-link"><span class="named-paragraph">Iterate with this value</span><span class="named-paragraph-number">13.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">stack_frame</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">outer</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13_1" class="paragraph-anchor"></a><b>&#167;13.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Iterate with this value</span><span class="named-paragraph-number">13.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="identifier-syntax">loop_var</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">as_lines</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">matter</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::scan_line</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP13">&#167;13</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-tf.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresscurrent">prp</li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-taa.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>

View file

@ -88,7 +88,7 @@ access.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Str::new</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">&#167;4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">&#167;6</a>, <a href="3-cla.html#SP11">&#167;11</a><br/>Directories - <a href="3-drc.html#SP3">&#167;3</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">&#167;5.2</a>, <a href="8-ws.html#SP6_1">&#167;6.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Str::new</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">&#167;4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">&#167;6</a>, <a href="3-cla.html#SP11">&#167;11</a><br/>Directories - <a href="3-drc.html#SP3">&#167;3</a><br/>Preprocessor - <a href="4-prp.html#SP11">&#167;11</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">&#167;5.2</a>, <a href="8-ws.html#SP6_1">&#167;6.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new_with_capacity</span></a><span class="plain-syntax">(32);</span>
<span class="plain-syntax">}</span>
@ -108,7 +108,7 @@ duplicated as <span class="extract"><span class="extract-syntax">NULL</span></sp
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::duplicate</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Str::duplicate</span></span>:<br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Trees - <a href="2-trs.html#SP7">&#167;7</a>, <a href="2-trs.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP5_1">&#167;5.1</a><br/>Time - <a href="3-tm.html#SP6">&#167;6</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7_1">&#167;7.1</a><br/>Web Modules - <a href="8-wm.html#SP2">&#167;2</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::duplicate</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Str::duplicate</span></span>:<br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Trees - <a href="2-trs.html#SP7">&#167;7</a>, <a href="2-trs.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP5_1">&#167;5.1</a><br/>Time - <a href="3-tm.html#SP6">&#167;6</a><br/>Preprocessor - <a href="4-prp.html#SP4">&#167;4</a>, <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP7_1">&#167;7.1</a>, <a href="4-prp.html#SP8">&#167;8</a>, <a href="4-prp.html#SP9">&#167;9</a>, <a href="4-prp.html#SP12">&#167;12</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7_1">&#167;7.1</a><br/>Web Modules - <a href="8-wm.html#SP2">&#167;2</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">E</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-str.html#SP26" class="function-link"><span class="function-syntax">Streams::open_to_memory</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">)+4)) {</span>
@ -198,7 +198,7 @@ thing plus a little extra, for efficiency's sake.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::len</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Str::len</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a>, <a href="4-sm.html#SP7">&#167;7</a>, <a href="4-sm.html#SP10">&#167;10</a>, <a href="4-sm.html#SP11">&#167;11</a>, <a href="4-sm.html#SP12">&#167;12</a>, <a href="4-sm.html#SP13">&#167;13</a>, <a href="4-sm.html#SP14">&#167;14</a>, <a href="4-sm.html#SP15">&#167;15</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP19">&#167;19</a>, <a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP25">&#167;25</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Debugging Log - <a href="2-dl.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a>, <a href="3-cla.html#SP14">&#167;14</a>, <a href="3-cla.html#SP14_1">&#167;14.1</a><br/>Pathnames - <a href="3-pth.html#SP4">&#167;4</a>, <a href="3-pth.html#SP5">&#167;5</a>, <a href="3-pth.html#SP7">&#167;7</a>, <a href="3-pth.html#SP8">&#167;8</a><br/>Filenames - <a href="3-fln.html#SP2">&#167;2</a>, <a href="3-fln.html#SP3">&#167;3</a>, <a href="3-fln.html#SP5">&#167;5</a>, <a href="3-fln.html#SP8">&#167;8</a>, <a href="3-fln.html#SP9">&#167;9</a><br/>Tries and Avinues - <a href="4-taa.html#SP2_1">&#167;2.1</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP10">&#167;10</a>, <a href="4-pm.html#SP11_3">&#167;11.3</a>, <a href="4-pm.html#SP14">&#167;14</a><br/>HTML - <a href="5-htm.html#SP8">&#167;8</a>, <a href="5-htm.html#SP17">&#167;17</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_1">&#167;7.1</a>, <a href="5-ee.html#SP7_2_3">&#167;7.2.3</a>, <a href="5-ee.html#SP7_2_4">&#167;7.2.4</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP7_1">&#167;7.1</a>, <a href="7-vn.html#SP10">&#167;10</a><br/>Web Structure - <a href="8-ws.html#SP5_4">&#167;5.4</a>, <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3">&#167;7.3</a>, <a href="8-ws.html#SP7_3_3_1">&#167;7.3.3.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP5">&#167;5</a>, <a href="8-bdfw.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a>, <a href="8-bf.html#SP4">&#167;4</a>, <a href="8-bf.html#SP5">&#167;5</a>, <a href="8-bf.html#SP6">&#167;6</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7">&#167;7</a>, <a href="8-st.html#SP7_1">&#167;7.1</a>, <a href="8-st.html#SP7_2_4">&#167;7.2.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::len</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Str::len</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a>, <a href="4-sm.html#SP7">&#167;7</a>, <a href="4-sm.html#SP10">&#167;10</a>, <a href="4-sm.html#SP11">&#167;11</a>, <a href="4-sm.html#SP12">&#167;12</a>, <a href="4-sm.html#SP13">&#167;13</a>, <a href="4-sm.html#SP14">&#167;14</a>, <a href="4-sm.html#SP15">&#167;15</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP19">&#167;19</a>, <a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP25">&#167;25</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Debugging Log - <a href="2-dl.html#SP9">&#167;9</a><br/>Command Line Arguments - <a href="3-cla.html#SP13">&#167;13</a>, <a href="3-cla.html#SP14">&#167;14</a>, <a href="3-cla.html#SP14_1">&#167;14.1</a><br/>Pathnames - <a href="3-pth.html#SP4">&#167;4</a>, <a href="3-pth.html#SP5">&#167;5</a>, <a href="3-pth.html#SP7">&#167;7</a>, <a href="3-pth.html#SP8">&#167;8</a><br/>Filenames - <a href="3-fln.html#SP2">&#167;2</a>, <a href="3-fln.html#SP3">&#167;3</a>, <a href="3-fln.html#SP5">&#167;5</a>, <a href="3-fln.html#SP8">&#167;8</a>, <a href="3-fln.html#SP9">&#167;9</a><br/>Preprocessor - <a href="4-prp.html#SP2">&#167;2</a>, <a href="4-prp.html#SP3">&#167;3</a>, <a href="4-prp.html#SP3_1">&#167;3.1</a><br/>Tries and Avinues - <a href="4-taa.html#SP2_1">&#167;2.1</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP10">&#167;10</a>, <a href="4-pm.html#SP11_3">&#167;11.3</a>, <a href="4-pm.html#SP14">&#167;14</a><br/>HTML - <a href="5-htm.html#SP8">&#167;8</a>, <a href="5-htm.html#SP17">&#167;17</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_1">&#167;7.1</a>, <a href="5-ee.html#SP7_2_3">&#167;7.2.3</a>, <a href="5-ee.html#SP7_2_4">&#167;7.2.4</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP7_1">&#167;7.1</a>, <a href="7-vn.html#SP10">&#167;10</a><br/>Web Structure - <a href="8-ws.html#SP5_4">&#167;5.4</a>, <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3">&#167;7.3</a>, <a href="8-ws.html#SP7_3_3_1">&#167;7.3.3.1</a>, <a href="8-ws.html#SP7_2_2_3_1">&#167;7.2.2.3.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP5">&#167;5</a>, <a href="8-bdfw.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a>, <a href="8-bf.html#SP4">&#167;4</a>, <a href="8-bf.html#SP5">&#167;5</a>, <a href="8-bf.html#SP6">&#167;6</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7">&#167;7</a>, <a href="8-st.html#SP7_1">&#167;7.1</a>, <a href="8-st.html#SP7_2_4">&#167;7.2.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-str.html#SP38" class="function-link"><span class="function-syntax">Streams::get_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
@ -277,21 +277,21 @@ at those positions may well not be, of course.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Str::get</span></span>:<br/><a href="4-sm.html#SP7">&#167;7</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP23">&#167;23</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP25">&#167;25</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Dictionaries - <a href="2-dct.html#SP4">&#167;4</a><br/>Pathnames - <a href="3-pth.html#SP4">&#167;4</a>, <a href="3-pth.html#SP5">&#167;5</a><br/>Filenames - <a href="3-fln.html#SP2">&#167;2</a>, <a href="3-fln.html#SP3">&#167;3</a>, <a href="3-fln.html#SP7">&#167;7</a>, <a href="3-fln.html#SP8">&#167;8</a>, <a href="3-fln.html#SP9">&#167;9</a><br/>Shell - <a href="3-shl.html#SP1">&#167;1</a><br/>Pattern Matching - <a href="4-pm.html#SP5">&#167;5</a><br/>HTML - <a href="5-htm.html#SP26">&#167;26</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP10">&#167;10</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">string_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Str::get</span></span>:<br/><a href="4-sm.html#SP7">&#167;7</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP22">&#167;22</a>, <a href="4-sm.html#SP23">&#167;23</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP25">&#167;25</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Dictionaries - <a href="2-dct.html#SP4">&#167;4</a><br/>Pathnames - <a href="3-pth.html#SP4">&#167;4</a>, <a href="3-pth.html#SP5">&#167;5</a><br/>Filenames - <a href="3-fln.html#SP2">&#167;2</a>, <a href="3-fln.html#SP3">&#167;3</a>, <a href="3-fln.html#SP7">&#167;7</a>, <a href="3-fln.html#SP8">&#167;8</a>, <a href="3-fln.html#SP9">&#167;9</a><br/>Shell - <a href="3-shl.html#SP1">&#167;1</a><br/>Preprocessor - <a href="4-prp.html#SP4">&#167;4</a>, <a href="4-prp.html#SP13_1">&#167;13.1</a><br/>Pattern Matching - <a href="4-pm.html#SP5">&#167;5</a><br/>HTML - <a href="5-htm.html#SP26">&#167;26</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a>, <a href="7-vn.html#SP10">&#167;10</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7_2">&#167;7.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">string_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="identifier-syntax">S</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="element-syntax">index</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-str.html#SP40" class="function-link"><span class="function-syntax">Streams::get_char_at_index</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="element-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="element-syntax">index</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_at</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Str::get_at</span></span>:<br/><a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Pathnames - <a href="3-pth.html#SP7">&#167;7</a><br/>Filenames - <a href="3-fln.html#SP5">&#167;5</a><br/>Tries and Avinues - <a href="4-taa.html#SP2">&#167;2</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP11">&#167;11</a>, <a href="4-pm.html#SP11_4">&#167;11.4</a>, <a href="4-pm.html#SP11_6">&#167;11.6</a>, <a href="4-pm.html#SP14">&#167;14</a>, <a href="4-pm.html#SP14_1">&#167;14.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP7">&#167;7</a><br/>Build Files - <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_1">&#167;7.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">index</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_at</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Str::get_at</span></span>:<br/><a href="4-sm.html#SP20">&#167;20</a>, <a href="4-sm.html#SP21">&#167;21</a>, <a href="4-sm.html#SP24">&#167;24</a>, <a href="4-sm.html#SP26">&#167;26</a><br/>Pathnames - <a href="3-pth.html#SP7">&#167;7</a><br/>Filenames - <a href="3-fln.html#SP5">&#167;5</a><br/>Preprocessor - <a href="4-prp.html#SP3">&#167;3</a><br/>Tries and Avinues - <a href="4-taa.html#SP2">&#167;2</a><br/>Pattern Matching - <a href="4-pm.html#SP3">&#167;3</a>, <a href="4-pm.html#SP4">&#167;4</a>, <a href="4-pm.html#SP11">&#167;11</a>, <a href="4-pm.html#SP11_4">&#167;11.4</a>, <a href="4-pm.html#SP11_6">&#167;11.6</a>, <a href="4-pm.html#SP14">&#167;14</a>, <a href="4-pm.html#SP14_1">&#167;14.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1_1">&#167;5.4.1.1</a>, <a href="8-ws.html#SP7">&#167;7</a><br/>Build Files - <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_1">&#167;7.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">index</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">S</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">index</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-str.html#SP40" class="function-link"><span class="function-syntax">Streams::get_char_at_index</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">index</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_first_char</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Str::get_first_char</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a><br/>Filenames - <a href="3-fln.html#SP8">&#167;8</a><br/>Version Numbers - <a href="7-vn.html#SP10">&#167;10</a><br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a>, <a href="8-ws.html#SP7_3_3">&#167;7.3.3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_2">&#167;7.2.2</a>, <a href="8-st.html#SP7_2_5">&#167;7.2.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_first_char</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Str::get_first_char</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a><br/>Filenames - <a href="3-fln.html#SP8">&#167;8</a><br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP7_1">&#167;7.1</a><br/>Version Numbers - <a href="7-vn.html#SP10">&#167;10</a><br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a>, <a href="8-ws.html#SP7_3_3">&#167;7.3.3</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_2">&#167;7.2.2</a>, <a href="8-st.html#SP7_2_5">&#167;7.2.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">Str::at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_last_char</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Str::get_last_char</span></span>:<br/>Pathnames - <a href="3-pth.html#SP8">&#167;8</a><br/>Web Structure - <a href="8-ws.html#SP7_3_3_1">&#167;7.3.3.1</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_4">&#167;7.2.4</a>, <a href="8-st.html#SP7_2_5_2">&#167;7.2.5.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="function-syntax">Str::get_last_char</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Str::get_last_char</span></span>:<br/>Pathnames - <a href="3-pth.html#SP8">&#167;8</a><br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a><br/>Web Structure - <a href="8-ws.html#SP7_3_3_1">&#167;7.3.3.1</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_4">&#167;7.2.4</a>, <a href="8-st.html#SP7_2_5_2">&#167;7.2.5.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">Str::at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">-1));</span>
@ -319,7 +319,7 @@ at those positions may well not be, of course.)
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Truncation. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::clear</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Str::clear</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP18">&#167;18</a>, <a href="4-sm.html#SP25">&#167;25</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a><br/>Text Files - <a href="4-tf.html#SP6">&#167;6</a><br/>Pattern Matching - <a href="4-pm.html#SP11_6">&#167;11.6</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Build Files - <a href="8-bf.html#SP8">&#167;8</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2">&#167;7.2</a>, <a href="8-st.html#SP7_2_5_1">&#167;7.2.5.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::clear</span><button class="popup" onclick="togglePopup('usagePopup21')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup21">Usage of <span class="code-font"><span class="function-syntax">Str::clear</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a>, <a href="4-sm.html#SP17">&#167;17</a>, <a href="4-sm.html#SP18">&#167;18</a>, <a href="4-sm.html#SP25">&#167;25</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a><br/>Text Files - <a href="4-tf.html#SP6">&#167;6</a><br/>Preprocessor - <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP9">&#167;9</a>, <a href="4-prp.html#SP11">&#167;11</a>, <a href="4-prp.html#SP12">&#167;12</a>, <a href="4-prp.html#SP13_1">&#167;13.1</a><br/>Pattern Matching - <a href="4-pm.html#SP11_6">&#167;11.6</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Version Numbers - <a href="7-vn.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1">&#167;5.4.1</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3_2_1">&#167;7.3.2.1</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a>, <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a><br/>Build Files - <a href="8-bf.html#SP8">&#167;8</a>, <a href="8-bf.html#SP9">&#167;9</a><br/>Simple Tangler - <a href="8-st.html#SP7_2">&#167;7.2</a>, <a href="8-st.html#SP7_2_5_1">&#167;7.2.5.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::truncate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
@ -374,7 +374,7 @@ at those positions may well not be, of course.)
<span class="plain-syntax"> </span><a href="2-str.html#SP42" class="function-link"><span class="function-syntax">Streams::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="identifier-syntax">S2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::copy</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Str::copy</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a><br/>Command Line Arguments - <a href="3-cla.html#SP12">&#167;12</a><br/>Pattern Matching - <a href="4-pm.html#SP14">&#167;14</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a>, <a href="5-ee.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7">&#167;7</a>, <a href="8-bdfw.html#SP7_2">&#167;7.2</a><br/>Build Files - <a href="8-bf.html#SP8">&#167;8</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_2">&#167;7.2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::copy</span><button class="popup" onclick="togglePopup('usagePopup23')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup23">Usage of <span class="code-font"><span class="function-syntax">Str::copy</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a><br/>Command Line Arguments - <a href="3-cla.html#SP12">&#167;12</a><br/>Preprocessor - <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP11">&#167;11</a>, <a href="4-prp.html#SP12">&#167;12</a><br/>Pattern Matching - <a href="4-pm.html#SP14">&#167;14</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a>, <a href="5-ee.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_3_2">&#167;7.3.2</a>, <a href="8-ws.html#SP7_3_3_2">&#167;7.3.3.2</a>, <a href="8-ws.html#SP7_2_2_3">&#167;7.2.2.3</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP7">&#167;7</a>, <a href="8-bdfw.html#SP7_2">&#167;7.2</a><br/>Build Files - <a href="8-bf.html#SP8">&#167;8</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_2">&#167;7.2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">S1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">S2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-str.html#SP42" class="function-link"><span class="function-syntax">Streams::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="identifier-syntax">S2</span><span class="plain-syntax">);</span>
@ -411,7 +411,7 @@ at those positions may well not be, of course.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::eq</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">Str::eq</span></span>:<br/>Debugging Log - <a href="2-dl.html#SP9">&#167;9</a><br/>Dictionaries - <a href="2-dct.html#SP7_3">&#167;7.3</a><br/>Pathnames - <a href="3-pth.html#SP3">&#167;3</a>, <a href="3-pth.html#SP7">&#167;7</a>, <a href="3-pth.html#SP8">&#167;8</a><br/>Filenames - <a href="3-fln.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP5_4">&#167;5.4</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_1">&#167;7.1</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::eq</span><button class="popup" onclick="togglePopup('usagePopup25')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup25">Usage of <span class="code-font"><span class="function-syntax">Str::eq</span></span>:<br/>Debugging Log - <a href="2-dl.html#SP9">&#167;9</a><br/>Dictionaries - <a href="2-dct.html#SP7_3">&#167;7.3</a><br/>Pathnames - <a href="3-pth.html#SP3">&#167;3</a>, <a href="3-pth.html#SP7">&#167;7</a>, <a href="3-pth.html#SP8">&#167;8</a><br/>Filenames - <a href="3-fln.html#SP11">&#167;11</a><br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP4">&#167;4</a>, <a href="4-prp.html#SP10">&#167;10</a>, <a href="4-prp.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP5_4">&#167;5.4</a>, <a href="8-ws.html#SP5_4_1_2">&#167;5.4.1.2</a>, <a href="8-ws.html#SP7_1">&#167;7.1</a><br/>Bibliographic Data for Webs - <a href="8-bdfw.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP20" class="function-link"><span class="function-syntax">Str::cmp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="identifier-syntax">S2</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
@ -555,7 +555,7 @@ for the staff of a publishing house.)
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. White space. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::is_whitespace</span><button class="popup" onclick="togglePopup('usagePopup34')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup34">Usage of <span class="code-font"><span class="function-syntax">Str::is_whitespace</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::is_whitespace</span><button class="popup" onclick="togglePopup('usagePopup34')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup34">Usage of <span class="code-font"><span class="function-syntax">Str::is_whitespace</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP7">&#167;7</a>, <a href="4-prp.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP2" class="function-link"><span class="function-syntax">Characters::is_space_or_tab</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">)) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
@ -566,7 +566,7 @@ for the staff of a publishing house.)
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::trim_white_space</span><button class="popup" onclick="togglePopup('usagePopup35')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup35">Usage of <span class="code-font"><span class="function-syntax">Str::trim_white_space</span></span>:<br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::trim_white_space</span><button class="popup" onclick="togglePopup('usagePopup35')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup35">Usage of <span class="code-font"><span class="function-syntax">Str::trim_white_space</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP12">&#167;12</a><br/>Web Structure - <a href="8-ws.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">len</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">), </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">string_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">Str::start</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
@ -620,11 +620,11 @@ for the staff of a publishing house.)
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. Deleting characters. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::delete_first_character</span><button class="popup" onclick="togglePopup('usagePopup36')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup36">Usage of <span class="code-font"><span class="function-syntax">Str::delete_first_character</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a><br/>Web Structure - <a href="8-ws.html#SP7_3_3">&#167;7.3.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::delete_first_character</span><button class="popup" onclick="togglePopup('usagePopup36')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup36">Usage of <span class="code-font"><span class="function-syntax">Str::delete_first_character</span></span>:<br/><a href="4-sm.html#SP16">&#167;16</a><br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a>, <a href="4-prp.html#SP7_1">&#167;7.1</a><br/>Web Structure - <a href="8-ws.html#SP7_3_3">&#167;7.3.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">Str::delete_nth_character</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::delete_last_character</span><button class="popup" onclick="togglePopup('usagePopup37')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup37">Usage of <span class="code-font"><span class="function-syntax">Str::delete_last_character</span></span>:<br/>Simple Tangler - <a href="8-st.html#SP7_2_4">&#167;7.2.4</a>, <a href="8-st.html#SP7_2_5_2">&#167;7.2.5.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Str::delete_last_character</span><button class="popup" onclick="togglePopup('usagePopup37')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup37">Usage of <span class="code-font"><span class="function-syntax">Str::delete_last_character</span></span>:<br/>Preprocessor - <a href="4-prp.html#SP3_1">&#167;3.1</a><br/>Simple Tangler - <a href="8-st.html#SP7_2_4">&#167;7.2.4</a>, <a href="8-st.html#SP7_2_5_2">&#167;7.2.5.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::truncate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">) - </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
@ -743,7 +743,7 @@ is run just once per I-literal in the source code, when the program starts up.
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-sm.html#SP27">&#167;27</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-ws.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresscurrent">sm</li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-tf.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-ws.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresscurrent">sm</li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-prp.html">prp</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-tf.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -457,7 +457,7 @@ trie in turn until one matches (if it does).
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-tf.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresscurrent">taa</li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-pm.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-prp.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-prp.html">prp</a></li><li class="progresscurrent">taa</li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-pm.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -122,7 +122,7 @@ client.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TextFiles::read</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">TextFiles::read</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>HTML - <a href="5-htm.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">escape_oddities</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">serious</span><span class="plain-syntax">,</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TextFiles::read</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">TextFiles::read</span></span>:<br/>Command Line Arguments - <a href="3-cla.html#SP11">&#167;11</a><br/>Preprocessor - <a href="4-prp.html#SP1">&#167;1</a><br/>HTML - <a href="5-htm.html#SP11">&#167;11</a><br/>Web Structure - <a href="8-ws.html#SP6">&#167;6</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">escape_oddities</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">message</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">serious</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (</span><span class="identifier-syntax">iterator</span><span class="plain-syntax">)(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *),</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">start_at</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">state</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">;</span>
@ -410,7 +410,7 @@ hyphens into em-rules when they are flanked by spaces, and so on.
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="4-tf.html#SP8">&#167;8</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-sm.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresscurrent">tf</li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-taa.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-sm.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresscurrent">tf</li><li class="progresssection"><a href="4-prp.html">prp</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-prp.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -81,7 +81,7 @@ wrappers simply abstract the standard C library's handling.
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="4-cst.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresscurrent">ws</li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-sm.html">&#10095;</a></li></ul></div>
<ul class="progressbar"><li class="progressprev"><a href="4-cst.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresscurrent">ws</li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresssection"><a href="4-prp.html">prp</a></li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-sm.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>

View file

@ -105,7 +105,7 @@ list is entirely sufficient.
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">ebook_datum</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure ebook_datum is accessed in 2/dct, 8/bdfw and here.</li></ul>
<ul class="endnotetexts"><li>The structure ebook_datum is accessed in 2/dct, 4/prp, 8/bdfw and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>As noted above, we use the following to stratify the book:
</p>

View file

@ -67,7 +67,7 @@ convenient to store them directly here than to use a dictionary.
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">web_bibliographic_datum</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure web_bibliographic_datum is accessed in 2/dl, 2/dct, 5/ee and here.</li></ul>
<ul class="endnotetexts"><li>The structure web_bibliographic_datum is accessed in 2/dl, 2/dct, 4/prp, 5/ee and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>We keep these in linked lists, and here's a convenient way to scan them:
</p>

View file

@ -207,6 +207,11 @@
<spon class="sectiontitle">Text Files</span></a> -
<span class="sectionpurpose">To read text files of whatever flavour, one line at a time.</span></p>
</li>
<li>
<p class="sectionentry"><a href="4-prp.html">
<spon class="sectiontitle">Preprocessor</span></a> -
<span class="sectionpurpose">A simple, general-purpose preprocessor for text files, expanding macros and performing repetitions.</span></p>
</li>
<li>
<p class="sectionentry"><a href="4-taa.html">
<spon class="sectiontitle">Tries and Avinues</span></a> -

Binary file not shown.

View file

@ -62,6 +62,7 @@ see <a href="../foundation-module/P-abgtf.html" class="internal">A Brief Guide t
<span class="definition-keyword">enum</span> <span class="constant-syntax">defined_constant_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">enumeration_set_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">footnote_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">gitignore_state_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">hash_table_entry_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">hash_table_entry_usage_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">language_function_CLASS</span>
@ -69,10 +70,7 @@ see <a href="../foundation-module/P-abgtf.html" class="internal">A Brief Guide t
<span class="definition-keyword">enum</span> <span class="constant-syntax">macro_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">macro_tokens_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">macro_usage_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">makefile_macro_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">makefile_macro_parameter_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">makefile_variable_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">makefile_variable_set_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">makefile_specifics_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">nonterminal_variable_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">para_macro_CLASS</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">paragraph_CLASS</span>
@ -156,6 +154,7 @@ see <a href="../foundation-module/P-abgtf.html" class="internal">A Brief Guide t
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">defined_constant</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">enumeration_set</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">footnote</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table_entry_usage</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">language_function</span><span class="plain-syntax">)</span>
@ -163,10 +162,7 @@ see <a href="../foundation-module/P-abgtf.html" class="internal">A Brief Guide t
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">macro_tokens</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">macro_usage</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">macro</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">makefile_macro</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">makefile_macro_parameter</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">makefile_variable</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">makefile_variable_set</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">makefile_specifics</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">nonterminal_variable</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">para_macro</span><span class="plain-syntax">)</span>
<span class="identifier-syntax">DECLARE_CLASS</span><span class="plain-syntax">(</span><span class="reserved-syntax">paragraph_tagging</span><span class="plain-syntax">)</span>

View file

@ -152,7 +152,7 @@ each of which has a list of <span class="extract"><span class="extract-syntax">s
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">web_md</span><span class="plain-syntax"> *</span><span class="function-syntax">Reader::load_web_md</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Reader::load_web_md</span></span>:<br/>Makefiles - <a href="6-mkf.html#SP15_4">&#167;15.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_F</span><span class="plain-syntax">, </span><span class="reserved-syntax">module_search</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="reserved-syntax">web_md</span><span class="plain-syntax"> *</span><span class="function-syntax">Reader::load_web_md</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Reader::load_web_md</span></span>:<br/>Makefiles - <a href="6-mkf.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">alt_F</span><span class="plain-syntax">, </span><span class="reserved-syntax">module_search</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">including_modules</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="../foundation-module/8-ws.html#SP5" class="function-link"><span class="function-syntax">WebMetadata::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">alt_F</span><span class="plain-syntax">, </span><span class="identifier-syntax">default_inweb_syntax</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="plain-syntax">, </span><span class="identifier-syntax">verbose_mode</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">including_modules</span><span class="plain-syntax">, </span><span class="identifier-syntax">path_to_inweb</span><span class="plain-syntax">);</span>

View file

@ -493,9 +493,17 @@ folder: failing that, we fall back on a default script belonging to Inweb.
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::write_gitignore</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Analyser::write_gitignore</span></span>:<br/>Program Control - <a href="1-pc.html#SP7_4_1">&#167;7.4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="function-link"><span class="function-syntax">Filenames::in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">path_to_web</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gitignorescript.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">path_to_web</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">short_name</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-pth.html#SP7" class="function-link"><span class="function-syntax">Pathnames::directory_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="../foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">short_name</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax"> (</span><a href="../foundation-module/4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">short_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"."</span><span class="plain-syntax">)) || (</span><a href="../foundation-module/4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">short_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">".."</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">short_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">I</span><span class="string-syntax">"web"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">, </span><span class="string-syntax">"%S.giscript"</span><span class="plain-syntax">, </span><span class="identifier-syntax">short_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="function-link"><span class="function-syntax">Filenames::in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">leafname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><a href="../foundation-module/4-tf.html#SP1" class="function-link"><span class="function-syntax">TextFiles::exists</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="function-link"><span class="function-syntax">Filenames::in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">path_to_inweb_materials</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gitignorescript.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="function-link"><span class="function-syntax">Filenames::in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">path_to_inweb_materials</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"default.giscript"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="6-gs.html#SP1" class="function-link"><span class="function-syntax">Git::write_gitignore</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>

View file

@ -240,7 +240,7 @@ currently inside.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pl</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure language_reader_state is accessed in 6/mkf and here.</li></ul>
<ul class="endnotetexts"><li>The structure language_reader_state is accessed in 4/prp and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP7_1" class="paragraph-anchor"></a><b>&#167;7.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialise the language to a plain-text state</span><span class="named-paragraph-number">7.1</span></span><span class="comment-syntax"> =</span>
</p>

View file

@ -109,7 +109,7 @@ directory holding a multi-section web.
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">colony_member</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure colony_member is accessed in 2/trs, 1/cnf, 1/ts, 3/tc, 5/wt, 6/mkf, 6/cs, 6/rw and here.</li></ul>
<ul class="endnotetexts"><li>The structure colony_member is accessed in 2/trs, 4/prp, 1/cnf, 1/ts, 3/tc, 5/wt, 6/cs, 6/rw and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>And the following reads a colony file <span class="extract"><span class="extract-syntax">F</span></span> and produces a suitable <span class="extract"><span class="extract-syntax">colony</span></span>
object from it. This, for example, is the colony file for the Inweb repository
at GitHub:

View file

@ -261,7 +261,7 @@ memory is cheap. It's easier to keep a duplicate list.
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">defined_constant</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure defined_constant is accessed in 2/trs, 1/apacs, 5/wt, 6/mkf, 6/rw, 6/cln and here.</li></ul>
<ul class="endnotetexts"><li>The structure defined_constant is accessed in 2/trs, 4/prp, 1/apacs, 5/wt, 6/rw, 6/cln and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. </b>This is called for any <span class="extract"><span class="extract-syntax">@d</span></span> or <span class="extract"><span class="extract-syntax">@e</span></span> constant name, then:
</p>

View file

@ -50,73 +50,38 @@ function togglePopup(material_id) {
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">inweb</a></li><li><a href="index.html#6">Chapter 6: Extras</a></li><li><b>Git Support</b></li></ul></div>
<p class="purpose">Constructing a suitable gitignore file for a simple inweb project.</p>
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>This section offers just one function, which constructs a <span class="extract"><span class="extract-syntax">.gitignore</span></span>
file by following a "prototype".
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>This is an extremely simple use of <a href="../foundation-module/4-prp.html" class="internal">Preprocessor (in foundation)</a>.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">for_web</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">to_gitignore</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_line_was_blank</span><span class="plain-syntax">; </span><span class="comment-syntax"> used to suppress runs of multiple blank lines</span>
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Git::write_gitignore</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Git::write_gitignore</span></span>:<br/>Program Control - <a href="1-pc.html#SP7_1">&#167;7.1</a><br/>The Analyser - <a href="3-ta.html#SP13">&#167;13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">MS</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">MS</span><span class="plain-syntax">.</span><span class="element-syntax">for_web</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">MS</span><span class="plain-syntax">.</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">MS</span><span class="plain-syntax">.</span><span class="element-syntax">to_gitignore</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">STREAM_OPEN_TO_FILE</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="constant-syntax">ISO_ENC</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="../foundation-module/3-em.html#SP2" class="function-link"><span class="function-syntax">Errors::fatal_with_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"unable to write tangled file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"# This gitignore was automatically written by inweb -gitignore\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"# and is not intended for human editing\n\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-tf.html#SP5" class="function-link"><span class="function-syntax">TextFiles::read</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open prototype file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">, </span><a href="6-gs.html#SP2" class="function-link"><span class="function-syntax">Git::copy_gitignore_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">MS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">STREAM_CLOSE</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"Wrote gitignore file '%f' from script '%f'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-prp.html#SP9" class="function-link"><span class="function-syntax">Preprocessor::reserve_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"basics"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><a href="6-gs.html#SP1" class="function-link"><span class="function-syntax">Git::basics_expander</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">specifics</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">for_web</span><span class="plain-syntax"> = </span><span class="identifier-syntax">W</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">header</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">header</span><span class="plain-syntax">, </span><span class="string-syntax">"# This gitignore was automatically written by inweb -gitignore\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">header</span><span class="plain-syntax">, </span><span class="string-syntax">"# and is not intended for human editing\n\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"(Read script from %f)\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-prp.html#SP1" class="function-link"><span class="function-syntax">Preprocessor::preprocess</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="identifier-syntax">header</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">STORE_POINTER_gitignore_state</span><span class="plain-syntax">(</span><span class="identifier-syntax">specifics</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Git::basics_expander</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">rep</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="function-link"><span class="function-syntax">Filenames::in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">path_to_inweb_materials</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"default.giscript"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-tf.html#SP5" class="function-link"><span class="function-syntax">TextFiles::read</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open basic .gitignore file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">, </span><a href="../foundation-module/4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"(Read basics.giscript from inweb/"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/3-pth.html#SP7" class="function-link"><span class="function-syntax">Pathnames::to_text_relative</span></a><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="identifier-syntax">path_to_inweb</span><span class="plain-syntax">, </span><span class="identifier-syntax">path_to_inweb_materials</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">")\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure gitignore_state is accessed in 3/tc, 6/mkf and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Git::copy_gitignore_line</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Git::copy_gitignore_line</span></span>:<br/><a href="6-gs.html#SP1">&#167;1</a>, <a href="6-gs.html#SP2_1">&#167;2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">MS</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">gitignore_state</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">X</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = &amp;(</span><span class="identifier-syntax">MS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">to_gitignore</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *#%c*"</span><span class="plain-syntax">)) { </span><a href="../foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *{basics} *"</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="6-gs.html#SP2_1" class="named-paragraph-link"><span class="named-paragraph">Expand basics</span><span class="named-paragraph-number">2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="6-gs.html#SP2_2" class="named-paragraph-link"><span class="named-paragraph">And otherwise copy the line straight through</span><span class="named-paragraph-number">2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2_1" class="paragraph-anchor"></a><b>&#167;2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand basics</span><span class="named-paragraph-number">2.1</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="../foundation-module/3-fln.html#SP2" class="function-link"><span class="function-syntax">Filenames::in</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">path_to_inweb_materials</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gitignorescript.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-tf.html#SP5" class="function-link"><span class="function-syntax">TextFiles::read</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open make settings file"</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">, </span><a href="6-gs.html#SP2" class="function-link"><span class="function-syntax">Git::copy_gitignore_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">MS</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="../foundation-module/4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-gs.html#SP2">&#167;2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2_2" class="paragraph-anchor"></a><b>&#167;2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">And otherwise copy the line straight through</span><span class="named-paragraph-number">2.2</span></span><span class="comment-syntax"> =</span>
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">MS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">MS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">MS</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="6-gs.html#SP2">&#167;2</a>.</li></ul>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="6-mkf.html">&#10094;</a></li><li class="progresschapter"><a href="M-iti.html">M</a></li><li class="progresschapter"><a href="P-htpw.html">P</a></li><li class="progresschapter"><a href="1-bsc.html">1</a></li><li class="progresschapter"><a href="2-tr.html">2</a></li><li class="progresschapter"><a href="3-ta.html">3</a></li><li class="progresschapter"><a href="4-pl.html">4</a></li><li class="progresschapter"><a href="5-wt.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresssection"><a href="6-mkf.html">mkf</a></li><li class="progresscurrent">gs</li><li class="progresssection"><a href="6-cs.html">cs</a></li><li class="progresssection"><a href="6-rw.html">rw</a></li><li class="progresssection"><a href="6-cln.html">cln</a></li><li class="progressnext"><a href="6-cs.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->

File diff suppressed because it is too large Load diff

View file

@ -87,7 +87,7 @@ uses these extra macros, is expanded to the final file, which does not.
<span class="plain-syntax"> </span><a href="../foundation-module/2-str.html#SP34" class="function-link"><span class="function-syntax">Streams::close</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">file_to</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure write_state is accessed in 1/apacs, 5/ptf, 5/tf, 5/hf, 5/df, 6/mkf and here.</li></ul>
<ul class="endnotetexts"><li>The structure write_state is accessed in 4/prp, 1/apacs, 5/ptf, 5/tf, 5/hf, 5/df and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The file consists of definitions of macros, made one at a time, and
starting with <span class="extract"><span class="extract-syntax">@define</span></span> and finishing with <span class="extract"><span class="extract-syntax">@end</span></span>, and actual material.
</p>
@ -149,7 +149,7 @@ parameters.
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">macro_tokens</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure macro is accessed in 2/trs, 3/twot, 5/wt, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df, 6/mkf, 6/cs, 6/cln and here.</li><li>The structure macro_tokens is private to this section.</li></ul>
<ul class="endnotetexts"><li>The structure macro is accessed in 2/trs, 4/prp, 3/twot, 5/wt, 5/fm, 5/ptf, 5/tf, 5/hf, 5/df, 6/cs, 6/cln and here.</li><li>The structure macro_tokens is private to this section.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b></p>
<pre class="displayed-code all-displayed-code code-font">
@ -344,7 +344,7 @@ assume that the version complies with any format).
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">datum</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"Version Number"</span><span class="plain-syntax">)) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">version</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure writeme_asset is accessed in 2/trs, 5/wt, 6/mkf, 6/cs, 6/cln and here.</li></ul>
<ul class="endnotetexts"><li>The structure writeme_asset is accessed in 2/trs, 4/prp, 5/wt, 6/cs, 6/cln and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. </b>That just leaves the business of inspecting assets to obtain their metadata.
</p>

View file

@ -12,6 +12,11 @@
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="../docs-assets/Bigfoot.js"></script>
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/ConsoleText-Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
@ -43,7 +48,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">inweb</a></li><li><a href="index.html#M">Manual</a></li><li><b>Webs, Tangling and Weaving</b></li></ul></div>
<p class="purpose">How to use Inweb to weave or tangle a web already written.</p>
<ul class="toc"><li><a href="M-wtaw.html#SP1">&#167;1. All-in-one webs</a></li><li><a href="M-wtaw.html#SP4">&#167;4. Multi-section webs</a></li><li><a href="M-wtaw.html#SP7">&#167;7. Tangling</a></li><li><a href="M-wtaw.html#SP10">&#167;10. Weaving</a></li><li><a href="M-wtaw.html#SP13">&#167;13. Weave tags</a></li><li><a href="M-wtaw.html#SP14">&#167;14. Modules</a></li><li><a href="M-wtaw.html#SP17">&#167;17. The section catalogue</a></li><li><a href="M-wtaw.html#SP18">&#167;18. Makefile</a></li><li><a href="M-wtaw.html#SP19">&#167;19. Gitignore</a></li><li><a href="M-wtaw.html#SP20">&#167;20. Ctags</a></li><li><a href="M-wtaw.html#SP21">&#167;21. README files</a></li><li><a href="M-wtaw.html#SP24">&#167;24. Semantic version numbering and build metadata</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="M-wtaw.html#SP1">&#167;1. All-in-one webs</a></li><li><a href="M-wtaw.html#SP4">&#167;4. Multi-section webs</a></li><li><a href="M-wtaw.html#SP7">&#167;7. Tangling</a></li><li><a href="M-wtaw.html#SP10">&#167;10. Weaving</a></li><li><a href="M-wtaw.html#SP13">&#167;13. Weave tags</a></li><li><a href="M-wtaw.html#SP14">&#167;14. Modules</a></li><li><a href="M-wtaw.html#SP17">&#167;17. The section catalogue</a></li><li><a href="M-wtaw.html#SP18">&#167;18. Makefile</a></li><li><a href="M-wtaw.html#SP25">&#167;25. Gitignore</a></li><li><a href="M-wtaw.html#SP26">&#167;26. Ctags</a></li><li><a href="M-wtaw.html#SP27">&#167;27. README files</a></li><li><a href="M-wtaw.html#SP30">&#167;30. Semantic version numbering and build metadata</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. All-in-one webs. </b>A program written for use with Inweb is called a "web". Inweb was primarily
designed for large, multisection webs, but it can also be used in a much
@ -613,25 +618,176 @@ Ordinarily the script used will be the one stored in
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> W/makescript.txt</span>
<span class="plain-syntax"> W/W.mkscript</span>
</pre>
<p class="commentary">or, if no such file exists, the default one stored in Inweb:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> inweb/Materials/makescript.txt</span>
<span class="plain-syntax"> inweb/Materials/default.mkscript</span>
</pre>
<p class="commentary">but this can be changed by using <span class="extract"><span class="extract-syntax">-prototype S</span></span>, which tells Inweb to use
<span class="extract"><span class="extract-syntax">S</span></span> as the script. If a <span class="extract"><span class="extract-syntax">-prototype</span></span> is given, then there's no need to
specify any one web for Inweb to use: this allows Inweb to construct more
elaborate makefiles for multi-web projects. (This is how the main makefile
for the Inform project is constructed.)
elaborate makefiles for multi-web projects.
</p>
<p class="commentary">To see how makescripts work, it's easiest simply to look at the default one.
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b>A makescript is really just copied out to produce the makefile, except that:
</p>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Gitignore. </b>A similar convenience exists for users who want to use the git source control
<ul class="items"><li>&#9679; Comment lines, those beginning with <span class="extract"><span class="extract-syntax">#</span></span>, are stripped out.
</li><li>&#9679; Material in balanced braces <span class="extract"><span class="extract-syntax">{ ... }</span></span> is expanded into something more
interesting.
</li></ul>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. </b>Makescripts support variables, whose names have to be in capital letters,
perhaps with underscores and digits added. For example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">{set name: SUPPORTED_BUILDS value: 6L02, 6L38, 6M62}</span>
<span class="plain-syntax">...</span>
<span class="plain-syntax"> echo "I support any of {SUPPORTED_BUILDS}."</span>
</pre>
<p class="commentary">expands to
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> echo "I support any of 6L02, 6L38, 6M62."</span>
</pre>
<p class="commentary">What happens is that the <span class="extract"><span class="extract-syntax">set</span></span> macro sets the variable <span class="extract"><span class="extract-syntax">SUPPORTED_BUILDS</span></span> and
gives it the value <span class="extract"><span class="extract-syntax">6L02, 6L38, 6M62</span></span>. Anywhere below this in the file,<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
<span class="extract"><span class="extract-syntax">{SUPPORTED_BUILDS}</span></span> is replaced by that value.
</p>
<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> If you set a variable inside a repeat loop, it will exist only in the loop.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li></ul>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b>Makescripts support repetition. For example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">{repeat with: BUILD in: 6L02, 6L38, 6M62}</span>
<span class="plain-syntax"> echo "I support {BUILD}."</span>
<span class="plain-syntax">{end-repeat}</span>
</pre>
<p class="commentary">produces:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> echo "I support 6L02."</span>
<span class="plain-syntax"> echo "I support 6L38."</span>
<span class="plain-syntax"> echo "I support 6M62."</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>Like <span class="extract"><span class="extract-syntax">set</span></span>, <span class="extract"><span class="extract-syntax">repeat</span></span> is a "macro". This has two parameters, <span class="extract"><span class="extract-syntax">with:</span></span>, naming
the loop variable, and <span class="extract"><span class="extract-syntax">in:</span></span>, giving a comma-separated list of values for it
to run through in order. In some macros parameters are optional, but not these.
</p>
<p class="commentary">Note that variables can be used within the parameters of macros, as in this example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">{repeat with: BUILD in: {SUPPORTED_BUILDS}}</span>
<span class="plain-syntax"> echo "I support {BUILD}."</span>
<span class="plain-syntax">{end-repeat}</span>
</pre>
<p class="commentary">Loops can be nested, for those who like to live on the edge. So:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">{repeat with: X in: alpha, beta, gamma}</span>
<span class="plain-syntax">{repeat with: Y in: 5, 11}</span>
<span class="plain-syntax"> echo "Greetings, Agent {X}-{Y}."</span>
<span class="plain-syntax">{end-repeat}</span>
<span class="plain-syntax">{end-repeat}</span>
</pre>
<p class="commentary">produces:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> echo "Greetings, Agent alpha-5."</span>
<span class="plain-syntax"> echo "Greetings, Agent alpha-11."</span>
<span class="plain-syntax"> echo "Greetings, Agent beta-5."</span>
<span class="plain-syntax"> echo "Greetings, Agent beta-11."</span>
<span class="plain-syntax"> echo "Greetings, Agent gamma-5."</span>
<span class="plain-syntax"> echo "Greetings, Agent gamma-11."</span>
</pre>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>You can also define your own macros, as in this example:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">{define: link to: TO from: FROM ?options: OPTS}</span>
<span class="plain-syntax"> clang $(CCOPTS) -g -o {TO} {FROM} {OPTS}</span>
<span class="plain-syntax">{end-define}</span>
</pre>
<p class="commentary">And here is a usage of it:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> {link from: frog.o to: frog.c}</span>
</pre>
<p class="commentary">This doesn't specify "options: ...", but doesn't have to, because that's optional &mdash;
note the question mark in the macro declaration. But it does specify "from: ..."
and "to: ...", which are compulsory. Parameters are always named, as this example
suggests, and can be given in any order so long as all the non-optional ones are
present.
</p>
<p class="commentary">This usage results in the following line in the final makefile:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax"> clang $(CCOPTS) -g -o frog.c frog.o</span>
</pre>
<p class="commentary">Note the difference between <span class="extract"><span class="extract-syntax">$(CCOPTS)</span></span>, which is a make variable, and the braced
tokens <span class="extract"><span class="extract-syntax">{TO}</span></span>, <span class="extract"><span class="extract-syntax">{FROM}</span></span> and <span class="extract"><span class="extract-syntax">{OPTS}</span></span>, which are makescript variables (which exist
only inside the definition).
</p>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b>A few more built-in macros special to makefiles may be useful:
</p>
<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">{platform-settings}</span></span> (which has no parameters) includes a file of makescript
material useful for compiling C-based tools on your current operating system or
"platform". It gets this file at <span class="extract"><span class="extract-syntax">inweb/Materials/platforms/YOURPLATFORM.mkscript</span></span>,
where <span class="extract"><span class="extract-syntax">YOURPLATFORM</span></span> may be <span class="extract"><span class="extract-syntax">macos</span></span>, <span class="extract"><span class="extract-syntax">windows</span></span>, <span class="extract"><span class="extract-syntax">linux</span></span> and so on.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">{identity-settings}</span></span> (which has no parameters) writes out make declarations
for make variables <span class="extract"><span class="extract-syntax">INWEB</span></span>, <span class="extract"><span class="extract-syntax">INTEST</span></span>, <span class="extract"><span class="extract-syntax">MYNAME</span></span> and <span class="extract"><span class="extract-syntax">ME</span></span>. The first two are paths
to the inweb and intest tools respectivly. <span class="extract"><span class="extract-syntax">MYNAME</span></span> and <span class="extract"><span class="extract-syntax">ME</span></span> are set only if
inweb has been given a specific web <span class="extract"><span class="extract-syntax">W</span></span> to work with at the command line, and
are then expanded to the directory name and web name respectively for <span class="extract"><span class="extract-syntax">W</span></span>. (These
are very often the same name, e.g., <span class="extract"><span class="extract-syntax">inform7</span></span>.)
</li><li>&#9679; <span class="extract"><span class="extract-syntax">{component symbol: SYMBOL webname: WEBNAME path: PATH set: SET type: TYPE}</span></span>
is used only in a makescript for a makefile trying to orchestrate complicated
operations on colonies of large numbers of webs. (See the <span class="extract"><span class="extract-syntax">inform.mkscript</span></span>
script in the main Inform repository for an example.) This macro says that one
of the webs it will talk about is called <span class="extract"><span class="extract-syntax">WEBNAME</span></span>, located at <span class="extract"><span class="extract-syntax">PATH</span></span> in the
file system, belongs to a set you want to call <span class="extract"><span class="extract-syntax">SET</span></span>, has the <span class="extract"><span class="extract-syntax">TYPE</span></span> of one
of <span class="extract"><span class="extract-syntax">tool</span></span>, <span class="extract"><span class="extract-syntax">web</span></span> or <span class="extract"><span class="extract-syntax">module</span></span>. (A <span class="extract"><span class="extract-syntax">tool</span></span> is the main web for an executable;
a <span class="extract"><span class="extract-syntax">module</span></span> for one of the modules making up an executable; a <span class="extract"><span class="extract-syntax">web</span></span> for some
other kind of resource tangled by Inweb but which doesn't make an executable.)
</li><li>&#9679; <span class="extract"><span class="extract-syntax">{dependent-files tool: WEBNAME}</span></span> then expands to a list of source files
inside the web <span class="extract"><span class="extract-syntax">WEBNAME</span></span> on which its tangled output depends, written in the
usual make-file way, i.e., divided by spaces. <span class="extract"><span class="extract-syntax">WEBNAME</span></span> has to be one which
has already been declared as having <span class="extract"><span class="extract-syntax">type: tool</span></span> in a <span class="extract"><span class="extract-syntax">{component ...}</span></span> line.
</li><li>&#9679; And similarly <span class="extract"><span class="extract-syntax">{dependent-files module: WEBNAME}</span></span>.
</li><li>&#9679; More elaborately, <span class="extract"><span class="extract-syntax">{dependent-files tool-and-modules: WEBNAME}</span></span> lists the
dependent files not only in the main web for a tool, which also in any of the
modules which it includes.
</li><li>&#9679; A form of loop, <span class="extract"><span class="extract-syntax">{components type: TYPE set: SET} ... {end-components}</span></span>
repeats through all the declared components with the given type and set. (The
set is optional: if not given, the repetition is over everything with that type.)
As before, <span class="extract"><span class="extract-syntax">TYPE</span></span> must be one of <span class="extract"><span class="extract-syntax">tool</span></span>, <span class="extract"><span class="extract-syntax">web</span></span> or <span class="extract"><span class="extract-syntax">module</span></span>. Inside the loop,
<span class="extract"><span class="extract-syntax">{NAME}</span></span> expands to the <span class="extract"><span class="extract-syntax">SYMBOL</span></span> which the component was declared with. For
example:
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">.PHONY: versions</span>
<span class="plain-syntax">versions:</span>
<span class="plain-syntax"> {components type: tool}</span>
<span class="plain-syntax"> $({SYMBOL}X) -version</span>
<span class="plain-syntax"> {end-components}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. Gitignore. </b>A similar convenience exists for users who want to use the git source control
tool with a web: for example, uploading it to Github.
</p>
@ -644,11 +800,18 @@ specifies the files to be ignored. The following does so for a web <span class="
<pre class="ConsoleText-displayed-code all-displayed-code code-font">
<span class="ConsoleText-plain-syntax"> </span><span class="ConsoleText-element-syntax">$</span><span class="ConsoleText-plain-syntax"> </span><span class="ConsoleText-function-syntax">inweb/Tangled/inweb</span><span class="ConsoleText-plain-syntax"> W</span><span class="ConsoleText-identifier-syntax"> -gitignore</span><span class="ConsoleText-plain-syntax"> W/.gitignore</span>
</pre>
<p class="commentary">Once again, Inweb does this by working from a script, this time called
<span class="extract"><span class="ConsoleText-extract-syntax">gitignorescript.txt</span></span>.
<p class="commentary">Once again, Inweb does this by working from a script, and the rules are almost
exactly the same as for makefiles except that the file extension is <span class="extract"><span class="ConsoleText-extract-syntax">.giscript</span></span>,
not <span class="extract"><span class="ConsoleText-extract-syntax">.mkscript</span></span>, and:
</p>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Ctags. </b>Each time a web is tangled, Inweb writes a <span class="extract"><span class="ConsoleText-extract-syntax">tags</span></span> file to the web's home
<ul class="items"><li>&#9679; The special makefile macros are not available, though <span class="extract"><span class="ConsoleText-extract-syntax">set</span></span> and <span class="extract"><span class="ConsoleText-extract-syntax">repeat</span></span> are;
</li><li>&#9679; The special macro <span class="extract"><span class="ConsoleText-extract-syntax">{basics}</span></span> expands to the contents of the file
<span class="extract"><span class="ConsoleText-extract-syntax">inweb/Materials/default.giscript</span></span>. This does the same thing as would be done
if the web provided no script of its own; the idea is that you can then list
some additional things to ignore.
</li></ul>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. Ctags. </b>Each time a web is tangled, Inweb writes a <span class="extract"><span class="ConsoleText-extract-syntax">tags</span></span> file to the web's home
directory, containing a list of <a href="https://ctags.io" class="external">Universal ctags</a>
for any structures, functions or constant definitions found in the web. You
need do nothing to make this happen, and can ignore the file if it's of no
@ -669,7 +832,7 @@ should make code completion and definition lookup features work.
<pre class="ConsoleText-displayed-code all-displayed-code code-font">
<span class="ConsoleText-plain-syntax"> </span><span class="ConsoleText-element-syntax">$</span><span class="ConsoleText-plain-syntax"> </span><span class="ConsoleText-function-syntax">inweb/Tangled/inweb</span><span class="ConsoleText-plain-syntax"> W</span><span class="ConsoleText-identifier-syntax"> -tangle -no-ctags</span>
</pre>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. README files. </b>Repositories at Github customarily have <span class="extract"><span class="ConsoleText-extract-syntax">README.mk</span></span> files, in Markdown
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. README files. </b>Repositories at Github customarily have <span class="extract"><span class="ConsoleText-extract-syntax">README.mk</span></span> files, in Markdown
syntax, explaining what they are. These of course should probably include
current version numbers, and it's a pain keeping that up to date. For
really complicated repositories, containing multiple webs, some automation
@ -686,7 +849,7 @@ the script can be specified explicitly:
<pre class="ConsoleText-displayed-code all-displayed-code code-font">
<span class="ConsoleText-plain-syntax"> </span><span class="ConsoleText-element-syntax">$</span><span class="ConsoleText-plain-syntax"> </span><span class="ConsoleText-function-syntax">inweb/Tangled/inweb</span><span class="ConsoleText-plain-syntax"> W</span><span class="ConsoleText-identifier-syntax"> -prototype</span><span class="ConsoleText-plain-syntax"> MySpecialThang.txt</span><span class="ConsoleText-identifier-syntax"> -write-me</span><span class="ConsoleText-plain-syntax"> W/README.mk</span>
</pre>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>Everything in the script is copied over verbatim except where the <span class="extract"><span class="ConsoleText-extract-syntax">@</span></span> character
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. </b>Everything in the script is copied over verbatim except where the <span class="extract"><span class="ConsoleText-extract-syntax">@</span></span> character
is used, which was chosen because it isn't significant in Github's form of
Markdown. <span class="extract"><span class="ConsoleText-extract-syntax">@name(args)</span></span> is like a function call (or, in more traditional
language, a macro): it expands out to something depending on the arguments.
@ -708,7 +871,7 @@ the web indicated by <span class="extract"><span class="ConsoleText-extract-synt
<span class="extract"><span class="ConsoleText-extract-syntax">@var(A,Version Number)</span></span> and <span class="extract"><span class="ConsoleText-extract-syntax">@purpose(A)</span></span> for <span class="extract"><span class="ConsoleText-extract-syntax">@var(A,Purpose)</span></span>, so this
is really the only one needed.
</li></ul>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>It is also possible to define new functions. For example:
<p class="commentary firstcommentary"><a id="SP29" class="paragraph-anchor"></a><b>&#167;29. </b>It is also possible to define new functions. For example:
</p>
<pre class="displayed-code all-displayed-code code-font">
@ -733,7 +896,7 @@ function <span class="extract"><span class="extract-syntax">B</span></span> not
both <span class="extract"><span class="extract-syntax">A</span></span> and <span class="extract"><span class="extract-syntax">B</span></span> have been defined. So, basically, declare before use.
</p>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. Semantic version numbering and build metadata. </b>When Inweb reads in a web, it also looks for a file called <span class="extract"><span class="extract-syntax">build.txt</span></span> in
<p class="commentary firstcommentary"><a id="SP30" class="paragraph-anchor"></a><b>&#167;30. Semantic version numbering and build metadata. </b>When Inweb reads in a web, it also looks for a file called <span class="extract"><span class="extract-syntax">build.txt</span></span> in
the web's directory; if that isn't there, it looks for the same file in the
current working directory; if that's not there either, never mind.
</p>
@ -766,7 +929,7 @@ the web as the variable <span class="extract"><span class="extract-syntax">Seman
<p class="commentary">For more on semvers, see: <a href="https://semver.org" class="external">https://semver.org</a>
</p>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b>A special advancing mechanism exists to update build numbers and dates.
<p class="commentary firstcommentary"><a id="SP31" class="paragraph-anchor"></a><b>&#167;31. </b>A special advancing mechanism exists to update build numbers and dates.
Running Inweb with <span class="extract"><span class="extract-syntax">-advance-build W</span></span> checks the build date for web <span class="extract"><span class="extract-syntax">W</span></span>:
if it differs from today, then it is changed to today, and the build code
is advanced by one.

View file

@ -33,6 +33,10 @@ here we are.
@e module_CLASS
@e module_search_CLASS
@e pathname_CLASS
@e preprocessor_macro_CLASS
@e preprocessor_macro_parameter_CLASS
@e preprocessor_variable_CLASS
@e preprocessor_variable_set_CLASS
@e scan_directory_CLASS
@e section_md_CLASS
@e semantic_version_number_holder_CLASS
@ -67,6 +71,10 @@ DECLARE_CLASS(method)
DECLARE_CLASS(module_search)
DECLARE_CLASS(module)
DECLARE_CLASS(pathname)
DECLARE_CLASS(preprocessor_macro)
DECLARE_CLASS(preprocessor_macro_parameter)
DECLARE_CLASS(preprocessor_variable)
DECLARE_CLASS(preprocessor_variable_set)
DECLARE_CLASS(scan_directory)
DECLARE_CLASS(section_md)
DECLARE_CLASS(semantic_version_number_holder)

View file

@ -0,0 +1,605 @@
[Preprocessor::] Preprocessor.
A simple, general-purpose preprocessor for text files, expanding macros and
performing repetitions.
@h State.
@d MAX_PREPROCESSOR_LOOP_DEPTH 8
=
typedef struct preprocessor_loop {
struct text_stream *loop_var_name;
struct linked_list *iterations; /* of |text_stream| */
int repeat_is_block;
struct text_stream *repeat_saved_dest;
} preprocessor_loop;
typedef struct preprocessor_state {
struct text_stream *dest;
struct preprocessor_macro *defining; /* a "define" body being scanned */
int repeat_sp;
int shadow_sp;
struct preprocessor_loop repeat_data[MAX_PREPROCESSOR_LOOP_DEPTH];
int suppress_newline; /* at the end of this line */
int last_line_was_blank; /* used to suppress runs of multiple blank lines */
struct preprocessor_variable_set *global_variables;
struct preprocessor_variable_set *stack_frame;
struct linked_list *known_macros; /* of |preprocessor_macro| */
struct general_pointer specifics;
} preprocessor_state;
void Preprocessor::preprocess(filename *prototype, filename *F, text_stream *header,
linked_list *special_macros, general_pointer specifics) {
struct text_stream processed_file;
if (STREAM_OPEN_TO_FILE(&processed_file, F, ISO_ENC) == FALSE)
Errors::fatal_with_file("unable to write tangled file", F);
text_stream *OUT = &processed_file;
WRITE("%S", header);
preprocessor_state PPS;
PPS.dest = OUT;
PPS.suppress_newline = FALSE;
PPS.last_line_was_blank = TRUE;
PPS.defining = NULL;
PPS.repeat_sp = 0;
PPS.shadow_sp = 0;
PPS.global_variables = Preprocessor::new_variable_set(NULL);
PPS.stack_frame = PPS.global_variables;
PPS.known_macros = Preprocessor::list_of_reserved_macros(special_macros);
PPS.specifics = specifics;
TextFiles::read(prototype, FALSE, "can't open prototype file",
TRUE, Preprocessor::scan_line, NULL, &PPS);
STREAM_CLOSE(OUT);
}
@h Scanner.
=
void Preprocessor::scan_line(text_stream *line, text_file_position *tfp, void *X) {
preprocessor_state *PPS = (preprocessor_state *) X;
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, line, L" *#%c*")) { Regexp::dispose_of(&mr); return; } // Skip comment lines
if (Regexp::match(&mr, line, L" *{define: *(%C+) (%c*)} *")) @<Begin a definition@>;
if (Regexp::match(&mr, line, L" *{end-define} *")) @<End a definition@>;
if (PPS->defining) @<Continue a definition@>;
Regexp::dispose_of(&mr);
Preprocessor::expand(line, tfp, PPS);
if (PPS->suppress_newline == FALSE) {
text_stream *OUT = PPS->dest;
if (Str::len(line) == 0) {
if (PPS->last_line_was_blank == FALSE) WRITE("\n");
PPS->last_line_was_blank = TRUE;
} else {
PPS->last_line_was_blank = FALSE;
WRITE("\n");
}
}
PPS->suppress_newline = FALSE;
}
@<Begin a definition@> =
if (PPS->defining)
Errors::in_text_file("nested definitions are not allowed", tfp);
text_stream *name = mr.exp[0];
text_stream *parameter_specification = mr.exp[1];
PPS->defining = Preprocessor::new_macro(PPS->known_macros, name, parameter_specification, tfp, Preprocessor::default_expander);
Regexp::dispose_of(&mr);
return;
@<Continue a definition@> =
Preprocessor::add_line_to_macro(PPS->defining, line, tfp);
Regexp::dispose_of(&mr);
return;
@<End a definition@> =
if (PPS->defining == NULL)
Errors::in_text_file("{end-define} without {define: ...}", tfp);
PPS->defining = NULL;
Regexp::dispose_of(&mr);
return;
@ =
void Preprocessor::expand(text_stream *text, text_file_position *tfp, preprocessor_state *PPS) {
TEMPORARY_TEXT(before_matter)
TEMPORARY_TEXT(braced_matter)
TEMPORARY_TEXT(after_matter)
int bl = 0, after_times = FALSE;
for (int i = 0; i < Str::len(text); i++) {
wchar_t c = Str::get_at(text, i);
if (after_times) PUT_TO(after_matter, c);
else if (c == '{') {
bl++;
if (bl > 1) PUT_TO(braced_matter, c);
} else if (c == '}') {
bl--;
if (bl == 0) after_times = TRUE;
else PUT_TO(braced_matter, c);
} else {
if (bl < 0) Errors::in_text_file("too many '}'s", tfp);
if (bl == 0) PUT_TO(before_matter, c);
else PUT_TO(braced_matter, c);
}
}
if (bl > 0) Errors::in_text_file("too many '{'s", tfp);
if (after_times) {
@<Expand a macro@>;
} else {
WRITE_TO(PPS->dest, "%S", text);
}
DISCARD_TEXT(before_matter)
DISCARD_TEXT(braced_matter)
DISCARD_TEXT(after_matter)
}
@<Expand a macro@> =
text_stream *identifier = braced_matter;
text_stream *parameter_settings = NULL;
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, identifier, L"(%C+) (%c*)")) {
identifier = mr.exp[0];
parameter_settings = mr.exp[1];
}
preprocessor_macro *loop_mm;
LOOP_OVER_LINKED_LIST(loop_mm, preprocessor_macro, PPS->known_macros)
if (Str::len(loop_mm->loop_name) > 0) {
if (Str::eq(identifier, loop_mm->loop_name)) {
if (Str::is_whitespace(after_matter)) {
if ((loop_mm->span == FALSE) && (loop_mm->begins_repeat)) identifier = loop_mm->identifier;
} else {
if ((loop_mm->span) && (loop_mm->begins_repeat)) identifier = loop_mm->identifier;
}
}
TEMPORARY_TEXT(end_name)
WRITE_TO(end_name, "end-%S", loop_mm->loop_name);
if (Str::eq(identifier, end_name)) {
if ((PPS->repeat_sp > 0) && (PPS->repeat_data[PPS->repeat_sp-1].repeat_is_block)) {
if ((loop_mm->span == FALSE) && (loop_mm->ends_repeat)) identifier = loop_mm->identifier;
} else {
if ((loop_mm->span) && (loop_mm->ends_repeat)) identifier = loop_mm->identifier;
}
}
DISCARD_TEXT(end_name)
}
if (Preprocessor::acceptable_variable_name(identifier)) {
Preprocessor::expand(before_matter, tfp, PPS);
if (PPS->repeat_sp > 0) {
WRITE_TO(PPS->dest, "{%S}", identifier);
} else {
preprocessor_variable *var = Preprocessor::find_variable_in(identifier, PPS->stack_frame);
if (var) {
WRITE_TO(PPS->dest, "%S", var->value);
} else {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown variable '%S'", identifier);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
}
Preprocessor::expand(after_matter, tfp, PPS);
} else {
preprocessor_macro *mm = Preprocessor::find_macro(PPS->known_macros, identifier);
if (mm == NULL) {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown macro '%S'", identifier);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
} else {
if (mm->suppress_whitespace_when_expanding) {
while (Characters::is_whitespace(Str::get_last_char(before_matter)))
Str::delete_last_character(before_matter);
while (Characters::is_whitespace(Str::get_first_char(after_matter)))
Str::delete_first_character(after_matter);
}
Preprocessor::expand(before_matter, tfp, PPS);
int divert_if_repeating = TRUE;
if ((mm) && (mm->begins_repeat)) {
PPS->shadow_sp++;
}
if ((mm) && (mm->ends_repeat)) {
PPS->shadow_sp--;
if (PPS->shadow_sp == 0) divert_if_repeating = FALSE;
}
if ((divert_if_repeating) && (PPS->repeat_sp > 0)) {
WRITE_TO(PPS->dest, "{%S}", braced_matter);
} else {
Preprocessor::expand_macro(PPS, mm, parameter_settings, tfp);
if (mm->suppress_newline_after_expanding) PPS->suppress_newline = TRUE;
}
Preprocessor::expand(after_matter, tfp, PPS);
}
}
Regexp::dispose_of(&mr);
@h Variables.
=
typedef struct preprocessor_variable {
struct text_stream *name;
struct text_stream *value;
CLASS_DEFINITION
} preprocessor_variable;
typedef struct preprocessor_variable_set {
struct linked_list *variables; /* of |preprocessor_variable| */
struct preprocessor_variable_set *outer;
CLASS_DEFINITION
} preprocessor_variable_set;
preprocessor_variable_set *Preprocessor::new_variable_set(preprocessor_variable_set *outer) {
preprocessor_variable_set *set = CREATE(preprocessor_variable_set);
set->variables = NEW_LINKED_LIST(preprocessor_variable);
set->outer = outer;
return set;
}
preprocessor_variable *Preprocessor::find_variable_in_one(text_stream *name, preprocessor_variable_set *set) {
if (set == NULL) return NULL;
preprocessor_variable *var;
LOOP_OVER_LINKED_LIST(var, preprocessor_variable, set->variables)
if (Str::eq(name, var->name))
return var;
return NULL;
}
preprocessor_variable *Preprocessor::find_variable_in(text_stream *name, preprocessor_variable_set *set) {
while (set) {
preprocessor_variable *var = Preprocessor::find_variable_in_one(name, set);
if (var) return var;
set = set->outer;
}
return NULL;
}
preprocessor_variable *Preprocessor::ensure_variable(text_stream *name, preprocessor_variable_set *in_set) {
if (in_set == NULL) internal_error("variable without set");
preprocessor_variable *var = Preprocessor::find_variable_in_one(name, in_set);
if (var == NULL) {
var = CREATE(preprocessor_variable);
var->name = Str::duplicate(name);
var->value = I"";
ADD_TO_LINKED_LIST(var, preprocessor_variable, in_set->variables);
}
return var;
}
int Preprocessor::acceptable_variable_name(text_stream *name) {
LOOP_THROUGH_TEXT(pos, name) {
wchar_t c = Str::get(pos);
if ((c >= '0') && (c <= '9')) continue;
if ((c >= 'A') && (c <= 'Z')) continue;
if (c == '_') continue;
return FALSE;
}
return TRUE;
}
@h Macros.
@ The above definition has three parameters, one optional, but only one line. There
are (for now, anyway) hard but harmlessly large limits on the number of these:
@d MAX_PP_MACRO_PARAMETERS 8
@d MAX_PP_MACRO_LINES 128
=
typedef struct preprocessor_macro {
struct text_stream *identifier;
struct preprocessor_macro_parameter *parameters[MAX_PP_MACRO_PARAMETERS];
int no_parameters;
struct text_stream *lines[MAX_PP_MACRO_LINES];
int no_lines;
int suppress_newline_after_expanding;
int suppress_whitespace_when_expanding;
int begins_repeat;
int ends_repeat;
struct text_stream *loop_name;
int span;
void (*expander)(struct preprocessor_macro *, struct preprocessor_state *, struct text_stream **, struct preprocessor_loop *, struct text_file_position *);
CLASS_DEFINITION
} preprocessor_macro;
typedef struct preprocessor_macro_parameter {
struct text_stream *name;
struct text_stream *definition_token;
int optional;
CLASS_DEFINITION
} preprocessor_macro_parameter;
@ New macro declaration lines are processed here, and added to a list |L| of
valid macros:
=
preprocessor_macro *Preprocessor::new_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification, text_file_position *tfp,
void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *)) {
if (Preprocessor::find_macro(L, name))
Errors::in_text_file("a macro with this name already exists", tfp);
preprocessor_macro *new_macro = CREATE(preprocessor_macro);
new_macro->identifier = Str::duplicate(name);
new_macro->no_parameters = 0;
new_macro->no_lines = 0;
new_macro->suppress_newline_after_expanding = TRUE;
new_macro->suppress_whitespace_when_expanding = TRUE;
new_macro->begins_repeat = FALSE;
new_macro->ends_repeat = FALSE;
new_macro->loop_name = NULL;
new_macro->span = FALSE;
new_macro->expander = expander;
match_results mr2 = Regexp::create_mr();
while (Regexp::match(&mr2, parameter_specification, L" *(%C+): *(%C+) *(%c*)")) {
text_stream *par_name = mr2.exp[0];
text_stream *token_name = mr2.exp[1];
Str::clear(parameter_specification);
Str::copy(parameter_specification, mr2.exp[2]);
if (new_macro->no_parameters >= MAX_PP_MACRO_PARAMETERS) {
Errors::in_text_file("too many parameters in this definition", tfp);
} else {
@<Add parameter to macro@>;
}
}
Regexp::dispose_of(&mr2);
if (Str::is_whitespace(parameter_specification) == FALSE)
Errors::in_text_file("parameter list for this definition is malformed", tfp);
ADD_TO_LINKED_LIST(new_macro, preprocessor_macro, L);
return new_macro;
}
@<Add parameter to macro@> =
preprocessor_macro_parameter *new_parameter = CREATE(preprocessor_macro_parameter);
new_parameter->name = Str::duplicate(par_name);
new_parameter->definition_token = Str::duplicate(token_name);
new_parameter->optional = FALSE;
if (Str::get_first_char(new_parameter->name) == '?') {
new_parameter->optional = TRUE;
Str::delete_first_character(new_parameter->name);
}
new_macro->parameters[new_macro->no_parameters++] = new_parameter;
@ We can then add lines to the definition:
=
void Preprocessor::add_line_to_macro(preprocessor_macro *mm, text_stream *line, text_file_position *tfp) {
if (mm->no_lines >= MAX_PP_MACRO_LINES) {
Errors::in_text_file("too many lines in this definition", tfp);
} else {
mm->lines[mm->no_lines++] = Str::duplicate(line);
}
}
@ A few macros are "reserved", that is, have built-in meanings and are not
declared by any makescript but by us. (These have no lines, only parameters.)
=
linked_list *Preprocessor::list_of_reserved_macros(linked_list *special_macros) {
linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
Preprocessor::reserve_repeat_macro(L, I"repeat", I"with: WITH in: IN", Preprocessor::repeat_expander);
Preprocessor::reserve_span_macro(L, I"set", I"name: NAME value: VALUE", Preprocessor::set_expander);
preprocessor_macro *mm;
LOOP_OVER_LINKED_LIST(mm, preprocessor_macro, special_macros)
ADD_TO_LINKED_LIST(mm, preprocessor_macro, L);
return L;
}
preprocessor_macro *Preprocessor::reserve_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification,
void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *)) {
preprocessor_macro *reserved = Preprocessor::new_macro(L, name,
Str::duplicate(parameter_specification), NULL, expander);
return reserved;
}
preprocessor_macro *Preprocessor::reserve_span_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification,
void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *)) {
preprocessor_macro *reserved = Preprocessor::reserve_macro(L, name, parameter_specification, expander);
reserved->suppress_newline_after_expanding = FALSE;
reserved->suppress_whitespace_when_expanding = FALSE;
reserved->span = TRUE;
return reserved;
}
void Preprocessor::reserve_repeat_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification,
void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *)) {
TEMPORARY_TEXT(subname)
WRITE_TO(subname, "%S-block", name);
preprocessor_macro *mm = Preprocessor::reserve_macro(L, subname, parameter_specification, expander);
mm->begins_repeat = TRUE;
mm->loop_name = Str::duplicate(name);
Str::clear(subname);
WRITE_TO(subname, "end-%S-block", name);
mm = Preprocessor::reserve_macro(L, subname, NULL, Preprocessor::end_repeat_expander);
mm->ends_repeat = TRUE;
mm->loop_name = Str::duplicate(name);
Str::clear(subname);
WRITE_TO(subname, "%S-span", name);
mm = Preprocessor::reserve_span_macro(L, subname, parameter_specification, expander);
mm->begins_repeat = TRUE;
mm->loop_name = Str::duplicate(name);
Str::clear(subname);
WRITE_TO(subname, "end-%S-span", name);
mm = Preprocessor::reserve_span_macro(L, subname, NULL, Preprocessor::end_repeat_expander);
mm->ends_repeat = TRUE;
mm->loop_name = Str::duplicate(name);
DISCARD_TEXT(subname)
}
@ Finding a macro in a list. (We could use a dictionary for efficiency, but really,
it's unlikely there are ever more than a few macros.)
=
preprocessor_macro *Preprocessor::find_macro(linked_list *L, text_stream *name) {
preprocessor_macro *mm;
LOOP_OVER_LINKED_LIST(mm, preprocessor_macro, L)
if (Str::eq(mm->identifier, name))
return mm;
return NULL;
}
@ Expanding a macro is the main event, then:
=
void Preprocessor::expand_macro(preprocessor_state *PPS, preprocessor_macro *mm,
text_stream *parameter_settings, text_file_position *tfp) {
text_stream *parameter_values[MAX_PP_MACRO_PARAMETERS];
for (int i=0; i<MAX_PP_MACRO_PARAMETERS; i++) parameter_values[i] = NULL;
match_results mr2 = Regexp::create_mr();
while (Regexp::match(&mr2, parameter_settings, L" *(%C+): *(%c*)")) {
text_stream *setting = mr2.exp[0];
text_stream *value = mr2.exp[1];
text_stream *remainder = NULL;
match_results mr3 = Regexp::create_mr();
if (Regexp::match(&mr3, value, L"(%c+?) *(%C+: *%c*)")) {
value = mr3.exp[0];
remainder = mr3.exp[1];
}
int found = FALSE;
for (int i=0; i<mm->no_parameters; i++)
if (Str::eq(setting, mm->parameters[i]->name)) {
found = TRUE;
parameter_values[i] = Str::new();
text_stream *saved = PPS->dest;
PPS->dest = parameter_values[i];
Preprocessor::expand(value, tfp, PPS);
PPS->dest = saved;
}
if (found == FALSE) {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown parameter '%S'", setting);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
Str::clear(parameter_settings);
Str::copy(parameter_settings, remainder);
Regexp::dispose_of(&mr3);
}
Regexp::dispose_of(&mr2);
if (Str::is_whitespace(parameter_settings) == FALSE)
Errors::in_text_file("parameter list is malformed", tfp);
for (int i=0; i<mm->no_parameters; i++)
if (parameter_values[i] == NULL)
if (mm->parameters[i]->optional == FALSE) {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "compulsory parameter '%S' not given", mm->parameters[i]->name);
Errors::in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
preprocessor_loop *rep = NULL;
if (mm->begins_repeat) {
if (PPS->repeat_sp >= MAX_PREPROCESSOR_LOOP_DEPTH) {
Errors::in_text_file("repetition too deep", tfp);
} else {
rep = &(PPS->repeat_data[PPS->repeat_sp++]);
PPS->shadow_sp = 1;
rep->loop_var_name = I"NAME";
rep->iterations = NEW_LINKED_LIST(text_stream);
rep->repeat_is_block = TRUE;
if (mm->span) rep->repeat_is_block = FALSE;
rep->repeat_saved_dest = PPS->dest;
PPS->dest = Str::new();
}
}
(*(mm->expander))(mm, PPS, parameter_values, rep, tfp);
}
@
=
void Preprocessor::default_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
PPS->stack_frame = Preprocessor::new_variable_set(PPS->stack_frame);
for (int i=0; i<mm->no_parameters; i++) {
preprocessor_variable *var =
Preprocessor::ensure_variable(mm->parameters[i]->definition_token, PPS->stack_frame);
var->value = parameter_values[i];
}
for (int i=0; i<mm->no_lines; i++)
Preprocessor::scan_line(mm->lines[i], tfp, (void *) PPS);
PPS->stack_frame = PPS->stack_frame->outer;
}
void Preprocessor::set_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
text_stream *name = parameter_values[0];
text_stream *value = parameter_values[1];
if (Preprocessor::acceptable_variable_name(name) == FALSE)
Errors::in_text_file("improper variable name", tfp);
preprocessor_variable *var = Preprocessor::ensure_variable(name, PPS->stack_frame);
var->value = Str::duplicate(value);
}
void Preprocessor::repeat_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
text_stream *with = parameter_values[0];
text_stream *in = parameter_values[1];
rep->loop_var_name = Str::duplicate(with);
match_results mr = Regexp::create_mr();
while (Regexp::match(&mr, in, L"(%c*?),(%c*)")) {
text_stream *value = mr.exp[0];
Str::trim_white_space(value);
ADD_TO_LINKED_LIST(Str::duplicate(value), text_stream, rep->iterations);
Str::clear(in);
Str::copy(in, mr.exp[1]);
}
Regexp::dispose_of(&mr);
text_stream *value = in;
Str::trim_white_space(value);
ADD_TO_LINKED_LIST(Str::duplicate(value), text_stream, rep->iterations);
}
@ =
void Preprocessor::end_repeat_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *rep, text_file_position *tfp) {
PPS->shadow_sp = 0;
if (PPS->repeat_sp == 0) Errors::in_text_file("end without repeat", tfp);
else {
preprocessor_loop *rep = &(PPS->repeat_data[--(PPS->repeat_sp)]);
int as_lines = TRUE;
if (mm->span) as_lines = FALSE;
text_stream *matter = PPS->dest;
PPS->dest = rep->repeat_saved_dest;
PPS->stack_frame = Preprocessor::new_variable_set(PPS->stack_frame);
preprocessor_variable *loop_var = Preprocessor::ensure_variable(rep->loop_var_name, PPS->stack_frame);
text_stream *value;
LOOP_OVER_LINKED_LIST(value, text_stream, rep->iterations)
@<Iterate with this value@>;
PPS->stack_frame = PPS->stack_frame->outer;
}
}
@<Iterate with this value@> =
loop_var->value = value;
if (as_lines) {
TEMPORARY_TEXT(line)
LOOP_THROUGH_TEXT(pos, matter) {
if (Str::get(pos) == '\n') {
Preprocessor::scan_line(line, tfp, (void *) PPS);
Str::clear(line);
} else {
PUT_TO(line, Str::get(pos));
}
}
DISCARD_TEXT(line)
} else {
Preprocessor::expand(matter, tfp, PPS);
}

View file

@ -44,6 +44,7 @@ Chapter 4: Text Handling
Wide Strings
String Manipulation
Text Files
Preprocessor
Tries and Avinues
Pattern Matching

View file

@ -1,5 +1,8 @@
# Because inweb needs to be bootstrapped, we unusually preserve the current
# tangled C file in the repository:
# This is "inweb.giscript", a script used to generate the ".gitignore" file
# in the inweb repository. Do not edit ".gitignore" directly. Instead,
# edit this script, and then rebuild ".gitignore" with the command:
# inweb/Tangled/inweb -prototype inweb/scripts/inweb.giscript -gitignore inweb/.gitignore
.DS_Store
Manual.html
@ -9,6 +12,7 @@ Woven/
Tangled/inweb
Tangled/inweb_dev*
Tangled/inweb.o
Tangled/inweb.exe
Tests/intest-history.txt
Tests/Transient/
Tests/hashes.intest