inweb-bootstrap/Tangled/inweb.c
2022-08-20 11:02:58 +01:00

34751 lines
1.1 MiB

#ifndef PLATFORM_WINDOWS
#define PLATFORM_POSIX
#endif
/* Tangled output generated by inweb: do not edit */
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#ifdef PLATFORM_POSIX
#include <errno.h>
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#include <limits.h>
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_WINDOWS
#include <errno.h>
#endif /* PLATFORM_WINDOWS */
#line 42 "inweb/foundation-module/Chapter 1/Foundation Module.w"
#include <stdint.h>
#line 48 "inweb/foundation-module/Chapter 1/Foundation Module.w"
#include <wchar.h>
#ifdef PLATFORM_POSIX
#line 25 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <sys/stat.h>
#include <sys/types.h>
#line 28 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <dirent.h>
#include <pthread.h>
#line 31 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <unistd.h>
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_UNIX
#ifdef PLATFORM_POSIX
#line 49 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <strings.h>
#endif /* PLATFORM_UNIX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#line 61 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <strings.h>
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#line 71 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <strings.h>
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 142 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int _NSGetExecutablePath(char* buf, uint32_t* bufsize);
void Platform__where_am_i(wchar_t *p, size_t length) {
char relative_path[4 * PATH_MAX + 1];
char absolute_path[PATH_MAX + 1];
size_t convert_len;
uint32_t pathsize = sizeof(relative_path);
uint32_t tempsize = pathsize;
/* Get "a path" to the executable */
if (_NSGetExecutablePath(relative_path, &tempsize) != 0)
{
#ifdef PLATFORM_POSIX
#line 180 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
p[0] = '\0';
return;
#endif /* PLATFORM_POSIX */
}
#line 152 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
;
/* Convert to canonical absolute path */
if (realpath(relative_path, absolute_path) == NULL)
{
#ifdef PLATFORM_POSIX
#line 180 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
p[0] = '\0';
return;
#endif /* PLATFORM_POSIX */
}
#line 155 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
;
/* Next, convert the obtained buffer (which is a string in the local
* filename encoding, possibly multibyte) to a wide-char string. */
convert_len = mbstowcs(p, absolute_path, length);
if (convert_len == (size_t)-1)
{
#ifdef PLATFORM_POSIX
#line 180 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
p[0] = '\0';
return;
#endif /* PLATFORM_POSIX */
}
#line 160 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
;
}
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 373 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
typedef pthread_t foundation_thread;
typedef pthread_attr_t foundation_thread_attributes;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#line 408 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <sys/sysinfo.h>
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 422 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <sys/sysctl.h>
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_WINDOWS
#line 19 "inweb/foundation-module/Chapter 1/Windows Platform.w"
#include <dirent.h>
#line 21 "inweb/foundation-module/Chapter 1/Windows Platform.w"
#include <io.h>
#include <sys/stat.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#undef IN
#undef OUT
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 67 "inweb/foundation-module/Chapter 1/Windows Platform.w"
char *Platform__getenv(const char *name) {
char *env = getenv(name);
if (env == 0) {
char value[MAX_PATH];
if (strcmp(name, "PWD") == 0) {
if (GetCurrentDirectoryA(MAX_PATH, value) != 0)
_putenv_s(name, value);
} else if (strcmp(name, "HOME") == 0) {
if (SHGetFolderPathA(0, CSIDL_PERSONAL, 0, SHGFP_TYPE_CURRENT, value) == 0)
_putenv_s(name, value);
}
env = getenv(name);
}
return env;
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 100 "inweb/foundation-module/Chapter 1/Windows Platform.w"
/* Check the first element of the command: if it has path separators in
it, we assume we are running one of our commands, otherwise it is a
Unix style command. */
int Platform__Win32_is_unix_cmd(const char* cmd) {
char stop = ' ';
int i = 0;
if (cmd[0] == '\"') {
stop = '\"';
i = 1;
}
while ((cmd[i] != 0) && (cmd[i] != stop)) {
if ((cmd[i] == '/') || (cmd[i] == '\\'))
return 0;
i++;
}
return 1;
}
int Platform__system(const char *cmd) {
char cmd_line[10*MAX_PATH];
/* Check if the command should be executed with the Windows cmd interpreter
or a Unix-like shell. */
int unix = Platform__Win32_is_unix_cmd(cmd);
if (unix) {
/* Some Cygwin commands cannot handle backslashes in paths. */
int forward_slash = 0;
if (strncmp(cmd,"pdftex ",7) == 0)
forward_slash = 1;
/* For a Unix shell command, escape any double quotes and backslashes. */
char *pcl;
const char *pc;
strcpy(cmd_line, "sh -c \"");
for (pc = cmd, pcl = cmd_line+strlen(cmd_line); *pc != 0; ++pc, ++pcl) {
if (*pc == '\"') {
*(pcl++) = '\\';
*pcl = *pc;
}
else if (*pc == '\\') {
if (forward_slash)
*pcl = '/';
else {
*(pcl++) = '\\';
*pcl = *pc;
}
}
else
*pcl = *pc;
}
*(pcl++) = '\"';
*(pcl++) = 0;
} else {
/* Otherwise, run with the Windows command interpreter. */
strcpy(cmd_line, "cmd /s /c \"");
strcat(cmd_line, cmd);
strcat(cmd_line, "\"");
}
STARTUPINFOA start;
memset(&start, 0, sizeof start);
start.cb = sizeof start;
start.dwFlags = STARTF_USESHOWWINDOW;
start.wShowWindow = SW_HIDE;
PROCESS_INFORMATION process;
if (CreateProcessA(0, cmd_line, 0, 0, FALSE, CREATE_NO_WINDOW, 0, 0, &start, &process) == 0) {
if (unix)
fprintf(stderr, "A Unix-like shell \"sh\" (such as that from Cygwin) must be in the path.\n");
return -1;
}
CloseHandle(process.hThread);
if (WaitForSingleObject(process.hProcess, INFINITE) != WAIT_OBJECT_0) {
CloseHandle(process.hProcess);
return -1;
}
DWORD code = 10;
GetExitCodeProcess(process.hProcess, &code);
CloseHandle(process.hProcess);
return (int)code;
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 378 "inweb/foundation-module/Chapter 1/Windows Platform.w"
typedef HANDLE foundation_thread;
typedef int foundation_thread_attributes;
struct Win32_Thread_Start { void *(*fn)(void *); void* arg; };
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 479 "inweb/foundation-module/Chapter 1/Windows Platform.w"
struct Win32_Mutex { INIT_ONCE init; CRITICAL_SECTION crit; };
#endif /* PLATFORM_WINDOWS */
#define TRUE 1
#define FALSE 0
#define NOT_APPLICABLE 2
#define UTF8_ENC 1 /* Write as UTF-8 without BOM */
#define ISO_ENC 2 /* Write as ISO Latin-1 (i.e., no conversion needed) */
#define MAX_FILENAME_LENGTH 1025
#define LOG_CLSW 0
#define VERSION_CLSW 1
#define CRASH_CLSW 2
#define HELP_CLSW 3
#define FIXTIME_CLSW 4
#define AT_CLSW 5
#define LOCALE_CLSW 6
#ifdef PLATFORM_POSIX
#define FOLDER_SEPARATOR '/'
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#define SHELL_QUOTE_CHARACTER '\''
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#define PLATFORM_STRING "macos"
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#define SHELL_QUOTE_CHARACTER '\''
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#define INFORM_FOLDER_RELATIVE_TO_HOME "Library"
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_UNIX
#ifdef PLATFORM_POSIX
#define PLATFORM_STRING "unix"
#endif /* PLATFORM_UNIX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_UNIX
#ifdef PLATFORM_POSIX
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#endif /* PLATFORM_UNIX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#define PLATFORM_STRING "linux"
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#define PLATFORM_STRING "android"
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#define SUPPRESS_MAIN
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#define CREATE_MUTEX(name) \
static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#define LOCK_MUTEX(name) pthread_mutex_lock(&name);
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#define UNLOCK_MUTEX(name) pthread_mutex_unlock(&name);
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_WINDOWS
#define PLATFORM_STRING "windows"
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define LOCALE_IS_ISO
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define FOLDER_SEPARATOR '\\'
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define SHELL_QUOTE_CHARACTER '\"'
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define WINDOWS_JAVASCRIPT
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define isdigit(x) Platform__Windows_isdigit(x)
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define CREATE_MUTEX(name) \
static struct Win32_Mutex name = { INIT_ONCE_STATIC_INIT, { 0 }};
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define LOCK_MUTEX(name) {\
BOOL pending;\
InitOnceBeginInitialize(&(name.init), 0, &pending, 0);\
if (pending) {\
InitializeCriticalSection(&(name.crit));\
InitOnceComplete(&(name.init), 0, 0);\
}\
EnterCriticalSection(&(name.crit));\
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#define UNLOCK_MUTEX(name) {\
LeaveCriticalSection(&(name.crit));\
}
#endif /* PLATFORM_WINDOWS */
#define LOG_INDENT STREAM_INDENT(DL)
#define LOG_OUTDENT STREAM_OUTDENT(DL)
#define DEBUGGING_LOG_INCLUSIONS_DA 0
#define SHELL_USAGE_DA 1
#define MEMORY_USAGE_DA 2
#define TEXT_FILES_DA 3
#define CLASS_DEFINITION \
int allocation_id; /* Numbered from 0 upwards in creation order */\
void *next_structure; /* Next object in double-linked list */\
void *prev_structure; /* Previous object in double-linked list */
#define unused_class_value_CLASS 0
#define SAFETY_MARGIN 128
#define BLANK_END_SIZE 256
#define MEMORY_GRANULARITY 100*1024*8 /* which must be divisible by 1024 */
#define INTEGRITY_NUMBER 0x12345678 /* a value unlikely to be in memory just by chance */
#define CREATE(type_name) (allocate_##type_name())
#define COPY(to, from, type_name) (copy_##type_name(to, from))
#define CREATE_BEFORE(existing, type_name) (allocate_##type_name##_before(existing))
#define DESTROY(this, type_name) (deallocate_##type_name(this))
#define FIRST_OBJECT(type_name) ((type_name *) alloc_status[type_name##_CLASS].first_in_memory)
#define LAST_OBJECT(type_name) ((type_name *) alloc_status[type_name##_CLASS].last_in_memory)
#define NEXT_OBJECT(this, type_name) ((type_name *) (this->next_structure))
#define PREV_OBJECT(this, type_name) ((type_name *) (this->prev_structure))
#define NUMBER_CREATED(type_name) (alloc_status[type_name##_CLASS].objects_count)
#define LOOP_OVER(var, type_name)\
for (var=FIRST_OBJECT(type_name); var != NULL; var = NEXT_OBJECT(var, type_name))
#define LOOP_BACKWARDS_OVER(var, type_name)\
for (var=LAST_OBJECT(type_name); var != NULL; var = PREV_OBJECT(var, type_name))
#define NEW_OBJECT(type_name) ((type_name *) Memory__allocate(type_name##_CLASS, sizeof(type_name)))
#define DECLARE_CLASS(type_name) DECLARE_CLASS_WITH_ID(type_name, type_name##_CLASS)
#define DECLARE_CLASS_WITH_ID(type_name, id_name)\
MAKE_REFERENCE_ROUTINES(type_name, id_name)\
type_name *allocate_##type_name(void) {\
LOCK_MUTEX(memory_single_allocation_mutex);\
alloc_status[id_name].name_of_type = #type_name;\
type_name *prev_obj = LAST_OBJECT(type_name);\
type_name *new_obj = Memory__allocate(type_name##_CLASS, sizeof(type_name));\
new_obj->allocation_id = alloc_status[id_name].objects_allocated-1;\
new_obj->next_structure = NULL;\
if (prev_obj != NULL)\
prev_obj->next_structure = (void *) new_obj;\
new_obj->prev_structure = prev_obj;\
alloc_status[id_name].objects_count++;\
UNLOCK_MUTEX(memory_single_allocation_mutex);\
return new_obj;\
}\
void deallocate_##type_name(type_name *kill_me) {\
LOCK_MUTEX(memory_single_allocation_mutex);\
type_name *prev_obj = PREV_OBJECT(kill_me, type_name);\
type_name *next_obj = NEXT_OBJECT(kill_me, type_name);\
if (prev_obj == NULL) {\
alloc_status[id_name].first_in_memory = next_obj;\
} else {\
prev_obj->next_structure = next_obj;\
}\
if (next_obj == NULL) {\
alloc_status[id_name].last_in_memory = prev_obj;\
} else {\
next_obj->prev_structure = prev_obj;\
}\
alloc_status[id_name].objects_count--;\
UNLOCK_MUTEX(memory_single_allocation_mutex);\
}\
type_name *allocate_##type_name##_before(type_name *existing) {\
LOCK_MUTEX(memory_single_allocation_mutex);\
type_name *new_obj = allocate_##type_name();\
deallocate_##type_name(new_obj);\
new_obj->prev_structure = existing->prev_structure;\
if (existing->prev_structure != NULL)\
((type_name *) existing->prev_structure)->next_structure = new_obj;\
else alloc_status[id_name].first_in_memory = (void *) new_obj;\
new_obj->next_structure = existing;\
existing->prev_structure = new_obj;\
alloc_status[id_name].objects_count++;\
UNLOCK_MUTEX(memory_single_allocation_mutex);\
return new_obj;\
}\
void copy_##type_name(type_name *to, type_name *from) {\
LOCK_MUTEX(memory_single_allocation_mutex);\
type_name *prev_obj = to->prev_structure;\
type_name *next_obj = to->next_structure;\
int aid = to->allocation_id;\
*to = *from;\
to->allocation_id = aid;\
to->next_structure = next_obj;\
to->prev_structure = prev_obj;\
UNLOCK_MUTEX(memory_single_allocation_mutex);\
}
#define DECLARE_CLASS_ALLOCATED_IN_ARRAYS(type_name, NO_TO_ALLOCATE_TOGETHER)\
MAKE_REFERENCE_ROUTINES(type_name, type_name##_CLASS)\
typedef struct type_name##_array {\
int used;\
struct type_name array[NO_TO_ALLOCATE_TOGETHER];\
CLASS_DEFINITION\
} type_name##_array;\
int type_name##_array_CLASS = type_name##_CLASS; /* C does permit |#define| to make |#define|s */\
DECLARE_CLASS_WITH_ID(type_name##_array, type_name##_CLASS)\
type_name##_array *next_##type_name##_array = NULL;\
struct type_name *allocate_##type_name(void) {\
LOCK_MUTEX(memory_array_allocation_mutex);\
if ((next_##type_name##_array == NULL) ||\
(next_##type_name##_array->used >= NO_TO_ALLOCATE_TOGETHER)) {\
alloc_status[type_name##_array_CLASS].no_allocated_together = NO_TO_ALLOCATE_TOGETHER;\
next_##type_name##_array = allocate_##type_name##_array();\
next_##type_name##_array->used = 0;\
}\
type_name *rv = &(next_##type_name##_array->array[next_##type_name##_array->used++]);\
UNLOCK_MUTEX(memory_array_allocation_mutex);\
return rv;\
}
#define STREAM_MREASON 0
#define FILENAME_STORAGE_MREASON 1
#define STRING_STORAGE_MREASON 2
#define DICTIONARY_MREASON 3
#define ARRAY_SORTING_MREASON 4
#define NULL_GENERAL_POINTER (Memory__store_gp_null())
#define GENERAL_POINTER_IS_NULL(gp) (Memory__test_gp_null(gp))
#define COMPARE_GENERAL_POINTERS(gp1, gp2)\
(gp1.pointer_to_data == gp2.pointer_to_data)
#define GENERAL_POINTER_AS_INT(gp) \
((pointer_sized_int) gp.pointer_to_data)
#define MAKE_REFERENCE_ROUTINES(type_name, id_code)\
general_pointer STORE_POINTER_##type_name(type_name *data) {\
general_pointer gp;\
gp.pointer_to_data = (void *) data;\
gp.run_time_type_code = id_code;\
return gp;\
}\
type_name *RETRIEVE_POINTER_##type_name(general_pointer gp) {\
if (gp.run_time_type_code != id_code) {\
LOG("Wanted ID code %d, found %d\n", id_code, gp.run_time_type_code);\
internal_error("attempt to retrieve wrong pointer type as " #type_name);\
}\
return (type_name *) gp.pointer_to_data;\
}\
general_pointer PASS_POINTER_##type_name(general_pointer gp) {\
if (gp.run_time_type_code != id_code) {\
LOG("Wanted ID code %d, found %d\n", id_code, gp.run_time_type_code);\
internal_error("attempt to pass wrong pointer type as " #type_name);\
}\
return gp;\
}\
int VALID_POINTER_##type_name(general_pointer gp) {\
if (gp.run_time_type_code == id_code) return TRUE;\
return FALSE;\
}
#define chapter_md_CLASS 1
#define command_line_switch_CLASS 2
#define debugging_aspect_CLASS 3
#define dict_entry_CLASS 4
#define dictionary_CLASS 5
#define ebook_chapter_CLASS 6
#define ebook_CLASS 7
#define ebook_datum_CLASS 8
#define ebook_image_CLASS 9
#define ebook_mark_CLASS 10
#define ebook_page_CLASS 11
#define ebook_volume_CLASS 12
#define filename_CLASS 13
#define heterogeneous_tree_CLASS 14
#define HTML_file_state_CLASS 15
#define HTML_tag_CLASS 16
#define JSON_pair_requirement_CLASS 17
#define JSON_requirement_CLASS 18
#define JSON_single_requirement_CLASS 19
#define JSON_type_CLASS 20
#define JSON_value_CLASS 21
#define linked_list_CLASS 22
#define linked_list_item_CLASS 23
#define match_avinue_CLASS 24
#define match_trie_CLASS 25
#define method_CLASS 26
#define method_set_CLASS 27
#define module_CLASS 28
#define module_search_CLASS 29
#define pathname_CLASS 30
#define preprocessor_macro_CLASS 31
#define preprocessor_macro_parameter_CLASS 32
#define preprocessor_variable_CLASS 33
#define preprocessor_variable_set_CLASS 34
#define scan_directory_CLASS 35
#define section_md_CLASS 36
#define semantic_version_number_holder_CLASS 37
#define semver_range_CLASS 38
#define stopwatch_timer_CLASS 39
#define string_storage_area_CLASS 40
#define text_stream_CLASS 41
#define tree_node_CLASS 42
#define tree_node_type_CLASS 43
#define tree_type_CLASS 44
#define web_bibliographic_datum_CLASS 45
#define web_md_CLASS 46
#define SHELL_LOCALE 0
#define CONSOLE_LOCALE 1
#define NEWLINE_IN_STRING ((char) 0x7f) /* Within quoted text, all newlines are converted to this */
#define OUTPUT_STREAM text_stream *OUT /* used only as a function prototype argument */
#define STDOUT Streams__get_stdout()
#define STDERR Streams__get_stderr()
#define PUT(c) Streams__putc(c, OUT)
#define PUT_TO(stream, c) Streams__putc(c, stream)
#define INDENT Streams__indent(OUT);
#define STREAM_INDENT(x) Streams__indent(x);
#define OUTDENT Streams__outdent(OUT);
#define STREAM_OUTDENT(x) Streams__outdent(x);
#define SET_INDENT(N) Streams__set_indentation(OUT, N);
#define TEMPORARY_TEXT(T) \
wchar_t T##_dest[2048];\
text_stream T##_stream_structure = Streams__new_buffer(2048, T##_dest);\
text_stream *T = &T##_stream_structure;
#define DISCARD_TEXT(T) \
STREAM_CLOSE(T);
#define STREAM_OPEN_TO_FILE(new, fn, enc) Streams__open_to_file(new, fn, enc)
#define STREAM_OPEN_TO_FILE_APPEND(new, fn, enc) Streams__open_to_file_append(new, fn, enc)
#define STREAM_OPEN_IN_MEMORY(new) Streams__open_to_memory(new, 20480)
#define STREAM_CLOSE(stream) Streams__close(stream)
#define STREAM_FLUSH(stream) Streams__flush(stream)
#define STREAM_EXTENT(x) Streams__get_position(x)
#define STREAM_MUST_BE_IN_MEMORY(x) \
if ((x != NULL) && (x->write_to_memory == NULL))\
internal_error("text_stream not in memory");
#define STREAM_BACKSPACE(x) Streams__set_position(x, Streams__get_position(x) - 1)
#define STREAM_ERASE_BACK_TO(start_position) Streams__set_position(OUT, start_position)
#define STREAM_MOST_RECENT_CHAR(x) Streams__latest(x)
#define STREAM_COPY(to, from) Streams__copy(to, from)
#define MALLOCED_STRF 0x00000001 /* was the |write_to_memory| pointer claimed by |malloc|? */
#define USES_XML_ESCAPES_STRF 0x00000002 /* see above */
#define USES_LOG_ESCAPES_STRF 0x00000004 /* |WRITE| to this stream supports |$| escapes */
#define INDENT_PENDING_STRF 0x00000008 /* we have just ended a line, so further text should indent */
#define FILE_ENCODING_ISO_STRF 0x00000010 /* relevant only for file streams */
#define FILE_ENCODING_UTF8_STRF 0x00000020 /* relevant only for file streams */
#define ECHO_BYTES_STRF 0x00000080 /* for debugging only */
#define FOR_RE_STRF 0x00000100 /* for debugging only */
#define FOR_TT_STRF 0x00000200 /* for debugging only */
#define FOR_CO_STRF 0x00000400 /* for debugging only */
#define FOR_FI_STRF 0x00000800 /* for debugging only */
#define FOR_OM_STRF 0x00001000 /* for debugging only */
#define USES_I6_ESCAPES_STRF 0x00002000 /* as if an Inform 6 string */
#define READ_ONLY_STRF 0x00008000
#define INDENTATION_BASE_STRF 0x00010000 /* number of tab stops in from the left margin */
#define INDENTATION_MASK_STRF 0x0FFF0000 /* (held in these bits) */
#define STREAM_USES_UTF8(x) ((x)?((x->stream_flags) & FILE_ENCODING_UTF8_STRF):FALSE)
#define SPACE_AT_END_OF_STREAM 6
#define VACANT_ECAT 0 /* unregistered */
#define POINTER_ECAT 1 /* data to be printed is a pointer to a structure */
#define INTSIZED_ECAT 2 /* data to be printed is or fits into an integer */
#define WORDING_ECAT 3 /* data to be printed is a |wording| structure from inform7 */
#define DIRECT_ECAT 4 /* data must be printed directly by the code below */
#define REGISTER_WRITER(c, f) Writers__register_logger(c, &f##_writer);
#define COMPILE_WRITER(t, f)\
void f##_writer(text_stream *format, void *obj) { text_stream *SDL = DL; DL = format; if (DL) f((t) obj); DL = SDL; }
#define REGISTER_WRITER_I(c, f) Writers__register_logger_I(c, &f##_writer);
#define COMPILE_WRITER_I(t, f)\
void f##_writer(text_stream *format, int I) { text_stream *SDL = DL; DL = format; if (DL) f((t) I); DL = SDL; }
#define UNUSED_METHOD_ID_MTID 1
#define INT_METHOD_TYPE(id, args...)\
typedef int (*id##_type)(args);
#define VOID_METHOD_TYPE(id, args...)\
typedef void (*id##_type)(args);
#define METHOD_ADD(upon, id, func)\
Methods__add(upon->methods, id, (void *) &func);
#define INT_METHOD_CALL(rval, upon, id, args...) {\
rval = FALSE;\
for (method *M = upon?(upon->methods->first_method):NULL; M; M = M->next_method)\
if (M->method_id == id) {\
int method_rval_ = (*((id##_type) (M->method_function)))(upon, args);\
if (method_rval_) {\
rval = method_rval_;\
break;\
}\
}\
}
#define INT_METHOD_CALL_WITHOUT_ARGUMENTS(rval, upon, id) {\
rval = FALSE;\
for (method *M = upon?(upon->methods->first_method):NULL; M; M = M->next_method)\
if (M->method_id == id) {\
int method_rval_ = (*((id##_type) (M->method_function)))(upon);\
if (method_rval_) {\
rval = method_rval_;\
break;\
}\
}\
}
#define VOID_METHOD_CALL(upon, id, args...)\
for (method *M = upon?(upon->methods->first_method):NULL; M; M = M->next_method)\
if (M->method_id == id)\
(*((id##_type) (M->method_function)))(upon, args);
#define VOID_METHOD_CALL_WITHOUT_ARGUMENTS(upon, id)\
for (method *M = upon?(upon->methods->first_method):NULL; M; M = M->next_method)\
if (M->method_id == id)\
(*((id##_type) (M->method_function)))(upon);
#define NO_LL_EARLY_ITEMS 32
#define NEW_LINKED_LIST(T) \
(LinkedLists__new())
#define FIRST_ITEM_IN_LINKED_LIST(T, L)\
(LinkedLists__first(L))
#define ENTRY_IN_LINKED_LIST(N, T, L)\
((T *) (LinkedLists__entry(N, L)))
#define DELETE_FROM_LINKED_LIST(N, T, L)\
((T *) (LinkedLists__delete(N, L)))
#define LAST_ITEM_IN_LINKED_LIST(T, L)\
(LinkedLists__last(L))
#define NEXT_ITEM_IN_LINKED_LIST(I, T)\
(LinkedLists__next(I))
#define CONTENT_IN_ITEM(I, T)\
((T *) (LinkedLists__content(I)))
#define ADD_TO_LINKED_LIST(I, T, L)\
LinkedLists__add(L, (void *) (I), TRUE)
#define FIRST_IN_LINKED_LIST(T, L)\
((T *) (LinkedLists__content(LinkedLists__first(L))))
#define LAST_IN_LINKED_LIST(T, L)\
((T *) (LinkedLists__content(LinkedLists__last(L))))
#define LOOP_OVER_LINKED_LIST(P, T, L)\
for (linked_list_item *P##_item = (P = FIRST_IN_LINKED_LIST(T, L), FIRST_ITEM_IN_LINKED_LIST(T, L));\
P##_item;\
P##_item = (P = CONTENT_IN_ITEM(NEXT_ITEM_IN_LINKED_LIST(P##_item, T), T), NEXT_ITEM_IN_LINKED_LIST(P##_item, T)))
#define lifo_stack linked_list
#define NEW_LIFO_STACK(T) \
(LinkedLists__new())
#define PUSH_TO_LIFO_STACK(I, T, L)\
LinkedLists__add((L), (void *) (I), FALSE)
#define PULL_FROM_LIFO_STACK(T, L)\
((T *) LinkedLists__remove_from_front(L))
#define POP_LIFO_STACK(T, L)\
(LinkedLists__remove_from_front(L))
#define TOP_OF_LIFO_STACK(T, L)\
FIRST_IN_LINKED_LIST(T, L)
#define LIFO_STACK_EMPTY(T, L)\
((LinkedLists__len(L) == 0)?TRUE:FALSE)
#define LOOP_DOWN_LIFO_STACK(P, T, L)\
LOOP_OVER_LINKED_LIST(P, T, L)
#define internal_error(message) Errors__internal_error_handler(NULL, message, __FILE__, __LINE__)
#define ACTION_CLSF 1
#define BOOLEAN_ON_CLSF 2
#define BOOLEAN_OFF_CLSF 3
#define NUMERICAL_CLSF 4
#define TEXTUAL_CLSF 5
#define NO_CLSG 0
#define FOUNDATION_CLSG 1
#define BOGUS_CLSN -12345678 /* bogus because guaranteed not to be a genuine switch ID */
#define FORMAT_PERHAPS_HTML 1
#define FORMAT_PERHAPS_JPEG 2
#define FORMAT_PERHAPS_PNG 3
#define FORMAT_PERHAPS_OGG 4
#define FORMAT_PERHAPS_AIFF 5
#define FORMAT_PERHAPS_MIDI 6
#define FORMAT_PERHAPS_MOD 7
#define FORMAT_PERHAPS_GLULX 8
#define FORMAT_PERHAPS_ZCODE 9
#define FORMAT_PERHAPS_SVG 10
#define FORMAT_PERHAPS_GIF 11
#define FORMAT_UNRECOGNISED 0
#define SPOOL_LENGTH 4*8*MAX_FILENAME_LENGTH
#define CHRISTMAS_FEAST 1
#define EASTER_FEAST 2
#define NON_FEAST 3
#define MAX_STRING_LENGTH 8*1024
#define LOOP_THROUGH_TEXT(P, ST)\
for (string_position P = Str__start(ST); P.index < Str__len(P.S); P.index++)
#define LOOP_BACKWARDS_THROUGH_TEXT(P, ST)\
for (string_position P = Str__back(Str__end(ST)); P.index >= 0; P.index--)
#define PROTECTED_OPEN_BRACE_PPCHAR 0x25A0
#define PROTECTED_CLOSE_BRACE_PPCHAR 0x25A1
#define PROTECTED_BLANK_PPCHAR 0x25A2
#define MAX_PREPROCESSOR_LOOP_DEPTH 8
#define MAX_PP_MACRO_PARAMETERS 8
#define MAX_PP_MACRO_LINES 128
#define TRIE_START -1 /* head: the root of a trie parsing forwards from the start */
#define TRIE_END -2 /* head: the root of a trie parsing backwards from the end */
#define TRIE_ANYTHING 10003 /* choice: match any text here */
#define TRIE_ANY_GROUP 10001 /* choice: match any character from this group */
#define TRIE_NOT_GROUP 10002 /* choice: match any character not in this group */
#define TRIE_STOP -3 /* terminal: here's the outcome */
#define MAX_TRIE_GROUP_SIZE 26 /* size of the allowable groups of characters */
#define MAX_TRIE_REWIND 10 /* that should be far, far more rewinding than necessary */
#define MAX_BRACKETED_SUBEXPRESSIONS 5 /* this many bracketed subexpressions can be extracted */
#define MATCH_TEXT_INITIAL_ALLOCATION 64
#define ANY_CHARCLASS 1
#define DIGIT_CHARCLASS 2
#define WHITESPACE_CHARCLASS 3
#define NONWHITESPACE_CHARCLASS 4
#define IDENTIFIER_CHARCLASS 5
#define PREFORM_CHARCLASS 6
#define PREFORMC_CHARCLASS 7
#define LITERAL_CHARCLASS 8
#define TAB_CHARCLASS 9
#define QUOTE_CHARCLASS 10
#define REP_REPEATING 1
#define REP_ATSTART 2
#define NUMBER_JSONTYPE 1
#define DOUBLE_JSONTYPE 2
#define STRING_JSONTYPE 3
#define BOOLEAN_JSONTYPE 4
#define ARRAY_JSONTYPE 5
#define OBJECT_JSONTYPE 6
#define NULL_JSONTYPE 7
#define ERROR_JSONTYPE 8
#define tag_error(x) {\
LOG("Tag error: %s\n", x);\
HTML_tag *ht;\
int i = 1;\
LOG("HTML tag stack:\n");\
LOOP_DOWN_LIFO_STACK(ht, HTML_tag, hs->tag_stack) {\
LOG(" %d. %s (opened at line %d of '%s')\n", i++,\
ht->tag_name, ht->from_line, ht->from_filename);\
}\
LOG("\n\n");\
}
#define HTML_TAG(tag) HTML__tag(OUT, tag, NULL);
#define HTML_OPEN(tag) HTML__open(OUT, tag, NULL, __FILE__, __LINE__);
#define HTML_CLOSE(tag) HTML__close(OUT, tag, __FILE__, __LINE__);
#define CORNER_SIZE 8 /* measured in pixels */
#define ROUND_BOX_TOP 1
#define ROUND_BOX_BOTTOM 2
#define SOURCE_REF_CHAR L'\xf0'
#define FORCE_NEW_PARA_CHAR L'\xd0'
#define SEMVER_NUMBER_DEPTH 3 /* major, minor, patch */
#define MMP_SEMVERPART 1
#define PRE_SEMVERPART 2
#define BM_SEMVERPART 3
#define CLOSED_RANGE_END 1
#define OPEN_RANGE_END 2
#define INFINITE_RANGE_END 3
#define EMPTY_RANGE_END 4
#define V1_SYNTAX 1
#define V2_SYNTAX 2
#define LOOP_OVER_BIBLIOGRAPHIC_DATA(bd, Wm)\
LOOP_OVER_LINKED_LIST(bd, web_bibliographic_datum, Wm->bibliographic_data)
#define READING_WEB_MOM 0
#define MAKEFILE_TOOL_MOM 1
#define MAKEFILE_WEB_MOM 2
#define MAKEFILE_MODULE_MOM 3
#define INWEB_PARAGRAPH_SYNTAX 1
#define INWEB_CODE_SYNTAX 2
#define INWEB_DASH_SYNTAX 3
#define INWEB_PURPOSE_SYNTAX 4
#define INWEB_FIGURE_SYNTAX 5
#define INWEB_EQUALS_SYNTAX 6
#define INWEB_EXTRACT_SYNTAX 7
#define PROGRAM_NAME "inweb"
#define asset_rule_CLASS 47
#define breadcrumb_request_CLASS 48
#define chapter_CLASS 49
#define colony_CLASS 50
#define colony_member_CLASS 51
#define colour_scheme_CLASS 52
#define colouring_language_block_CLASS 53
#define colouring_rule_CLASS 54
#define defined_constant_CLASS 55
#define enumeration_set_CLASS 56
#define footnote_CLASS 57
#define hash_table_entry_CLASS 58
#define hash_table_entry_usage_CLASS 59
#define language_function_CLASS 60
#define language_type_CLASS 61
#define macro_usage_CLASS 62
#define makefile_specifics_CLASS 63
#define nonterminal_variable_CLASS 64
#define para_macro_CLASS 65
#define paragraph_CLASS 66
#define paragraph_tagging_CLASS 67
#define preform_nonterminal_CLASS 68
#define programming_language_CLASS 69
#define reserved_word_CLASS 70
#define section_CLASS 71
#define source_line_CLASS 72
#define structure_element_CLASS 73
#define tangle_target_CLASS 74
#define tex_results_CLASS 75
#define text_literal_CLASS 76
#define theme_tag_CLASS 77
#define weave_format_CLASS 78
#define weave_pattern_CLASS 79
#define weave_plugin_CLASS 80
#define weave_order_CLASS 81
#define web_CLASS 82
#define writeme_asset_CLASS 83
#define weave_document_node_CLASS 84
#define weave_head_node_CLASS 85
#define weave_body_node_CLASS 86
#define weave_tail_node_CLASS 87
#define weave_section_header_node_CLASS 88
#define weave_section_footer_node_CLASS 89
#define weave_chapter_header_node_CLASS 90
#define weave_chapter_footer_node_CLASS 91
#define weave_verbatim_node_CLASS 92
#define weave_section_purpose_node_CLASS 93
#define weave_subheading_node_CLASS 94
#define weave_bar_node_CLASS 95
#define weave_linebreak_node_CLASS 96
#define weave_pagebreak_node_CLASS 97
#define weave_paragraph_heading_node_CLASS 98
#define weave_endnote_node_CLASS 99
#define weave_material_node_CLASS 100
#define weave_figure_node_CLASS 101
#define weave_extract_node_CLASS 102
#define weave_audio_node_CLASS 103
#define weave_download_node_CLASS 104
#define weave_video_node_CLASS 105
#define weave_embed_node_CLASS 106
#define weave_pmac_node_CLASS 107
#define weave_vskip_node_CLASS 108
#define weave_chapter_node_CLASS 109
#define weave_section_node_CLASS 110
#define weave_code_line_node_CLASS 111
#define weave_function_usage_node_CLASS 112
#define weave_commentary_node_CLASS 113
#define weave_carousel_slide_node_CLASS 114
#define weave_toc_node_CLASS 115
#define weave_toc_line_node_CLASS 116
#define weave_chapter_title_page_node_CLASS 117
#define weave_defn_node_CLASS 118
#define weave_source_code_node_CLASS 119
#define weave_url_node_CLASS 120
#define weave_footnote_cue_node_CLASS 121
#define weave_begin_footnote_text_node_CLASS 122
#define weave_display_line_node_CLASS 123
#define weave_function_defn_node_CLASS 124
#define weave_item_node_CLASS 125
#define weave_grammar_index_node_CLASS 126
#define weave_inline_node_CLASS 127
#define weave_locale_node_CLASS 128
#define weave_maths_node_CLASS 129
#define NO_MODE 0
#define ANALYSE_MODE 1
#define TANGLE_MODE 2
#define WEAVE_MODE 3
#define TRANSLATE_MODE 4
#define SWARM_OFF_SWM 0
#define SWARM_INDEX_SWM 1
#define SWARM_CHAPTERS_SWM 2
#define SWARM_SECTIONS_SWM 3
#define VERBOSE_CLSW 7
#define IMPORT_FROM_CLSW 8
#define LANGUAGES_CLSG 2
#define LANGUAGE_CLSW 9
#define LANGUAGES_CLSW 10
#define SHOW_LANGUAGES_CLSW 11
#define TEST_LANGUAGE_CLSW 12
#define TEST_LANGUAGE_ON_CLSW 13
#define ANALYSIS_CLSG 3
#define CATALOGUE_CLSW 14
#define FUNCTIONS_CLSW 15
#define STRUCTURES_CLSW 16
#define ADVANCE_CLSW 17
#define GITIGNORE_CLSW 18
#define MAKEFILE_CLSW 19
#define WRITEME_CLSW 20
#define PLATFORM_CLSW 21
#define ADVANCE_FILE_CLSW 22
#define PROTOTYPE_CLSW 23
#define SCAN_CLSW 24
#define WEAVING_CLSG 4
#define WEAVE_CLSW 25
#define WEAVE_INTO_CLSW 26
#define WEAVE_TO_CLSW 27
#define OPEN_CLSW 28
#define WEAVE_AS_CLSW 29
#define WEAVE_TAG_CLSW 30
#define BREADCRUMB_CLSW 31
#define NAVIGATION_CLSW 32
#define TANGLING_CLSG 5
#define TANGLE_CLSW 33
#define TANGLE_TO_CLSW 34
#define CTAGS_TO_CLSW 35
#define CTAGS_CLSW 36
#define COLONIAL_CLSG 6
#define COLONY_CLSW 37
#define MEMBER_CLSW 38
#define EMBED_ASSET_METHOD 1
#define COPY_ASSET_METHOD 2
#define PRIVATE_COPY_ASSET_METHOD 3
#define COLLATE_ASSET_METHOD 4
#define LOOP_WITHIN_TANGLE(C, S, T)\
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)\
LOOP_OVER_LINKED_LIST(S, section, C->sections)\
if (S->sect_target == T)\
for (source_line *L = S->first_line; L; L = L->next_line)
#define NO_LCAT 0
#define BAR_LCAT 1
#define BEGIN_CODE_LCAT 2
#define BEGIN_DEFINITION_LCAT 3
#define C_LIBRARY_INCLUDE_LCAT 4
#define CHAPTER_HEADING_LCAT 5
#define CODE_BODY_LCAT 6
#define COMMAND_LCAT 7
#define COMMENT_BODY_LCAT 8
#define CONT_DEFINITION_LCAT 9
#define DEFINITIONS_LCAT 10
#define END_EXTRACT_LCAT 11
#define FOOTNOTE_TEXT_LCAT 12
#define HEADING_START_LCAT 13
#define INTERFACE_BODY_LCAT 14
#define INTERFACE_LCAT 15
#define MACRO_DEFINITION_LCAT 16
#define PARAGRAPH_START_LCAT 17
#define PREFORM_GRAMMAR_LCAT 18
#define PREFORM_LCAT 19
#define PURPOSE_BODY_LCAT 20
#define PURPOSE_LCAT 21
#define SECTION_HEADING_LCAT 22
#define SOURCE_DISPLAY_LCAT 23
#define TEXT_EXTRACT_LCAT 24
#define TYPEDEF_LCAT 25
#define NO_CMD 0
#define PAGEBREAK_CMD 1
#define GRAMMAR_INDEX_CMD 2
#define FIGURE_CMD 3
#define AUDIO_CMD 4
#define VIDEO_CMD 5
#define DOWNLOAD_CMD 6
#define CAROUSEL_CMD 7
#define CAROUSEL_ABOVE_CMD 8
#define CAROUSEL_BELOW_CMD 9
#define CAROUSEL_UNCAPTIONED_CMD 10
#define CAROUSEL_END_CMD 11
#define EMBED_CMD 12
#define TAG_CMD 13
#define HTML_CMD 14
#define ORDINARY_WEIGHT 0 /* an ordinary paragraph has this "weight" */
#define SUBHEADING_WEIGHT 1 /* a heading paragraph */
#define POINTS_PER_CM 72
#define BASIC_SECTIONCAT 1
#define STRUCTURES_SECTIONCAT 2
#define FUNCTIONS_SECTIONCAT 3
#define ELEMENT_ACCESS_USAGE 0x00000001 /* C-like languages: access via |->| or |.| operators to structure element */
#define FCALL_USAGE 0x00000002 /* C-like languages: function call made using brackets, |name(args)| */
#define PREFORM_IN_CODE_USAGE 0x00000004 /* InC only: use of a Preform nonterminal as a C "constant" */
#define PREFORM_IN_GRAMMAR_USAGE 0x00000008 /* InC only: ditto, but within Preform production rather than C code */
#define MISC_USAGE 0x00000010 /* any other appearance as an identifier */
#define ANY_USAGE 0x7fffffff /* any of the above */
#define HASH_TAB_SIZE 1000 /* the possible hash codes are 0 up to this minus 1 */
#define NUMBER_HASH 0 /* literal decimal integers, and no other words, have this hash code */
#define HASH_SAFETY_CODE 0x31415927
#define TRACE_COLLATER_EXECUTION FALSE /* set true for debugging */
#define MAX_TEMPLATE_LINES 8192 /* maximum number of lines in template */
#define CI_STACK_CAPACITY 8 /* maximum recursion of chapter/section iteration */
#define MODULE_LEVEL 1
#define CHAPTER_LEVEL 2
#define SECTION_LEVEL 3
#define IF_TRUE_LEVEL 4
#define IF_FALSE_LEVEL 5
#define COMMENTARY_MATERIAL 1
#define MACRO_MATERIAL 2
#define DEFINITION_MATERIAL 3
#define CODE_MATERIAL 4
#define ENDNOTES_MATERIAL 5
#define FOOTNOTES_MATERIAL 6
#define LOOP_OVER_PARAGRAPHS(C, S, T, P)\
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)\
LOOP_OVER_LINKED_LIST(S, section, C->sections)\
if (S->sect_target == T)\
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
#define MAX_EXTRACT_FILES 10
#define WHOLE_LINE_CRULE_RUN -1 /* This block applies to the whole snippet being coloured */
#define CHARACTERS_CRULE_RUN -2 /* This block applies to each character in turn */
#define CHARACTERS_IN_CRULE_RUN -3 /* This block applies to each character from a set in turn */
#define INSTANCES_CRULE_RUN -4 /* This block applies to each instance in turn */
#define MATCHES_CRULE_RUN -5 /* This block applies to each match against a regexp in turn */
#define BRACKETS_CRULE_RUN -6 /* This block applies to bracketed subexpressions in a regexp */
#define NOT_A_RULE_PREFIX 1 /* this isn't a prefix rule */
#define UNSPACED_RULE_PREFIX 2 /* for |prefix P| */
#define SPACED_RULE_PREFIX 3 /* for |spaced prefix P| */
#define OPTIONALLY_SPACED_RULE_PREFIX 4 /* for |optionally spaced prefix P| */
#define UNSPACED_RULE_SUFFIX 5 /* for |suffix P| */
#define SPACED_RULE_SUFFIX 6 /* for |spaced suffix P| */
#define OPTIONALLY_SPACED_RULE_SUFFIX 7 /* for |optionally spaced suffix P| */
#define MAX_ILDF_REGEXP_LENGTH 64
#define DEFINITION_COLOUR 'd'
#define FUNCTION_COLOUR 'f'
#define RESERVED_COLOUR 'r'
#define ELEMENT_COLOUR 'e'
#define IDENTIFIER_COLOUR 'i'
#define CHARACTER_COLOUR 'c'
#define CONSTANT_COLOUR 'n'
#define STRING_COLOUR 's'
#define PLAIN_COLOUR 'p'
#define EXTRACT_COLOUR 'x'
#define COMMENT_COLOUR '!'
#define NEWLINE_COLOUR '\n'
#define NOT_A_COLOUR ' '
#define UNQUOTED_COLOUR '_'
#define PARSE_TYPES_PAR_MTID 2
#define PARSE_FUNCTIONS_PAR_MTID 3
#define FURTHER_PARSING_PAR_MTID 4
#define SUBCATEGORISE_LINE_PAR_MTID 5
#define PARSE_COMMENT_TAN_MTID 6
#define SHEBANG_TAN_MTID 7
#define SUPPRESS_DISCLAIMER_TAN_MTID 8
#define ADDITIONAL_EARLY_MATTER_TAN_MTID 9
#define START_DEFN_TAN_MTID 10
#define PROLONG_DEFN_TAN_MTID 11
#define END_DEFN_TAN_MTID 12
#define ADDITIONAL_PREDECLARATIONS_TAN_MTID 13
#define SUPPRESS_EXPANSION_TAN_MTID 14
#define TANGLE_COMMAND_TAN_MTID 15
#define WILL_TANGLE_EXTRA_LINE_TAN_MTID 16
#define TANGLE_EXTRA_LINE_TAN_MTID 17
#define INSERT_LINE_MARKER_TAN_MTID 18
#define BEFORE_MACRO_EXPANSION_TAN_MTID 19
#define AFTER_MACRO_EXPANSION_TAN_MTID 20
#define OPEN_IFDEF_TAN_MTID 21
#define CLOSE_IFDEF_TAN_MTID 22
#define COMMENT_TAN_MTID 23
#define TANGLE_LINE_UNUSUALLY_TAN_MTID 24
#define GNABEHS_TAN_MTID 25
#define ADDITIONAL_TANGLING_TAN_MTID 26
#define BEGIN_WEAVE_WEA_MTID 27
#define SKIP_IN_WEAVING_WEA_MTID 28
#define RESET_SYNTAX_COLOURING_WEA_MTID 29
#define SYNTAX_COLOUR_WEA_MTID 30
#define WEAVE_CODE_LINE_WEA_MTID 31
#define NOTIFY_NEW_TAG_WEA_MTID 32
#define ANALYSIS_ANA_MTID 33
#define POST_ANALYSIS_ANA_MTID 34
#define SHARE_ELEMENT_ANA_MTID 35
#define UNSPACED_RULE_PREFIX 2 /* for |prefix P| */
#define SPACED_RULE_PREFIX 3 /* for |spaced prefix P| */
#define OPTIONALLY_SPACED_RULE_PREFIX 4 /* for |optionally spaced prefix P| */
#define UNSPACED_RULE_SUFFIX 5 /* for |suffix P| */
#define SPACED_RULE_SUFFIX 6 /* for |spaced suffix P| */
#define OPTIONALLY_SPACED_RULE_SUFFIX 7 /* for |optionally spaced suffix P| */
#define MAX_CONDITIONAL_COMPILATION_STACK 8
#define MAX_ARG_LINES 32 /* maximum number of lines over which a function's header can extend */
#define NOT_A_NONTERMINAL -4
#define A_FLEXIBLE_NONTERMINAL -3
#define A_VORACIOUS_NONTERMINAL -2
#define A_GRAMMAR_NONTERMINAL -1
#define INFINITE_WORD_COUNT 1000000000
#define MAX_PREFORM_RESULT_CLAUSES 10
#define SPACES_PER_TAB_IN_WOVEN_CODE 4
#define BEGIN_WEAVING_FOR_MTID 36
#define END_WEAVING_FOR_MTID 37
#define RENDER_FOR_MTID 38
#define PREFORM_DOCUMENT_FOR_MTID 39
#define POST_PROCESS_POS_MTID 40
#define POST_PROCESS_REPORT_POS_MTID 41
#define POST_PROCESS_SUBSTITUTE_POS_MTID 42
#define PDFTEX_TEX_FORM 1
#define NO_DEFINED_CLSW_VALUES 39
#define NO_DEFINED_DA_VALUES 4
#define NO_DEFINED_CLASS_VALUES 130
#define NO_DEFINED_MREASON_VALUES 5
#define NO_DEFINED_LOCALE_VALUES 2
#define NO_DEFINED_MTID_VALUES 42
#define NO_DEFINED_CLSF_VALUES 5
#define NO_DEFINED_CLSG_VALUES 7
#define NO_DEFINED_JSONTYPE_VALUES 8
#define NO_DEFINED_SEMVERPART_VALUES 3
#define NO_DEFINED_END_VALUES 4
#define NO_DEFINED_SYNTAX_VALUES 2
#define NO_DEFINED_MOM_VALUES 4
#define NO_DEFINED_MODE_VALUES 5
#define NO_DEFINED_SWM_VALUES 4
#define NO_DEFINED_METHOD_VALUES 4
#define NO_DEFINED_LCAT_VALUES 26
#define NO_DEFINED_CMD_VALUES 15
#define NO_DEFINED_SECTIONCAT_VALUES 3
#define NO_DEFINED_MATERIAL_VALUES 6
#define NO_DEFINED_FORM_VALUES 1
#line 41 "inweb/foundation-module/Chapter 2/Debugging Log.w"
typedef struct debugging_aspect {
struct text_stream *hyphenated_name; /* e.g., "memory-usage" */
struct text_stream *negated_name; /* e.g., "no-memory-usage" */
struct text_stream *unhyphenated_name; /* e.g., "memory usage" */
int on_or_off; /* whether or not active when writing to debugging log */
int alternate; /* whether or not active when writing in trace mode */
CLASS_DEFINITION
} debugging_aspect;
#line 58 "inweb/foundation-module/Chapter 2/Memory.w"
typedef struct allocation_status_structure {
/* actually needed for allocation purposes: */
int objects_allocated; /* total number of objects (or arrays) ever allocated */
void *first_in_memory; /* head of doubly linked list */
void *last_in_memory; /* tail of doubly linked list */
/* used only to provide statistics for the debugging log: */
char *name_of_type; /* e.g., |"index_lexicon_entry_CLASS"| */
int bytes_allocated; /* total allocation for this type of object, not counting overhead */
int objects_count; /* total number currently in existence (i.e., undeleted) */
int no_allocated_together; /* number of objects in each array of this type of object */
} allocation_status_structure;
#line 136 "inweb/foundation-module/Chapter 2/Memory.w"
typedef struct memblock_header {
int block_number;
struct memblock_header *next;
char *the_memory;
} memblock_header;
#line 217 "inweb/foundation-module/Chapter 2/Memory.w"
typedef struct memory_frame {
int integrity_check; /* this should always contain the |INTEGRITY_NUMBER| */
struct memory_frame *next_frame; /* next frame in the list of memory frames */
int mem_type; /* type of object stored in this frame */
int allocation_id; /* allocation ID number of object stored in this frame */
} memory_frame;
#line 743 "inweb/foundation-module/Chapter 2/Memory.w"
typedef struct general_pointer {
void *pointer_to_data;
int run_time_type_code;
} general_pointer;
#line 235 "inweb/foundation-module/Chapter 2/Streams.w"
typedef struct text_stream {
int stream_flags; /* bitmap of the |*_STRF| values above */
FILE *write_to_file; /* for an open stream, exactly one of these is |NULL| */
struct HTML_file_state *as_HTML; /* relevant only to the |HTML::| section */
wchar_t *write_to_memory;
struct filename *file_written; /* ditto */
int chars_written; /* number of characters sent, counting |\n| as 1 */
int chars_capacity; /* maximum number the stream can accept without claiming more resources */
struct text_stream *stream_continues; /* if one memory stream is extended by another */
} text_stream;
#line 27 "inweb/foundation-module/Chapter 2/Methods.w"
typedef struct method_set {
struct method *first_method;
CLASS_DEFINITION
} method_set;
#line 69 "inweb/foundation-module/Chapter 2/Methods.w"
typedef struct method {
int method_id;
void *method_function;
struct method *next_method;
CLASS_DEFINITION
} method;
#line 24 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
typedef struct linked_list_item {
void *item_contents;
struct linked_list_item *next_list_item;
} linked_list_item;
#line 15 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
typedef struct linked_list {
struct linked_list_item *first_list_item;
struct linked_list_item *last_list_item;
int linked_list_length;
int early_items_used;
struct linked_list_item early_items[NO_LL_EARLY_ITEMS];
CLASS_DEFINITION
} linked_list;
#line 13 "inweb/foundation-module/Chapter 2/Dictionaries.w"
typedef struct dictionary {
int textual; /* values are texts? */
int no_entries; /* total number of key-value pairs currently stored here */
int hash_table_size; /* size of array... */
struct dict_entry *hash_table; /* ...of linked lists of dictionary entries */
CLASS_DEFINITION
} dictionary;
#line 21 "inweb/foundation-module/Chapter 2/Dictionaries.w"
typedef struct dict_entry {
int vacant; /* a "vacant" entry is not currently used to store a k-v pair */
struct text_stream *key; /* for non-vacant entries only: the key text */
void *value; /* for non-vacant entries only: the value, some kind of pointer */
struct dict_entry *next_in_entry;
} dict_entry;
#line 11 "inweb/foundation-module/Chapter 2/Trees.w"
typedef struct heterogeneous_tree {
struct tree_type *type;
struct tree_node *root;
CLASS_DEFINITION
} heterogeneous_tree;
#line 26 "inweb/foundation-module/Chapter 2/Trees.w"
typedef struct tree_node {
struct heterogeneous_tree *owner;
struct tree_node_type *type;
struct general_pointer content;
struct tree_node *next;
struct tree_node *parent;
struct tree_node *child;
CLASS_DEFINITION
} tree_node;
#line 74 "inweb/foundation-module/Chapter 2/Trees.w"
typedef struct tree_type {
struct text_stream *name;
int (*verify_root)(struct tree_node *); /* function to vet the root node */
CLASS_DEFINITION
} tree_type;
#line 92 "inweb/foundation-module/Chapter 2/Trees.w"
typedef struct tree_node_type {
struct text_stream *node_type_name; /* text such as |TL_IS_0| */
int required_CLASS; /* if any; or negative for no restriction */
int (*verify_children)(struct tree_node *); /* function to vet the children */
CLASS_DEFINITION
} tree_node_type;
#line 38 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
typedef struct command_line_switch {
int switch_id;
struct text_stream *switch_name; /* e.g., |no-verbose| */
struct text_stream *switch_sort_name; /* e.g., |verbose| */
struct text_stream *help_text;
int valency; /* 1 for bare, 2 for one argument follows */
int form; /* one of the |*_CLSF| values above */
int switch_group; /* one of the |*_CLSG| valyes above */
int active_by_default; /* relevant only for booleans */
struct command_line_switch *negates; /* relevant only for booleans */
CLASS_DEFINITION
} command_line_switch;
#line 171 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
typedef struct clf_reader_state {
void *state;
void (*f)(int, int, text_stream *, void *);
void (*g)(int, text_stream *, void *);
int subs;
int nrt;
} clf_reader_state;
#line 38 "inweb/foundation-module/Chapter 3/Pathnames.w"
typedef struct pathname {
struct text_stream *intermediate;
struct pathname *pathname_of_parent;
int known_to_exist; /* corresponds to a directory in the filing system */
CLASS_DEFINITION
} pathname;
#line 12 "inweb/foundation-module/Chapter 3/Filenames.w"
typedef struct filename {
struct pathname *pathname_of_location;
struct text_stream *leafname;
CLASS_DEFINITION
} filename;
#line 8 "inweb/foundation-module/Chapter 3/Directories.w"
typedef struct scan_directory {
void *directory_handle;
char directory_name_written_out[4*MAX_FILENAME_LENGTH];
CLASS_DEFINITION
} scan_directory;
#line 129 "inweb/foundation-module/Chapter 3/Time.w"
typedef struct stopwatch_timer {
int running; /* set if this has been started but not stopped */
struct text_stream *event;
clock_t start_time;
clock_t end_time;
int time_taken; /* measured in centiseconds of CPU time */
linked_list *stages_chronological; /* of |stopwatch_timer| */
linked_list *stages_sorted; /* of |stopwatch_timer| */
CLASS_DEFINITION
} stopwatch_timer;
#line 123 "inweb/foundation-module/Chapter 4/C Strings.w"
typedef struct string_storage_area {
char *storage_at;
int capacity;
CLASS_DEFINITION
} string_storage_area;
#line 159 "inweb/foundation-module/Chapter 4/String Manipulation.w"
typedef struct string_position {
struct text_stream *S;
int index;
} string_position;
#line 228 "inweb/foundation-module/Chapter 4/Text Files.w"
typedef struct unicode_file_buffer {
char unicode_feed_buffer[32]; /* holds a single escape such as "[unicode 3106]" */
int ufb_counter; /* position in the unicode feed buffer */
} unicode_file_buffer;
#line 39 "inweb/foundation-module/Chapter 4/Text Files.w"
typedef struct text_file_position {
struct filename *text_file_filename;
FILE *handle_when_open;
struct unicode_file_buffer ufb;
int line_count; /* counting from 1 */
int line_position;
int skip_terminator;
int actively_scanning; /* whether we are still interested in the rest of the file */
} text_file_position;
#line 71 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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;
#line 56 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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;
wchar_t comment_character;
} preprocessor_state;
#line 471 "inweb/foundation-module/Chapter 4/Preprocessor.w"
typedef struct preprocessor_variable {
struct text_stream *name;
struct text_stream *value;
CLASS_DEFINITION
} preprocessor_variable;
#line 491 "inweb/foundation-module/Chapter 4/Preprocessor.w"
typedef struct preprocessor_variable_set {
struct linked_list *variables; /* of |preprocessor_variable| */
struct preprocessor_variable_set *outer;
CLASS_DEFINITION
} preprocessor_variable_set;
#line 564 "inweb/foundation-module/Chapter 4/Preprocessor.w"
typedef struct preprocessor_macro {
/* syntax */
struct text_stream *identifier;
struct preprocessor_macro_parameter *parameters[MAX_PP_MACRO_PARAMETERS];
int no_parameters;
/* meaning */
struct text_stream *lines[MAX_PP_MACRO_LINES];
int no_lines;
void (*expander)(struct preprocessor_macro *, struct preprocessor_state *, struct text_stream **, struct preprocessor_loop *, struct text_file_position *);
/* loop construct if any */
int begins_loop; /* |TRUE| for e.g. |repeat-block| or |repeat-span| */
int ends_loop; /* |TRUE| for e.g. |end-repeat-block| */
struct text_stream *loop_name; /* e.g. |repeat| */
int span; /* |TRUE| for e.g. |end-repeat-span| or |repeat-span| */
/* textual behaviour */
int suppress_newline_after_expanding;
int suppress_whitespace_when_expanding;
CLASS_DEFINITION
} preprocessor_macro;
#line 588 "inweb/foundation-module/Chapter 4/Preprocessor.w"
typedef struct preprocessor_macro_parameter {
struct text_stream *name;
struct text_stream *definition_token;
int optional;
CLASS_DEFINITION
} preprocessor_macro_parameter;
#line 42 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
typedef struct match_trie {
int match_character; /* or one of the special cases above */
wchar_t group_characters[MAX_TRIE_GROUP_SIZE+1];
wchar_t *match_outcome;
struct match_trie *on_success;
struct match_trie *next;
} match_trie;
#line 284 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
typedef struct match_avinue {
struct match_trie *the_trie;
struct match_avinue *next;
} match_avinue;
#line 109 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
typedef struct match_position {
int tpos; /* position within text being matched */
int ppos; /* position within pattern */
int bc; /* count of bracketed subexpressions so far begun */
int bl; /* bracket indentation level */
int bracket_nesting[MAX_BRACKETED_SUBEXPRESSIONS];
/* which subexpression numbers (0, 1, 2, 3) correspond to which nesting */
int brackets_start[MAX_BRACKETED_SUBEXPRESSIONS], brackets_end[MAX_BRACKETED_SUBEXPRESSIONS];
/* positions in text being matched, inclusive */
} match_position;
#line 126 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
typedef struct match_result {
wchar_t match_text_storage[MATCH_TEXT_INITIAL_ALLOCATION];
struct text_stream match_text_struct;
} match_result;
#line 130 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
typedef struct match_results {
int no_matched_texts;
struct match_result exp_storage[MAX_BRACKETED_SUBEXPRESSIONS];
struct text_stream *exp[MAX_BRACKETED_SUBEXPRESSIONS];
int exp_at[MAX_BRACKETED_SUBEXPRESSIONS];
} match_results;
#line 64 "inweb/foundation-module/Chapter 4/JSON.w"
typedef struct JSON_value {
int JSON_type;
int if_integer;
double if_double;
struct text_stream *if_string;
int if_boolean;
struct linked_list *if_list; /* of |JSON_value| */
struct dictionary *dictionary_if_object; /* to |JSON_value| */
struct linked_list *list_if_object; /* of |text_stream| */
struct text_stream *if_error;
CLASS_DEFINITION
} JSON_value;
#line 595 "inweb/foundation-module/Chapter 4/JSON.w"
typedef struct JSON_requirement {
struct linked_list *alternatives; /* of |JSON_single_requirement| */
CLASS_DEFINITION
} JSON_requirement;
#line 619 "inweb/foundation-module/Chapter 4/JSON.w"
typedef struct JSON_single_requirement {
struct JSON_requirement *this_requirement;
struct JSON_value *this_value;
struct JSON_type *this_type;
CLASS_DEFINITION
} JSON_single_requirement;
#line 657 "inweb/foundation-module/Chapter 4/JSON.w"
typedef struct JSON_type {
int JSON_type;
struct linked_list *if_list; /* of |JSON_requirement| */
struct JSON_requirement *all_if_list;
struct dictionary *dictionary_if_object; /* to |JSON_pair_requirement| */
struct linked_list *list_if_object; /* of |text_stream| */
struct text_stream *if_error;
CLASS_DEFINITION
} JSON_type;
#line 670 "inweb/foundation-module/Chapter 4/JSON.w"
typedef struct JSON_pair_requirement {
struct JSON_requirement *req;
int optional;
CLASS_DEFINITION
} JSON_pair_requirement;
#line 1340 "inweb/foundation-module/Chapter 4/JSON.w"
typedef struct JSON_rrf_state {
struct text_stream *name;
struct text_stream *defn;
struct dictionary *dict;
struct text_file_position at;
} JSON_rrf_state;
#line 56 "inweb/foundation-module/Chapter 5/HTML.w"
typedef struct HTML_file_state {
int XHTML_flag; /* writing strict XHTML for use in epubs */
struct lifo_stack *tag_stack; /* of |HTML_tag|: those currently open */
int CSS_included;
int JS_included;
CLASS_DEFINITION
} HTML_file_state;
#line 79 "inweb/foundation-module/Chapter 5/HTML.w"
typedef struct HTML_tag {
char *tag_name;
int tag_xref;
char *from_filename;
int from_line;
CLASS_DEFINITION
} HTML_tag;
#line 699 "inweb/foundation-module/Chapter 5/HTML.w"
typedef struct colour_translation {
wchar_t *chip_name;
wchar_t *html_colour;
} colour_translation;
#line 23 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
typedef struct ebook {
struct linked_list *metadata_list; /* of |ebook_datum|: DCMI-standard bibliographic data */
char *prefix; /* to apply to the page leafnames */
struct filename *CSS_file_throughout; /* where to find a CSS file to be used for all volumes */
struct filename *eventual_epub; /* filename of the final |*.epub| to be made */
struct pathname *holder; /* directory to put the ingredients into */
struct pathname *OEBPS_path; /* subdirectory which mysteriously has to be called |OEBPS| */
struct linked_list *ebook_volume_list; /* of |ebook_volume| */
struct ebook_volume *current_volume; /* the one to which chapters are now being added */
struct linked_list *ebook_chapter_list; /* of |ebook_chapter| */
struct ebook_chapter *current_chapter; /* the one to which pages are now being added */
struct linked_list *ebook_page_list; /* of |book_page| */
struct linked_list *ebook_image_list; /* of |ebook_image| */
CLASS_DEFINITION
} ebook;
#line 48 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
typedef struct ebook_datum {
struct text_stream *key;
struct text_stream *value;
CLASS_DEFINITION
} ebook_datum;
#line 57 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
typedef struct ebook_volume {
struct text_stream *volume_title;
struct ebook_page *volume_starts; /* on which page the volume starts */
struct filename *CSS_file; /* where to find the CSS file to be included */
CLASS_DEFINITION
} ebook_volume;
#line 64 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
typedef struct ebook_chapter {
struct text_stream *chapter_title;
struct ebook_volume *in_volume; /* to which volume this chapter belongs */
struct ebook_page *chapter_starts; /* on which page the chapter starts */
struct linked_list *ebook_mark_list; /* of |ebook_mark|: for when multiple navigable points exist within this */
struct text_stream *start_URL;
CLASS_DEFINITION
} ebook_chapter;
#line 77 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
typedef struct ebook_page {
struct text_stream *page_title;
struct text_stream *page_type;
struct text_stream *page_ID;
struct filename *relative_URL; /* eventual URL of this page within the ebook */
struct ebook_volume *in_volume; /* to which volume this page belongs */
struct ebook_chapter *in_chapter; /* to which chapter this page belongs */
int nav_entry_written; /* keep track of what we've written to the navigation tree */
CLASS_DEFINITION
} ebook_page;
#line 91 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
typedef struct ebook_mark {
struct text_stream *mark_text;
struct text_stream *mark_URL;
CLASS_DEFINITION
} ebook_mark;
#line 97 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
typedef struct ebook_image {
struct text_stream *image_ID;
struct filename *relative_URL; /* eventual URL of this image within the ebook */
CLASS_DEFINITION
} ebook_image;
#line 60 "inweb/foundation-module/Chapter 7/Version Numbers.w"
typedef struct semantic_version_number {
int version_numbers[SEMVER_NUMBER_DEPTH];
struct linked_list *prerelease_segments; /* of |text_stream| */
struct text_stream *build_metadata;
} semantic_version_number;
#line 66 "inweb/foundation-module/Chapter 7/Version Numbers.w"
typedef struct semantic_version_number_holder {
struct semantic_version_number version;
CLASS_DEFINITION
} semantic_version_number_holder;
#line 24 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
typedef struct range_end {
int end_type;
struct semantic_version_number end_value;
} range_end;
#line 29 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
typedef struct semver_range {
struct range_end lower;
struct range_end upper;
CLASS_DEFINITION
} semver_range;
#line 27 "inweb/foundation-module/Chapter 8/Web Structure.w"
typedef struct web_md {
struct pathname *path_to_web; /* relative to the current working directory */
struct filename *single_file; /* relative to the current working directory */
struct linked_list *bibliographic_data; /* of |web_bibliographic_datum| */
struct semantic_version_number version_number; /* as deduced from bibliographic data */
int default_syntax; /* which version syntax the sections will have */
int chaptered; /* has the author explicitly divided it into named chapters? */
struct text_stream *main_language_name; /* in which most of the sections are written */
struct module *as_module; /* the root of a small dependency graph */
struct filename *contents_filename; /* or |NULL| for a single-file web */
struct linked_list *tangle_target_names; /* of |text_stream| */
struct linked_list *header_filenames; /* of |filename| */
struct linked_list *chapters_md; /* of |chapter_md| */
struct linked_list *sections_md; /* of |section_md| */
CLASS_DEFINITION
} web_md;
#line 50 "inweb/foundation-module/Chapter 8/Web Structure.w"
typedef struct chapter_md {
struct text_stream *ch_range; /* e.g., |P| for Preliminaries, |7| for Chapter 7, |C| for Appendix C */
struct text_stream *ch_title; /* e.g., "Chapter 3: Fresh Water Fish" */
struct text_stream *ch_basic_title; /* e.g., "Chapter 3" */
struct text_stream *ch_decorated_title; /* e.g., "Fresh Water Fish" */
struct text_stream *rubric; /* optional; without double-quotation marks */
struct text_stream *ch_language_name; /* in which most of the sections are written */
int imported; /* from a different web? */
struct linked_list *sections_md; /* of |section_md| */
CLASS_DEFINITION
} chapter_md;
#line 68 "inweb/foundation-module/Chapter 8/Web Structure.w"
typedef struct section_md {
struct text_stream *sect_title; /* e.g., "Program Control" */
struct text_stream *sect_range; /* e.g., "2/ct" */
int using_syntax; /* which syntax the web is written in */
int is_a_singleton; /* is this the only section in its entire web? */
struct filename *source_file_for_section;
struct text_stream *tag_name;
struct text_stream *sect_independent_language;
struct text_stream *sect_language_name;
struct text_stream *titling_line_to_insert;
struct module *owning_module;
CLASS_DEFINITION
} section_md;
#line 246 "inweb/foundation-module/Chapter 8/Web Structure.w"
typedef struct reader_state {
struct web_md *Wm;
struct filename *contents_filename;
int in_biblio;
int in_purpose; /* Reading the bit just after the new chapter? */
struct chapter_md *chapter_being_scanned;
struct text_stream *chapter_dir_name; /* Where sections in the current chapter live */
struct text_stream *titling_line_to_insert; /* To be inserted automagically */
struct pathname *path_to; /* Where web material is being read from */
struct module *reading_from;
struct module_search *import_from; /* Where imported webs are */
struct pathname *path_to_inweb;
int scan_verbosely;
int including_modules;
int main_web_not_module; /* Reading the original web, or an included one? */
int halt_at_at; /* Used for reading contents pages of single-file webs */
int halted; /* Set when such a halt has occurred */
int section_count;
struct section_md *last_section;
} reader_state;
#line 11 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
typedef struct web_bibliographic_datum {
struct text_stream *key;
struct text_stream *value;
int declaration_permitted; /* is the contents page of the web allowed to set this? */
int declaration_mandatory; /* is it positively required to? */
int on_or_off; /* boolean: which we handle as the string "On" or "Off" */
struct web_bibliographic_datum *alias;
CLASS_DEFINITION
} web_bibliographic_datum;
#line 19 "inweb/foundation-module/Chapter 8/Web Modules.w"
typedef struct module {
struct pathname *module_location;
struct text_stream *module_name;
struct linked_list *dependencies; /* of |module|: which other modules does this need? */
struct text_stream *module_tag;
int origin_marker; /* one of the |*_MOM| values above */
struct linked_list *chapters_md; /* of |chapter_md|: just the ones in this module */
struct linked_list *sections_md; /* of |section_md|: just the ones in this module */
CLASS_DEFINITION
} module;
#line 73 "inweb/foundation-module/Chapter 8/Web Modules.w"
typedef struct module_search {
struct pathname *path_to_search;
CLASS_DEFINITION
} module_search;
#line 21 "inweb/foundation-module/Chapter 8/Build Files.w"
typedef struct build_file_data {
struct text_stream *prerelease_text;
struct text_stream *build_code;
struct text_stream *build_date;
} build_file_data;
#line 20 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
typedef struct simple_tangle_docket {
void (*raw_callback)(struct text_stream *, struct simple_tangle_docket *);
void (*command_callback)(struct text_stream *, struct text_stream *,
struct text_stream *, struct simple_tangle_docket *);
void (*bplus_callback)(struct text_stream *, struct simple_tangle_docket *);
void (*error_callback)(char *, struct text_stream *);
void *state;
struct pathname *web_path;
} simple_tangle_docket;
#line 11 "inweb/Chapter 1/Configuration.w"
typedef struct inweb_instructions {
int inweb_mode; /* our main mode of operation: one of the |*_MODE| constants */
struct pathname *chosen_web; /* project folder relative to cwd */
struct filename *chosen_file; /* or, single file relative to cwd */
struct text_stream *chosen_range; /* which subset of this web we apply to (often, all of it) */
int chosen_range_actually_chosen; /* rather than being a default choice */
int swarm_mode; /* relevant to weaving only: one of the |*_SWARM| constants */
struct text_stream *tag_setting; /* |-weave-tag X|: weave, but only the material tagged X */
struct text_stream *weave_pattern; /* |-weave-as X|: for example, |-weave-to HTML| */
int show_languages_switch; /* |-show-languages|: print list of available PLs */
int catalogue_switch; /* |-catalogue|: print catalogue of sections */
int functions_switch; /* |-functions|: print catalogue of functions within sections */
int structures_switch; /* |-structures|: print catalogue of structures within sections */
int advance_switch; /* |-advance-build|: advance build file for web */
int scan_switch; /* |-scan|: simply show the syntactic scan of the source */
int ctags_switch; /* |-ctags|: generate a set of Universal Ctags on each tangle */
struct filename *weave_to_setting; /* |-weave-to X|: the pathname X, if supplied */
struct pathname *weave_into_setting; /* |-weave-into X|: the pathname X, if supplied */
int sequential; /* give the sections sequential sigils */
struct filename *tangle_setting; /* |-tangle-to X|: the pathname X, if supplied */
struct filename *ctags_setting; /* |-ctags-to X|: the pathname X, if supplied */
struct filename *makefile_setting; /* |-makefile X|: the filename X, if supplied */
struct filename *gitignore_setting; /* |-gitignore X|: the filename X, if supplied */
struct filename *advance_setting; /* |-advance-build-file X|: advance build file X */
struct filename *writeme_setting; /* |-write-me X|: advance build file X */
struct filename *prototype_setting; /* |-prototype X|: the pathname X, if supplied */
struct filename *navigation_setting; /* |-navigation X|: the filename X, if supplied */
struct filename *colony_setting; /* |-colony X|: the filename X, if supplied */
struct text_stream *member_setting; /* |-member X|: sets web to member X of colony */
struct linked_list *breadcrumb_setting; /* of |breadcrumb_request| */
struct text_stream *platform_setting; /* |-platform X|: sets prevailing platform to X */
int verbose_switch; /* |-verbose|: print names of files read to stdout */
int targets; /* used only for parsing */
struct programming_language *test_language_setting; /* |-test-language X| */
struct filename *test_language_on_setting; /* |-test-language-on X| */
struct pathname *import_setting; /* |-import X|: where to find imported webs */
} inweb_instructions;
#line 70 "inweb/Chapter 1/The Swarm.w"
typedef struct weave_order {
struct web *weave_web; /* which web we weave */
struct text_stream *weave_range; /* which parts of the web in this weave */
struct theme_tag *theme_match; /* pick out only paragraphs with this theme */
struct text_stream *booklet_title;
struct weave_pattern *pattern; /* which pattern is to be followed */
struct filename *weave_to; /* where to put it */
struct weave_format *format; /* plain text, say, or HTML */
void *post_processing_results; /* optional typesetting diagnostics after running through */
int self_contained; /* make a self-contained file if possible */
struct linked_list *breadcrumbs; /* non-standard breadcrumb trail, if any */
struct filename *navigation; /* navigation links, or |NULL| if not supplied */
struct linked_list *plugins; /* of |weave_plugin|: these are for HTML extensions */
struct linked_list *colour_schemes; /* of |colour_scheme|: these are for HTML */
/* used for workspace during an actual weave: */
struct source_line *current_weave_line;
CLASS_DEFINITION
} weave_order;
#line 11 "inweb/Chapter 1/Patterns.w"
typedef struct weave_pattern {
struct text_stream *pattern_name; /* such as |HTML| */
struct pathname *pattern_location; /* the directory */
struct weave_pattern *based_on; /* inherit from which other pattern? */
struct weave_format *pattern_format; /* such as |DVI|: the desired final format */
struct linked_list *plugins; /* of |weave_plugin|: any extras needed */
struct linked_list *colour_schemes; /* of |colour_scheme|: any extras needed */
struct text_stream *mathematics_plugin; /* name only, not a |weave_pattern *| */
struct text_stream *footnotes_plugin; /* name only, not a |weave_pattern *| */
struct text_stream *initial_extension; /* filename extension, that is */
struct linked_list *post_commands; /* of |text_stream| */
struct linked_list *blocked_templates; /* of |text_stream| */
struct linked_list *asset_rules; /* of |asset_rule| */
int show_abbrevs; /* show section range abbreviations in the weave? */
int number_sections; /* insert section numbers into the weave? */
struct text_stream *default_range; /* for example, |sections| */
struct web *patterned_for; /* the web which caused this to be read in */
int commands;
int name_command_given;
CLASS_DEFINITION
} weave_pattern;
#line 12 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
typedef struct weave_plugin {
struct text_stream *plugin_name;
int last_included_in_round;
CLASS_DEFINITION
} weave_plugin;
#line 34 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
typedef struct colour_scheme {
struct text_stream *scheme_name;
struct text_stream *prefix;
struct filename *at;
int last_included_in_round;
CLASS_DEFINITION
} colour_scheme;
#line 168 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
typedef struct asset_rule {
struct text_stream *applies_to;
int method; /* one of the |*_ASSET_METHOD| values above */
struct text_stream *pre;
struct text_stream *post;
int transform_names;
CLASS_DEFINITION
} asset_rule;
#line 348 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
typedef struct css_file_transformation {
struct text_stream *OUT;
struct text_stream *trans;
} css_file_transformation;
#line 28 "inweb/Chapter 2/The Reader.w"
typedef struct web {
struct web_md *md;
struct linked_list *chapters; /* of |chapter| (including Sections, Preliminaries, etc.) */
int web_extent; /* total lines in literate source, excluding contents */
int no_paragraphs; /* this will be at least 1 */
struct programming_language *main_language; /* in which most of the sections are written */
struct linked_list *tangle_targets; /* of |tangle_target| */
struct linked_list *headers; /* of |filename|: additional header files */
int analysed; /* has this been scanned for function usage and such? */
struct linked_list *language_types; /* of |language_type|: used only for C-like languages */
struct ebook *as_ebook; /* when being woven to an ebook */
struct pathname *redirect_weaves_to; /* ditto */
CLASS_DEFINITION
} web;
#line 51 "inweb/Chapter 2/The Reader.w"
typedef struct chapter {
struct chapter_md *md;
struct web *owning_web;
struct linked_list *sections; /* of |section| */
struct weave_order *ch_weave; /* |NULL| unless this chapter produces a weave of its own */
int titling_line_inserted; /* has an interleaved chapter heading been added yet? */
struct programming_language *ch_language; /* in which this chapter is written */
CLASS_DEFINITION
} chapter;
#line 65 "inweb/Chapter 2/The Reader.w"
typedef struct section {
struct section_md *md;
struct web *owning_web;
struct chapter *owning_chapter;
struct text_stream *sect_namespace; /* e.g., "Text::Languages::" */
struct text_stream *sect_purpose; /* e.g., "To manage the zoo, and feed all penguins" */
int barred; /* if version 1 syntax, contains a dividing bar? */
struct programming_language *sect_language; /* in which this section is written */
struct tangle_target *sect_target; /* |NULL| unless this section produces a tangle of its own */
struct weave_order *sect_weave; /* |NULL| unless this section produces a weave of its own */
int sect_extent; /* total number of lines in this section */
struct source_line *first_line; /* for efficiency's sake not held as a |linked_list|, */
struct source_line *last_line; /* but that's what it is, all the same */
int sect_paragraphs; /* total number of paragraphs in this section */
struct linked_list *paragraphs; /* of |paragraph|: the content of this section */
struct theme_tag *tag_with; /* automatically tag paras in this section thus */
struct linked_list *macros; /* of |para_macro|: those defined in this section */
int scratch_flag; /* temporary workspace */
int paused_until_at; /* ignore the top half of the file, until the first |@| sign */
int printed_number; /* temporary again: sometimes used in weaving */
CLASS_DEFINITION
} section;
#line 257 "inweb/Chapter 3/The Analyser.w"
typedef struct hash_table {
struct linked_list *analysis_hash[HASH_TAB_SIZE]; /* of |hash_table_entry| */
int safety_code; /* when we start up, array's contents are undefined, so... */
} hash_table;
#line 384 "inweb/Chapter 2/The Reader.w"
typedef struct tangle_target {
struct programming_language *tangle_language; /* common to the entire contents */
struct hash_table symbols; /* a table of identifiable names in this program */
CLASS_DEFINITION
} tangle_target;
#line 20 "inweb/Chapter 2/Line Categories.w"
typedef struct source_line {
struct text_stream *text; /* the text as read in */
struct text_stream *text_operand; /* meaning depends on category */
struct text_stream *text_operand2; /* meaning depends on category */
int category; /* what sort of line this is: an |*_LCAT| value */
int command_code; /* used only for |COMMAND_LCAT| lines: a |*_CMD| value */
int default_defn; /* used only for |BEGIN_DEFINITION_LCAT| lines */
int plainer; /* used only for |BEGIN_CODE_LCAT| lines: suppresses box */
int enable_hyperlinks; /* used only for |CODE_BODY_LCAT| lines: link URLs in weave */
struct programming_language *colour_as; /* used only for |TEXT_EXTRACT_LCAT| lines */
struct text_stream *extract_to; /* used only for |TEXT_EXTRACT_LCAT| lines */
int is_commentary; /* flag */
struct language_function *function_defined; /* if any C-like function is defined on this line */
struct preform_nonterminal *preform_nonterminal_defined; /* similarly */
int suppress_tangling; /* if e.g., lines are tangled out of order */
int interface_line_identified; /* only relevant during parsing of Interface lines */
struct footnote *footnote_text; /* which fn this is the text of, if it is at all */
struct text_file_position source; /* which file this was read in from, if any */
struct section *owning_section; /* for interleaved title lines, it's the one about to start */
struct source_line *next_line; /* within the owning section's linked list */
struct paragraph *owning_paragraph; /* for lines falling under paragraphs; |NULL| if not */
} source_line;
#line 756 "inweb/Chapter 2/The Parser.w"
typedef struct paragraph {
int above_bar; /* placed above the dividing bar in its section (in Version 1 syntax) */
int placed_early; /* should appear early in the tangled code */
int placed_very_early; /* should appear very early in the tangled code */
int invisible; /* do not render paragraph number */
struct text_stream *heading_text; /* if any - many paras have none */
struct text_stream *ornament; /* a "P" for a pilcrow or "S" for section-marker */
struct text_stream *paragraph_number; /* used in combination with the ornament */
int next_child_number; /* used when working out paragraph numbers */
struct paragraph *parent_paragraph; /* ditto */
int weight; /* typographic prominence: one of the |*_WEIGHT| values */
int starts_on_new_page; /* relevant for weaving to TeX only, of course */
struct para_macro *defines_macro; /* there can only be one */
struct linked_list *functions; /* of |function|: those defined in this para */
struct linked_list *structures; /* of |language_type|: similarly */
struct linked_list *taggings; /* of |paragraph_tagging| */
struct linked_list *footnotes; /* of |footnote| */
struct source_line *first_line_in_paragraph;
struct section *under_section;
CLASS_DEFINITION
} paragraph;
#line 874 "inweb/Chapter 2/The Parser.w"
typedef struct footnote {
int footnote_cue_number; /* used only for |FOOTNOTE_TEXT_LCAT| lines */
int footnote_text_number; /* used only for |FOOTNOTE_TEXT_LCAT| lines */
struct text_stream *cue_text;
int cued_already;
CLASS_DEFINITION
} footnote;
#line 8 "inweb/Chapter 2/Paragraph Macros.w"
typedef struct para_macro {
struct text_stream *macro_name; /* usually long, like "Create a paragraph macro here" */
struct paragraph *defining_paragraph; /* as printed in small type after the name in any usage */
struct source_line *defn_start; /* it ends at the end of its defining paragraph */
struct linked_list *macro_usages; /* of |macro_usage|: only computed for weaves */
CLASS_DEFINITION
} para_macro;
#line 10 "inweb/Chapter 2/Tags.w"
typedef struct theme_tag {
struct text_stream *tag_name;
int ifdef_positive;
struct text_stream *ifdef_symbol;
CLASS_DEFINITION
} theme_tag;
#line 50 "inweb/Chapter 2/Tags.w"
typedef struct paragraph_tagging {
struct theme_tag *the_tag;
struct text_stream *caption;
CLASS_DEFINITION
} paragraph_tagging;
#line 14 "inweb/Chapter 2/Enumerated Constants.w"
typedef struct enumeration_set {
struct text_stream *postfix;
struct text_stream *stub;
int first_value;
int next_free_value;
struct source_line *last_observed_at;
CLASS_DEFINITION
} enumeration_set;
#line 61 "inweb/Chapter 2/Paragraph Numbering.w"
typedef struct macro_usage {
struct paragraph *used_in_paragraph;
int multiplicity; /* for example, 2 if it's used twice in this paragraph */
CLASS_DEFINITION
} macro_usage;
#line 270 "inweb/Chapter 3/The Analyser.w"
typedef struct hash_table_entry {
text_stream *hash_key;
int language_reserved_word; /* in the language currently being woven, that is */
struct linked_list *usages; /* of |hash_table_entry_usage| */
struct source_line *definition_line; /* or null, if it's not a constant, function or type name */
struct language_function *as_function; /* for function names only */
CLASS_DEFINITION
} hash_table_entry;
#line 370 "inweb/Chapter 3/The Analyser.w"
typedef struct hash_table_entry_usage {
struct paragraph *usage_recorded_at;
int form_of_usage; /* bitmap of the |*_USAGE| constants defined above */
CLASS_DEFINITION
} hash_table_entry_usage;
#line 48 "inweb/Chapter 3/The Collater.w"
typedef struct collater_state {
struct web *for_web;
struct text_stream *tlines[MAX_TEMPLATE_LINES];
int no_tlines;
int repeat_stack_level[CI_STACK_CAPACITY];
struct linked_list_item *repeat_stack_variable[CI_STACK_CAPACITY];
struct linked_list_item *repeat_stack_threshold[CI_STACK_CAPACITY];
int repeat_stack_startpos[CI_STACK_CAPACITY];
int sp; /* And this is our stack pointer for tracking of loops */
struct text_stream *restrict_to_range;
struct weave_pattern *nav_pattern;
struct filename *nav_file;
struct linked_list *crumbs;
int inside_navigation_submenu;
struct filename *errors_at;
struct weave_order *wv;
struct filename *into_file;
struct linked_list *modules; /* of |module| */
} collater_state;
#line 113 "inweb/Chapter 3/The Weaver.w"
typedef struct weaver_state {
int kind_of_material; /* one of the enumerated |*_MATERIAL| constants above */
int line_break_pending; /* insert a line break before the next woven line? */
int next_heading_without_vertical_skip;
int horizontal_rule_just_drawn;
struct section *last_extract_from;
struct tree_node *body_node;
struct tree_node *chapter_node;
struct tree_node *section_node;
struct tree_node *para_node;
struct tree_node *carousel_node;
struct tree_node *material_node;
struct tree_node *ap;
} weaver_state;
#line 106 "inweb/Chapter 4/Programming Languages.w"
typedef struct programming_language {
text_stream *language_name; /* identifies it: see above */
/* then a great many fields set directly in the definition file: */
text_stream *file_extension; /* by default output to a file whose name has this extension */
text_stream *language_details; /* brief explanation of what language is */
int supports_namespaces;
text_stream *line_comment;
text_stream *whole_line_comment;
text_stream *multiline_comment_open;
text_stream *multiline_comment_close;
text_stream *string_literal;
text_stream *string_literal_escape;
text_stream *character_literal;
text_stream *character_literal_escape;
text_stream *binary_literal_prefix;
text_stream *octal_literal_prefix;
text_stream *hexadecimal_literal_prefix;
text_stream *negative_literal_prefix;
text_stream *shebang;
text_stream *line_marker;
text_stream *before_macro_expansion;
text_stream *after_macro_expansion;
text_stream *start_definition;
text_stream *prolong_definition;
text_stream *end_definition;
text_stream *start_ifdef;
text_stream *end_ifdef;
text_stream *start_ifndef;
text_stream *end_ifndef;
wchar_t type_notation[MAX_ILDF_REGEXP_LENGTH];
wchar_t function_notation[MAX_ILDF_REGEXP_LENGTH];
int suppress_disclaimer;
int C_like; /* languages with this set have access to extra features */
struct linked_list *reserved_words; /* of |reserved_word| */
struct hash_table built_in_keywords;
struct colouring_language_block *program; /* algorithm for syntax colouring */
struct method_set *methods;
CLASS_DEFINITION
} programming_language;
#line 156 "inweb/Chapter 4/Programming Languages.w"
typedef struct language_reader_state {
struct programming_language *defining;
struct colouring_language_block *current_block;
} language_reader_state;
#line 394 "inweb/Chapter 4/Programming Languages.w"
typedef struct colouring_language_block {
struct linked_list *rules; /* of |colouring_rule| */
struct colouring_language_block *parent; /* or |NULL| for the topmost one */
int run; /* one of the |*_CRULE_RUN| values, or else a colour */
struct text_stream *run_instance; /* used only for |INSTANCES_CRULE_RUN| */
struct text_stream *char_set; /* used only for |CHARACTERS_IN_CRULE_RUN| */
wchar_t match_regexp_text[MAX_ILDF_REGEXP_LENGTH]; /* used for |MATCHES_CRULE_RUN|, |BRACKETS_CRULE_RUN| */
/* workspace during painting */
struct match_results mr; /* of a regular expression */
CLASS_DEFINITION
} colouring_language_block;
#line 438 "inweb/Chapter 4/Programming Languages.w"
typedef struct colouring_rule {
/* the premiss: */
int sense; /* |FALSE| to negate the condition */
wchar_t match_colour; /* for |coloured C|, or else |NOT_A_COLOUR| */
wchar_t match_keyword_of_colour; /* for |keyword C|, or else |NOT_A_COLOUR| */
struct text_stream *match_text; /* or length 0 to mean "anything" */
int match_prefix; /* one of the |*_RULE_PREFIX| values above */
wchar_t match_regexp_text[MAX_ILDF_REGEXP_LENGTH];
int number; /* for |number N| rules; 0 for others */
int number_of; /* for |number N of M| rules; 0 for others */
/* the conclusion: */
struct colouring_language_block *execute_block; /* or |NULL|, in which case... */
wchar_t set_to_colour; /* ...paint the snippet in this colour */
wchar_t set_prefix_to_colour; /* ...also paint this (same for suffix) */
int debug; /* ...or print debugging text to console */
/* workspace during painting */
int fix_position; /* where the prefix or suffix started */
struct match_results mr; /* of a regular expression */
CLASS_DEFINITION
} colouring_rule;
#line 560 "inweb/Chapter 4/Programming Languages.w"
typedef struct reserved_word {
struct text_stream *word;
int colour;
CLASS_DEFINITION
} reserved_word;
#line 8 "inweb/Chapter 4/Types and Functions.w"
typedef struct language_type {
struct text_stream *structure_name;
int tangled; /* whether the structure definition has been tangled out */
struct source_line *structure_header_at; /* opening line of |typedef| */
struct source_line *typedef_ends; /* closing line, where |}| appears */
struct linked_list *incorporates; /* of |language_type| */
struct linked_list *elements; /* of |structure_element| */
struct language_type *next_cst_alphabetically;
CLASS_DEFINITION
} language_type;
#line 78 "inweb/Chapter 4/Types and Functions.w"
typedef struct structure_element {
struct text_stream *element_name;
struct source_line *element_created_at;
int allow_sharing;
CLASS_DEFINITION
} structure_element;
#line 112 "inweb/Chapter 4/Types and Functions.w"
typedef struct language_function {
struct text_stream *function_name; /* e.g., |"cultivate"| */
struct text_stream *function_type; /* e.g., |"tree *"| */
struct text_stream *function_arguments; /* e.g., |"int rainfall)"|: note |)| */
struct source_line *function_header_at; /* where the first line of the header begins */
int within_namespace; /* written using InC namespace dividers */
int called_from_other_sections;
int call_freely;
int usage_described;
int no_conditionals;
struct source_line *within_conditionals[MAX_CONDITIONAL_COMPILATION_STACK];
CLASS_DEFINITION
} language_function;
#line 105 "inweb/Chapter 4/InC Support.w"
typedef struct preform_nonterminal {
struct text_stream *nt_name; /* e.g., |<action-clause>| */
struct text_stream *unangled_name; /* e.g., |action-clause| */
struct text_stream *as_C_identifier; /* e.g., |action_clause_NTM| */
int as_function; /* defined internally, that is, parsed by a C language_function */
int voracious; /* a voracious nonterminal: see "The English Syntax of Inform" */
int min_word_count; /* for internals only */
int max_word_count;
int takes_pointer_result; /* right-hand formula defines |*XP|, not |*X| */
struct source_line *where_defined;
struct preform_nonterminal *next_pnt_alphabetically;
CLASS_DEFINITION
} preform_nonterminal;
#line 280 "inweb/Chapter 4/InC Support.w"
typedef struct nonterminal_variable {
struct text_stream *ntv_name; /* e.g., |"num"| */
struct text_stream *ntv_type; /* e.g., |"int"| */
struct text_stream *ntv_identifier; /* e.g., |"num_NTMV"| */
struct source_line *first_mention; /* first usage */
CLASS_DEFINITION
} nonterminal_variable;
#line 332 "inweb/Chapter 4/InC Support.w"
typedef struct text_literal {
struct text_stream *tl_identifier;
struct text_stream *tl_content;
CLASS_DEFINITION
} text_literal;
#line 6 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_document_node {
struct weave_order *wv;
CLASS_DEFINITION
} weave_document_node;
#line 11 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_head_node {
struct text_stream *banner;
CLASS_DEFINITION
} weave_head_node;
#line 16 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_body_node {
CLASS_DEFINITION
} weave_body_node;
#line 20 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_tail_node {
struct text_stream *rennab;
CLASS_DEFINITION
} weave_tail_node;
#line 25 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_chapter_header_node {
struct chapter *chap;
CLASS_DEFINITION
} weave_chapter_header_node;
#line 30 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_chapter_footer_node {
struct chapter *chap;
CLASS_DEFINITION
} weave_chapter_footer_node;
#line 35 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_section_header_node {
struct section *sect;
CLASS_DEFINITION
} weave_section_header_node;
#line 40 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_section_footer_node {
struct section *sect;
CLASS_DEFINITION
} weave_section_footer_node;
#line 45 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_section_purpose_node {
struct text_stream *purpose;
CLASS_DEFINITION
} weave_section_purpose_node;
#line 50 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_subheading_node {
struct text_stream *text;
CLASS_DEFINITION
} weave_subheading_node;
#line 55 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_bar_node {
CLASS_DEFINITION
} weave_bar_node;
#line 59 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_pagebreak_node {
CLASS_DEFINITION
} weave_pagebreak_node;
#line 63 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_linebreak_node {
CLASS_DEFINITION
} weave_linebreak_node;
#line 67 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_paragraph_heading_node {
struct paragraph *para;
int no_skip;
CLASS_DEFINITION
} weave_paragraph_heading_node;
#line 73 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_endnote_node {
CLASS_DEFINITION
} weave_endnote_node;
#line 77 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_figure_node {
struct text_stream *figname;
int w;
int h;
CLASS_DEFINITION
} weave_figure_node;
#line 84 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_extract_node {
struct text_stream *extract;
CLASS_DEFINITION
} weave_extract_node;
#line 89 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_audio_node {
struct text_stream *audio_name;
int w;
CLASS_DEFINITION
} weave_audio_node;
#line 95 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_video_node {
struct text_stream *video_name;
int w;
int h;
CLASS_DEFINITION
} weave_video_node;
#line 102 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_download_node {
struct text_stream *download_name;
struct text_stream *filetype;
CLASS_DEFINITION
} weave_download_node;
#line 108 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_material_node {
int material_type;
int plainly;
struct programming_language *styling;
struct text_stream *endnote;
CLASS_DEFINITION
} weave_material_node;
#line 116 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_embed_node {
struct text_stream *service;
struct text_stream *ID;
int w;
int h;
CLASS_DEFINITION
} weave_embed_node;
#line 124 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_pmac_node {
struct para_macro *pmac;
int defn;
CLASS_DEFINITION
} weave_pmac_node;
#line 130 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_vskip_node {
int in_comment;
CLASS_DEFINITION
} weave_vskip_node;
#line 135 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_chapter_node {
struct chapter *chap;
CLASS_DEFINITION
} weave_chapter_node;
#line 140 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_section_node {
struct section *sect;
CLASS_DEFINITION
} weave_section_node;
#line 145 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_code_line_node {
CLASS_DEFINITION
} weave_code_line_node;
#line 149 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_function_usage_node {
struct text_stream *url;
struct language_function *fn;
CLASS_DEFINITION
} weave_function_usage_node;
#line 155 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_commentary_node {
struct text_stream *text;
int in_code;
CLASS_DEFINITION
} weave_commentary_node;
#line 161 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_carousel_slide_node {
struct text_stream *caption;
int caption_command;
CLASS_DEFINITION
} weave_carousel_slide_node;
#line 167 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_toc_node {
struct text_stream *text1;
CLASS_DEFINITION
} weave_toc_node;
#line 172 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_toc_line_node {
struct text_stream *text1;
struct text_stream *text2;
struct paragraph *para;
CLASS_DEFINITION
} weave_toc_line_node;
#line 179 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_chapter_title_page_node {
CLASS_DEFINITION
} weave_chapter_title_page_node;
#line 183 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_defn_node {
struct text_stream *keyword;
CLASS_DEFINITION
} weave_defn_node;
#line 188 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_inline_node {
CLASS_DEFINITION
} weave_inline_node;
#line 192 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_locale_node {
struct paragraph *par1;
struct paragraph *par2;
CLASS_DEFINITION
} weave_locale_node;
#line 198 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_source_code_node {
struct text_stream *matter;
struct text_stream *colouring;
CLASS_DEFINITION
} weave_source_code_node;
#line 204 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_url_node {
struct text_stream *url;
struct text_stream *content;
int external;
CLASS_DEFINITION
} weave_url_node;
#line 211 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_footnote_cue_node {
struct text_stream *cue_text;
CLASS_DEFINITION
} weave_footnote_cue_node;
#line 216 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_begin_footnote_text_node {
struct text_stream *cue_text;
CLASS_DEFINITION
} weave_begin_footnote_text_node;
#line 221 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_display_line_node {
struct text_stream *text;
CLASS_DEFINITION
} weave_display_line_node;
#line 226 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_function_defn_node {
struct language_function *fn;
CLASS_DEFINITION
} weave_function_defn_node;
#line 231 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_item_node {
int depth;
struct text_stream *label;
CLASS_DEFINITION
} weave_item_node;
#line 237 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_grammar_index_node {
CLASS_DEFINITION
} weave_grammar_index_node;
#line 241 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_maths_node {
struct text_stream *content;
int displayed;
CLASS_DEFINITION
} weave_maths_node;
#line 247 "inweb/Chapter 5/Weave Tree.w"
typedef struct weave_verbatim_node {
struct text_stream *content;
CLASS_DEFINITION
} weave_verbatim_node;
#line 11 "inweb/Chapter 5/Format Methods.w"
typedef struct weave_format {
struct text_stream *format_name;
struct text_stream *woven_extension;
struct method_set *methods;
CLASS_DEFINITION
} weave_format;
#line 18 "inweb/Chapter 5/Plain Text Format.w"
typedef struct PlainText_render_state {
struct text_stream *OUT;
struct weave_order *wv;
} PlainText_render_state;
#line 33 "inweb/Chapter 5/TeX Format.w"
typedef struct TeX_render_state {
struct text_stream *OUT;
struct weave_order *wv;
int TeX_form;
} TeX_render_state;
#line 29 "inweb/Chapter 5/HTML Formats.w"
typedef struct HTML_render_state {
struct text_stream *OUT;
struct filename *into_file;
struct weave_order *wv;
struct colour_scheme *colours;
int EPUB_flag;
int popup_counter;
int carousel_number;
int slide_number;
int slide_of;
struct asset_rule *copy_rule;
} HTML_render_state;
#line 18 "inweb/Chapter 5/Debugging Format.w"
typedef struct debugging_render_state {
struct text_stream *OUT;
struct weave_order *wv;
} debugging_render_state;
#line 20 "inweb/Chapter 5/TeX Utilities.w"
typedef struct tex_results {
int overfull_hbox_count;
int tex_error_count;
int page_count;
int pdf_size;
struct filename *PDF_filename;
CLASS_DEFINITION
} tex_results;
#line 51 "inweb/Chapter 6/Makefiles.w"
typedef struct makefile_specifics {
struct web *for_web; /* if one has been set at the command line */
struct dictionary *tools_dictionary; /* components with |type: tool| */
struct dictionary *webs_dictionary; /* components with |type: web| */
struct dictionary *modules_dictionary; /* components with |type: module| */
struct module_search *search_path;
struct text_stream *which_platform;
CLASS_DEFINITION
} makefile_specifics;
#line 173 "inweb/Chapter 6/Ctags Support.w"
typedef struct defined_constant {
struct text_stream *name;
struct source_line *at;
CLASS_DEFINITION
} defined_constant;
#line 41 "inweb/Chapter 6/Readme Writeme.w"
typedef struct writeme_asset {
struct text_stream *name;
struct web_md *if_web;
struct text_stream *date;
struct text_stream *version;
int next_is_version;
CLASS_DEFINITION
} writeme_asset;
#line 21 "inweb/Chapter 6/Colonies.w"
typedef struct colony {
struct linked_list *members; /* of |colony_member| */
struct text_stream *home; /* path of home repository */
struct pathname *assets_path; /* where assets shared between weaves live */
struct pathname *patterns_path; /* where additional patterns live */
CLASS_DEFINITION
} colony;
#line 39 "inweb/Chapter 6/Colonies.w"
typedef struct colony_member {
int web_rather_than_module; /* |TRUE| for a web, |FALSE| for a module */
struct text_stream *name; /* the |N| in |N at P in W| */
struct text_stream *path; /* the |P| in |N at P in W| */
struct pathname *weave_path; /* the |W| in |N at P in W| */
struct text_stream *home_leaf; /* usually |index.html|, but not for single-file webs */
struct text_stream *default_weave_pattern; /* for use when weaving */
struct web_md *loaded; /* metadata on its sections, lazily evaluated */
struct filename *navigation; /* navigation sidebar HTML */
struct linked_list *breadcrumb_tail; /* of |breadcrumb_request| */
CLASS_DEFINITION
} colony_member;
#line 59 "inweb/Chapter 6/Colonies.w"
typedef struct colony_reader_state {
struct colony *province;
struct filename *nav;
struct linked_list *crumbs; /* of |breadcrumb_request| */
struct text_stream *pattern;
} colony_reader_state;
#line 163 "inweb/Chapter 6/Colonies.w"
typedef struct breadcrumb_request {
struct text_stream *breadcrumb_text;
struct text_stream *breadcrumb_link;
CLASS_DEFINITION
} breadcrumb_request;
typedef long int pointer_sized_int;
typedef void (*writer_function)(text_stream *, char *, void *);
typedef void (*writer_function_I)(text_stream *, char *, int);
typedef void (*log_function)(text_stream *, void *);
typedef void (*log_function_I)(text_stream *, int);
typedef char string[MAX_STRING_LENGTH+1];
#line 90 "inweb/foundation-module/Chapter 1/Foundation Module.w"
void Foundation__start(int argc, char **argv) ;
#line 174 "inweb/foundation-module/Chapter 1/Foundation Module.w"
void Foundation__end(void) ;
#ifdef PLATFORM_POSIX
#line 81 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__is_folder_separator(wchar_t c) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 102 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
char * Platform__getenv(const char *name) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#line 115 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__where_am_i(wchar_t *p, size_t length) ;
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_UNIX
#ifdef PLATFORM_POSIX
#line 166 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__where_am_i(wchar_t *p, size_t length) ;
#endif /* PLATFORM_UNIX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#line 173 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__where_am_i(wchar_t *p, size_t length) ;
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifndef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 186 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__system(const char *cmd) ;
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 216 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__system(const char *cmd) ;
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 233 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__mkdir(char *transcoded_pathname) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 241 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void * Platform__opendir(char *dir_name) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 246 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__readdir(void *D, char *dir_name, char *leafname) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 261 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__closedir(void *D) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 274 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
time_t Platform__never_time(void) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 278 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
time_t Platform__timestamp(char *transcoded_filename) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 284 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
off_t Platform__size(char *transcoded_filename) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 298 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__rsync(char *transcoded_source, char *transcoded_dest) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 307 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__quote_text(char *quoted, char *raw, int terminate) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 323 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__sleep(int seconds) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 339 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__notification(text_stream *text, int happy) ;
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifndef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 352 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__notification(text_stream *text, int happy) ;
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 365 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__configure_terminal(void) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 377 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__create_thread(foundation_thread *pt, const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 382 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__join_thread(foundation_thread pt, void** rv) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 386 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__init_thread(foundation_thread_attributes *pa, size_t size) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 391 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
size_t Platform__get_thread_stack_size(foundation_thread_attributes *pa) ;
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#line 412 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__get_core_count(void) ;
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 426 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__get_core_count(void) ;
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#line 438 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__get_core_count(void) ;
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_WINDOWS
#line 48 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__Windows_isdigit(int c) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 60 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__is_folder_separator(wchar_t c) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 92 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__where_am_i(wchar_t *p, size_t length) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 189 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__mkdir(char *transcoded_pathname) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 197 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void * Platform__opendir(char *dir_name) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 202 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__readdir(void *D, char *dir_name, char *leafname) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 219 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__closedir(void *D) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 227 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__path_add(const char* base, const char* add, char* path) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 237 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__rsync(char *transcoded_source, char *transcoded_dest) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 316 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__sleep(int seconds) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 323 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__notification(text_stream *text, int happy) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 341 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__Win32_ResetConsole(void) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 350 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__configure_terminal(void) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 392 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__create_thread(foundation_thread *pt, const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 407 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__join_thread(foundation_thread pt, void** rv) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 411 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__init_thread(foundation_thread_attributes* pa, size_t size) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 414 "inweb/foundation-module/Chapter 1/Windows Platform.w"
size_t Platform__get_thread_stack_size(foundation_thread_attributes* pa) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 424 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__get_core_count(void) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 445 "inweb/foundation-module/Chapter 1/Windows Platform.w"
time_t Platform__never_time(void) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 449 "inweb/foundation-module/Chapter 1/Windows Platform.w"
time_t Platform__timestamp(char *transcoded_filename) ;
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 455 "inweb/foundation-module/Chapter 1/Windows Platform.w"
off_t Platform__size(char *transcoded_filename) ;
#endif /* PLATFORM_WINDOWS */
#line 64 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__declare_aspect(int a, wchar_t *name, int def, int alt) ;
#line 111 "inweb/foundation-module/Chapter 2/Debugging Log.w"
filename * Log__get_debug_log_filename(void) ;
#line 115 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__set_debug_log_filename(filename *F) ;
#line 119 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int Log__open(void) ;
#line 131 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int Log__open_alternative(filename *F, text_stream *at) ;
#line 140 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__close(void) ;
#line 155 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__new_phase(char *p, text_stream *q) ;
#line 164 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__new_stage(text_stream *p) ;
#line 178 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int Log__aspect_switched_on(int aspect) ;
#line 185 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__set_aspect(int aspect, int state) ;
#line 192 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__set_all_aspects(int new_state) ;
#line 210 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int Log__set_aspect_from_command_line(text_stream *name, int give_error) ;
#line 241 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__tracing_on(int starred, text_stream *heading) ;
#line 261 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__show_debugging_settings_with_state(int state) ;
#line 274 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__show_debugging_contents(void) ;
#line 78 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__start(void) ;
#line 156 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__allocate_another_block(void) ;
#line 196 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__free(void) ;
#line 241 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__check_memory_integrity(void) ;
#line 252 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__debug_memory_frames(int from, int to) ;
#line 269 "inweb/foundation-module/Chapter 2/Memory.w"
void * Memory__allocate(int mem_type, int extent) ;
#line 470 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__name_fundamental_reasons(void) ;
#line 483 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__reason_name(int r, char *reason) ;
#line 488 "inweb/foundation-module/Chapter 2/Memory.w"
char * Memory__description_of_reason(int r) ;
#line 513 "inweb/foundation-module/Chapter 2/Memory.w"
void * Memory__calloc(int how_many, int size_in_bytes, int reason) ;
#line 516 "inweb/foundation-module/Chapter 2/Memory.w"
void * Memory__malloc(int size_in_bytes, int reason) ;
#line 523 "inweb/foundation-module/Chapter 2/Memory.w"
void * Memory__alloc_inner(int N, int S, int R) ;
#line 574 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__I7_free(void *pointer, int R, int bytes_freed) ;
#line 583 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__I7_array_free(void *pointer, int R, int num_cells, size_t cell_size) ;
#line 591 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__log_statistics(void) ;
#line 673 "inweb/foundation-module/Chapter 2/Memory.w"
int Memory__log_usage(int total) ;
#line 693 "inweb/foundation-module/Chapter 2/Memory.w"
int Memory__compare_usage(const void *ent1, const void *ent2) ;
#line 703 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__log_percentage(int bytes, int total) ;
#line 716 "inweb/foundation-module/Chapter 2/Memory.w"
void * Memory__paranoid_calloc(size_t N, size_t S) ;
#line 748 "inweb/foundation-module/Chapter 2/Memory.w"
general_pointer Memory__store_gp_null(void) ;
#line 754 "inweb/foundation-module/Chapter 2/Memory.w"
int Memory__test_gp_null(general_pointer gp) ;
#line 12 "inweb/foundation-module/Chapter 2/Locales.w"
char * Locales__name(int L) ;
#line 20 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__parse_locale(char *name) ;
#line 35 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__get(int L) ;
#line 42 "inweb/foundation-module/Chapter 2/Locales.w"
void Locales__set(int L, int E) ;
#line 60 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__parse_encoding(char *name) ;
#line 72 "inweb/foundation-module/Chapter 2/Locales.w"
void Locales__write_locales(OUTPUT_STREAM) ;
#line 82 "inweb/foundation-module/Chapter 2/Locales.w"
void Locales__write_locale(OUTPUT_STREAM, int L) ;
#line 98 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__platform_locale(void) ;
#line 118 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__set_locales(char *text) ;
#line 274 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__initialise(text_stream *stream, int from) ;
#line 292 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__enable_XML_escapes(text_stream *stream) ;
#line 296 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__disable_XML_escapes(text_stream *stream) ;
#line 302 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__enable_I6_escapes(text_stream *stream) ;
#line 307 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__disable_I6_escapes(text_stream *stream) ;
#line 313 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__I6_escapes_enabled(text_stream *stream) ;
#line 317 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__enable_debugging(text_stream *stream) ;
#line 321 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__disable_debugging(text_stream *stream) ;
#line 326 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__mark_as_read_only(text_stream *stream) ;
#line 330 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__declare_as_HTML(text_stream *stream, HTML_file_state *hs) ;
#line 334 "inweb/foundation-module/Chapter 2/Streams.w"
HTML_file_state * Streams__get_HTML_file_state(text_stream *stream) ;
#line 341 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__log(OUTPUT_STREAM, void *vS) ;
#line 364 "inweb/foundation-module/Chapter 2/Streams.w"
text_stream * Streams__get_stdout(void) ;
#line 383 "inweb/foundation-module/Chapter 2/Streams.w"
text_stream * Streams__get_stderr(void) ;
#line 400 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_to_file(text_stream *stream, filename *name, int encoding) ;
#line 419 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_to_file_append(text_stream *stream, filename *name, int encoding) ;
#line 440 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_to_memory(text_stream *stream, int capacity) ;
#line 456 "inweb/foundation-module/Chapter 2/Streams.w"
text_stream Streams__new_buffer(int capacity, wchar_t *at) ;
#line 474 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_wide_string(text_stream *stream, const wchar_t *c_string) ;
#line 482 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_wide_string(text_stream *stream, const wchar_t *c_string) ;
#line 490 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_ISO_string(text_stream *stream, const char *c_string) ;
#line 498 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_ISO_string(text_stream *stream, const char *c_string) ;
#line 505 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_UTF8_string(text_stream *stream, const char *c_string) ;
#line 513 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_UTF8_string(text_stream *stream, const char *c_string) ;
#line 532 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_as_wide_string(wchar_t *C_string, text_stream *stream, int buffer_size) ;
#line 551 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_as_ISO_string(char *C_string, text_stream *stream, int buffer_size) ;
#line 568 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_as_UTF8_string(char *C_string, text_stream *stream, int buffer_size) ;
#line 599 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_locale_string(text_stream *stream, const char *C_string) ;
#line 608 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_as_locale_string(char *C_string, text_stream *stream, int buffer_size) ;
#line 616 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_locale_string(text_stream *stream, char *C_string) ;
#line 629 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__flush(text_stream *stream) ;
#line 637 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__close(text_stream *stream) ;
#line 688 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__putc(int c_int, text_stream *stream) ;
#line 795 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__literal(text_stream *stream, char *p) ;
#line 809 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__indent(text_stream *stream) ;
#line 814 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__outdent(text_stream *stream) ;
#line 823 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__set_indentation(text_stream *stream, int N) ;
#line 837 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__get_position(text_stream *stream) ;
#line 851 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__latest(text_stream *stream) ;
#line 867 "inweb/foundation-module/Chapter 2/Streams.w"
wchar_t Streams__get_char_at_index(text_stream *stream, int position) ;
#line 879 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__put_char_at_index(text_stream *stream, int position, wchar_t C) ;
#line 905 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__set_position(text_stream *stream, int position) ;
#line 929 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__copy(text_stream *to, text_stream *from) ;
#line 946 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__writer(OUTPUT_STREAM, char *format_string, void *vS) ;
#line 51 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__log_escape_usage(void) ;
#line 67 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__register_writer(int esc, void (*f)(text_stream *, char *, void *)) ;
#line 70 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__register_logger(int esc, void (*f)(text_stream *, void *)) ;
#line 73 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__register_writer_I(int esc, void (*f)(text_stream *, char *, int)) ;
#line 76 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__register_logger_I(int esc, void (*f)(text_stream *, int)) ;
#line 87 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__register_writer_p(int set, int esc, void *f, int cat) ;
#line 130 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__printf(text_stream *stream, char *fmt, ...) ;
#line 32 "inweb/foundation-module/Chapter 2/Methods.w"
method_set * Methods__new_set(void) ;
#line 76 "inweb/foundation-module/Chapter 2/Methods.w"
void Methods__add(method_set *S, int ID, void *function) ;
#line 90 "inweb/foundation-module/Chapter 2/Methods.w"
int Methods__provided(method_set *S, int ID) ;
#line 30 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
linked_list * LinkedLists__new(void) ;
#line 36 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void LinkedLists__empty(linked_list *ll) ;
#line 47 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void LinkedLists__add(linked_list *L, void *P, int to_end) ;
#line 75 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void * LinkedLists__remove_from_front(linked_list *L) ;
#line 88 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void * LinkedLists__delete(int N, linked_list *L) ;
#line 112 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void LinkedLists__insert(linked_list *L, int N, void *P) ;
#line 140 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
int LinkedLists__len(linked_list *L) ;
#line 143 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
linked_list_item * LinkedLists__first(linked_list *L) ;
#line 146 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void * LinkedLists__entry(int N, linked_list *L) ;
#line 153 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void LinkedLists__set_entry(int N, linked_list *L, void *P) ;
#line 160 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
linked_list_item * LinkedLists__last(linked_list *L) ;
#line 163 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
linked_list_item * LinkedLists__next(linked_list_item *I) ;
#line 166 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void * LinkedLists__content(linked_list_item *I) ;
#line 33 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dictionary * Dictionaries__new(int S, int textual) ;
#line 51 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__log(OUTPUT_STREAM, dictionary *D) ;
#line 71 "inweb/foundation-module/Chapter 2/Dictionaries.w"
int Dictionaries__hash(text_stream *K, int N) ;
#line 85 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry * Dictionaries__find(dictionary *D, text_stream *K) ;
#line 88 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry * Dictionaries__create(dictionary *D, text_stream *K) ;
#line 91 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__destroy(dictionary *D, text_stream *K) ;
#line 100 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry * Dictionaries__find_literal(dictionary *D, wchar_t *lit) ;
#line 107 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry * Dictionaries__create_literal(dictionary *D, wchar_t *lit) ;
#line 114 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__destroy_literal(dictionary *D, wchar_t *lit) ;
#line 125 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry * Dictionaries__find_p(dictionary *D, text_stream *K, int change) ;
#line 202 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void * Dictionaries__value_for_entry(dict_entry *de) ;
#line 207 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void * Dictionaries__read_value(dictionary *D, text_stream *key) ;
#line 215 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void * Dictionaries__read_value_literal(dictionary *D, wchar_t *key) ;
#line 224 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__write_value(dictionary *D, text_stream *key, void *val) ;
#line 232 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__write_value_literal(dictionary *D, wchar_t *key, void *val) ;
#line 245 "inweb/foundation-module/Chapter 2/Dictionaries.w"
text_stream * Dictionaries__create_text(dictionary *D, text_stream *key) ;
#line 251 "inweb/foundation-module/Chapter 2/Dictionaries.w"
text_stream * Dictionaries__create_text_literal(dictionary *D, wchar_t *lit) ;
#line 262 "inweb/foundation-module/Chapter 2/Dictionaries.w"
text_stream * Dictionaries__get_text(dictionary *D, text_stream *key) ;
#line 270 "inweb/foundation-module/Chapter 2/Dictionaries.w"
text_stream * Dictionaries__get_text_literal(dictionary *D, wchar_t *lit) ;
#line 283 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__dispose_of(dictionary *D) ;
#line 18 "inweb/foundation-module/Chapter 2/Trees.w"
heterogeneous_tree * Trees__new(tree_type *type) ;
#line 40 "inweb/foundation-module/Chapter 2/Trees.w"
tree_node * Trees__new_node(heterogeneous_tree *T, tree_node_type *type, general_pointer wrapping) ;
#line 61 "inweb/foundation-module/Chapter 2/Trees.w"
tree_node * Trees__new_child(tree_node *of, tree_node_type *type, general_pointer wrapping) ;
#line 81 "inweb/foundation-module/Chapter 2/Trees.w"
tree_type * Trees__new_type(text_stream *name, int (*verifier)(tree_node *)) ;
#line 100 "inweb/foundation-module/Chapter 2/Trees.w"
tree_node_type * Trees__new_node_type(text_stream *name, int req, int (*verifier)(tree_node *)) ;
#line 114 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__make_root(heterogeneous_tree *T, tree_node *N) ;
#line 126 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__remove_root(heterogeneous_tree *T) ;
#line 134 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__make_child(tree_node *N, tree_node *of) ;
#line 151 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__make_eldest_child(tree_node *N, tree_node *of) ;
#line 162 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__make_sibling(tree_node *N, tree_node *of) ;
#line 179 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__remove(tree_node *N) ;
#line 194 "inweb/foundation-module/Chapter 2/Trees.w"
int Trees__verify_children(tree_node *N) ;
#line 210 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__traverse_tree(heterogeneous_tree *T, int (*visitor)(tree_node *, void *, int L), void *state) ;
#line 216 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__traverse_from(tree_node *N, int (*visitor)(tree_node *, void *, int L), void *state, int L) ;
#line 223 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__traverse(tree_node *N, int (*visitor)(tree_node *, void *, int L), void *state, int L) ;
#line 233 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__prune_tree(heterogeneous_tree *T, int (*visitor)(tree_node *, void *), void *state) ;
#line 239 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__prune_from(tree_node *N, int (*visitor)(tree_node *, void *), void *state) ;
#line 249 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__prune(tree_node *N, int (*visitor)(tree_node *, void *), void *state) ;
#line 13 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__set_handler(int (*f)(text_stream *, int)) ;
#line 16 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__set_internal_handler(void (*f)(void *, char *, char *, int)) ;
#line 21 "inweb/foundation-module/Chapter 3/Error Messages.w"
int Errors__have_occurred(void) ;
#line 26 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__issue(text_stream *message, int fatality) ;
#line 43 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__fatal(char *message) ;
#line 50 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__fatal_with_C_string(char *message, char *parameter) ;
#line 59 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__fatal_with_text(char *message, text_stream *parameter) ;
#line 68 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__fatal_with_file(char *message, filename *F) ;
#line 75 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__fatal_with_path(char *message, pathname *P) ;
#line 91 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__internal_error_handler(void *p, char *message, char *f, int lc) ;
#line 106 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__enter_debugger_mode(void) ;
#line 111 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__die(void) ;
#line 127 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__nowhere(char *message) ;
#line 131 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__in_text_file(char *message, text_file_position *here) ;
#line 138 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__in_text_file_S(text_stream *message, text_file_position *here) ;
#line 148 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__at_position(char *message, filename *file, int line) ;
#line 157 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__at_position_S(text_stream *message, filename *file, int line) ;
#line 169 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__with_file(char *message, filename *F) ;
#line 176 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__with_text(char *message, text_stream *T) ;
#line 65 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__begin_group(int id, text_stream *name) ;
#line 71 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__end_group(void) ;
#line 74 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
command_line_switch * CommandLine__declare_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal) ;
#line 80 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
command_line_switch * CommandLine__declare_switch_p(int id, text_stream *name, int val, text_stream *help_literal) ;
#line 117 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
command_line_switch * CommandLine__declare_boolean_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal, int active) ;
#line 136 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__declare_numerical_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal) ;
#line 143 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__declare_textual_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal) ;
#line 179 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__read(int argc, char **argv, void *state, void (*f)(int, int, text_stream *, void *), void (*g)(int, text_stream *, void *)) ;
#line 189 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__set_locale(int argc, char **argv) ;
#line 198 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__read_array(clf_reader_state *crs, int argc, char **argv) ;
#line 225 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__also_read_file(filename *F) ;
#line 236 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__record_log(text_stream *line) ;
#line 242 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__play_back_log(void) ;
#line 259 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__read_file(clf_reader_state *crs) ;
#line 271 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__read_file_helper(text_stream *text, text_file_position *tfp, void *state) ;
#line 300 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__read_one(clf_reader_state *crs, text_stream *opt) ;
#line 308 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__read_pair(clf_reader_state *crs, text_stream *opt, text_stream *arg) ;
#line 332 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__read_pair_p(text_stream *opt, text_stream *opt_val, int N, text_stream *arg, void *state, void (*f)(int, int, text_stream *, void *), int *substantive) ;
#line 424 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__declare_heading(wchar_t *heading_text_literal) ;
#line 428 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__write_help(OUTPUT_STREAM) ;
#line 486 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__compare_names(const void *ent1, const void *ent2) ;
#line 51 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__start(void) ;
#line 64 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__set_installation_path(pathname *P) ;
#line 67 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname * Pathnames__installation_path(const char *V, text_stream *def) ;
#line 96 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname * Pathnames__down(pathname *P, text_stream *dir_name) ;
#line 100 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname * Pathnames__primitive(text_stream *str, int from, int to, pathname *par) ;
#line 120 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname * Pathnames__from_text(text_stream *path) ;
#line 124 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname * Pathnames__from_text_relative(pathname *P, text_stream *path) ;
#line 141 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__writer(OUTPUT_STREAM, char *format_string, void *vP) ;
#line 148 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__writer_r(OUTPUT_STREAM, pathname *P, int divider) ;
#line 178 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__to_text_relative(OUTPUT_STREAM, pathname *P, pathname *R) ;
#line 193 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname * Pathnames__up(pathname *P) ;
#line 198 "inweb/foundation-module/Chapter 3/Pathnames.w"
text_stream * Pathnames__directory_name(pathname *P) ;
#line 209 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__relative_URL(OUTPUT_STREAM, pathname *from, pathname *to) ;
#line 245 "inweb/foundation-module/Chapter 3/Pathnames.w"
int Pathnames__create_in_file_system(pathname *P) ;
#line 263 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__rsync(pathname *source, pathname *dest) ;
#line 22 "inweb/foundation-module/Chapter 3/Filenames.w"
filename * Filenames__in(pathname *P, text_stream *file_name) ;
#line 26 "inweb/foundation-module/Chapter 3/Filenames.w"
filename * Filenames__primitive(text_stream *S, int from, int to, pathname *P) ;
#line 42 "inweb/foundation-module/Chapter 3/Filenames.w"
filename * Filenames__from_text(text_stream *path) ;
#line 58 "inweb/foundation-module/Chapter 3/Filenames.w"
filename * Filenames__from_text_relative(pathname *from, text_stream *path) ;
#line 75 "inweb/foundation-module/Chapter 3/Filenames.w"
void Filenames__writer(OUTPUT_STREAM, char *format_string, void *vF) ;
#line 91 "inweb/foundation-module/Chapter 3/Filenames.w"
void Filenames__to_text_relative(OUTPUT_STREAM, filename *F, pathname *P) ;
#line 115 "inweb/foundation-module/Chapter 3/Filenames.w"
pathname * Filenames__up(filename *F) ;
#line 123 "inweb/foundation-module/Chapter 3/Filenames.w"
filename * Filenames__without_path(filename *F) ;
#line 127 "inweb/foundation-module/Chapter 3/Filenames.w"
text_stream * Filenames__get_leafname(filename *F) ;
#line 132 "inweb/foundation-module/Chapter 3/Filenames.w"
void Filenames__write_unextended_leafname(OUTPUT_STREAM, filename *F) ;
#line 148 "inweb/foundation-module/Chapter 3/Filenames.w"
void Filenames__write_extension(OUTPUT_STREAM, filename *F) ;
#line 157 "inweb/foundation-module/Chapter 3/Filenames.w"
filename * Filenames__set_extension(filename *F, text_stream *extension) ;
#line 190 "inweb/foundation-module/Chapter 3/Filenames.w"
int Filenames__guess_format(filename *F) ;
#line 234 "inweb/foundation-module/Chapter 3/Filenames.w"
FILE * Filenames__fopen(filename *F, char *usage) ;
#line 243 "inweb/foundation-module/Chapter 3/Filenames.w"
FILE * Filenames__fopen_caseless(filename *F, char *usage) ;
#line 258 "inweb/foundation-module/Chapter 3/Filenames.w"
int Filenames__eq(filename *F1, filename *F2) ;
#line 273 "inweb/foundation-module/Chapter 3/Filenames.w"
time_t Filenames__timestamp(filename *F) ;
#line 283 "inweb/foundation-module/Chapter 3/Filenames.w"
int Filenames__size(filename *F) ;
#ifdef PLATFORM_POSIX
#line 50 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
FILE * CIFilingSystem__fopen(const char *path, const char *mode) ;
#endif /* PLATFORM_POSIX */
#line 205 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
char * CIFilingSystem__strrchr(const char *p) ;
#line 225 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
int CIFilingSystem__match_in_directory(void *vd, char *name, char *last_match) ;
#ifndef PLATFORM_POSIX
#line 245 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
FILE * CIFilingSystem__fopen(const char *path, const char *mode) ;
#endif /* PLATFORM_POSIX */
#line 14 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__quote_path(OUTPUT_STREAM, pathname *P) ;
#line 21 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__quote_file(OUTPUT_STREAM, filename *F) ;
#line 28 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__plain(OUTPUT_STREAM, char *raw) ;
#line 32 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__plain_text(OUTPUT_STREAM, text_stream *raw) ;
#line 36 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__quote_text(OUTPUT_STREAM, text_stream *raw) ;
#line 50 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__apply(char *command, filename *F) ;
#line 58 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__apply_S(text_stream *command, filename *F) ;
#line 70 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__rm(filename *F) ;
#line 74 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__copy(filename *F, pathname *T, char *options) ;
#line 89 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__redirect(OUTPUT_STREAM, filename *F) ;
#line 106 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__verbose(void) ;
#line 110 "inweb/foundation-module/Chapter 3/Shell.w"
int Shell__run(OUTPUT_STREAM) ;
#line 19 "inweb/foundation-module/Chapter 3/Directories.w"
scan_directory * Directories__open_from(text_stream *name) ;
#line 27 "inweb/foundation-module/Chapter 3/Directories.w"
scan_directory * Directories__open(pathname *P) ;
#line 35 "inweb/foundation-module/Chapter 3/Directories.w"
int Directories__next(scan_directory *D, text_stream *leafname) ;
#line 47 "inweb/foundation-module/Chapter 3/Directories.w"
void Directories__close(scan_directory *D) ;
#line 55 "inweb/foundation-module/Chapter 3/Directories.w"
int Directories__exists(pathname *P) ;
#line 74 "inweb/foundation-module/Chapter 3/Directories.w"
linked_list * Directories__listing(pathname *P) ;
#line 102 "inweb/foundation-module/Chapter 3/Directories.w"
int Directories__compare_names(const void *ent1, const void *ent2) ;
#line 13 "inweb/foundation-module/Chapter 3/Time.w"
void Time__begin(void) ;
#line 26 "inweb/foundation-module/Chapter 3/Time.w"
void Time__fix(void) ;
#line 35 "inweb/foundation-module/Chapter 3/Time.w"
int Time__fixed(void) ;
#line 79 "inweb/foundation-module/Chapter 3/Time.w"
void Time__easter(int year, int *d, int *m) ;
#line 102 "inweb/foundation-module/Chapter 3/Time.w"
int Time__feast(void) ;
#line 145 "inweb/foundation-module/Chapter 3/Time.w"
stopwatch_timer * Time__start_stopwatch(stopwatch_timer *within, text_stream *name) ;
#line 166 "inweb/foundation-module/Chapter 3/Time.w"
int Time__stop_stopwatch(stopwatch_timer *st) ;
#line 193 "inweb/foundation-module/Chapter 3/Time.w"
int Time__compare_watches(const void *w1, const void *w2) ;
#line 208 "inweb/foundation-module/Chapter 3/Time.w"
void Time__resume_stopwatch(stopwatch_timer *st) ;
#line 220 "inweb/foundation-module/Chapter 3/Time.w"
void Time__log_timing(stopwatch_timer *st, int total) ;
#line 8 "inweb/foundation-module/Chapter 4/Characters.w"
wchar_t Characters__tolower(wchar_t c) ;
#line 11 "inweb/foundation-module/Chapter 4/Characters.w"
wchar_t Characters__toupper(wchar_t c) ;
#line 14 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__isalpha(wchar_t c) ;
#line 17 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__isdigit(wchar_t c) ;
#line 20 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__isupper(wchar_t c) ;
#line 23 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__islower(wchar_t c) ;
#line 26 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__isalnum(wchar_t c) ;
#line 29 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__iscntrl(wchar_t c) ;
#line 33 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__vowel(wchar_t c) ;
#line 41 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__is_space_or_tab(int c) ;
#line 45 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__is_whitespace(int c) ;
#line 55 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__is_babel_whitespace(int c) ;
#line 66 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__combine_accent(int accent, int letter) ;
#line 120 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__make_filename_safe(int charcode) ;
#line 126 "inweb/foundation-module/Chapter 4/Characters.w"
wchar_t Characters__make_wchar_t_filename_safe(wchar_t charcode) ;
#line 135 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__remove_accent(int charcode) ;
#line 162 "inweb/foundation-module/Chapter 4/Characters.w"
wchar_t Characters__remove_wchar_t_accent(wchar_t charcode) ;
#line 169 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__isalphabetic(int letter) ;
#line 25 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__strlen_unbounded(const char *p) ;
#line 35 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__check_len(int n) ;
#line 44 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__len(char *str) ;
#line 55 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__copy(char *to, char *from) ;
#line 65 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__eq(char *A, char *B) ;
#line 69 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__ne(char *A, char *B) ;
#line 76 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__cmp(char *A, char *B) ;
#line 89 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__transcode_ISO_string_to_UTF8(char *p, char *dest) ;
#line 110 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__truncated_strcpy(char *to, char *from, int max) ;
#line 130 "inweb/foundation-module/Chapter 4/C Strings.w"
char * CStrings__park_string(char *from) ;
#line 141 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__free_ssas(void) ;
#line 14 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__len(wchar_t *p) ;
#line 21 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__cmp(wchar_t *A, wchar_t *B) ;
#line 26 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__atoi(wchar_t *p) ;
#line 38 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__new(void) ;
#line 42 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__new_with_capacity(int c) ;
#line 48 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__dispose_of(text_stream *text) ;
#line 57 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__duplicate(text_stream *E) ;
#line 73 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__new_from_wide_string(const wchar_t *C_string) ;
#line 79 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__new_from_ISO_string(const char *C_string) ;
#line 85 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__new_from_UTF8_string(const char *C_string) ;
#line 91 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__new_from_locale_string(const char *C_string) ;
#line 100 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__from_wide_string(text_stream *S, wchar_t *c_string) ;
#line 105 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__from_locale_string(text_stream *S, char *c_string) ;
#line 113 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_to_ISO_string(char *C_string, text_stream *S, int buffer_size) ;
#line 117 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_to_UTF8_string(char *C_string, text_stream *S, int buffer_size) ;
#line 121 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_to_wide_string(wchar_t *C_string, text_stream *S, int buffer_size) ;
#line 125 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_to_locale_string(char *C_string, text_stream *S, int buffer_size) ;
#line 132 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__atoi(text_stream *S, int index) ;
#line 146 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__len(text_stream *S) ;
#line 167 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__start(text_stream *S) ;
#line 171 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__at(text_stream *S, int i) ;
#line 177 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__end(text_stream *S) ;
#line 184 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__back(string_position P) ;
#line 188 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__forward(string_position P) ;
#line 192 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__plus(string_position P, int increment) ;
#line 196 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__width_between(string_position P1, string_position P2) ;
#line 201 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__in_range(string_position P) ;
#line 206 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__index(string_position P) ;
#line 222 "inweb/foundation-module/Chapter 4/String Manipulation.w"
wchar_t Str__get(string_position P) ;
#line 227 "inweb/foundation-module/Chapter 4/String Manipulation.w"
wchar_t Str__get_at(text_stream *S, int index) ;
#line 232 "inweb/foundation-module/Chapter 4/String Manipulation.w"
wchar_t Str__get_first_char(text_stream *S) ;
#line 236 "inweb/foundation-module/Chapter 4/String Manipulation.w"
wchar_t Str__get_last_char(text_stream *S) ;
#line 243 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__put(string_position P, wchar_t C) ;
#line 255 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__put_at(text_stream *S, int index, wchar_t C) ;
#line 262 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__clear(text_stream *S) ;
#line 266 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__truncate(text_stream *S, int len) ;
#line 274 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__remove_indentation(text_stream *S, int spaces_per_tab) ;
#line 300 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__rectify_indentation(text_stream *S, int spaces_per_tab) ;
#line 313 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__concatenate(text_stream *S1, text_stream *S2) ;
#line 317 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy(text_stream *S1, text_stream *S2) ;
#line 323 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_tail(text_stream *S1, text_stream *S2, int from) ;
#line 334 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_ISO_string(text_stream *S, char *C_string) ;
#line 339 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_UTF8_string(text_stream *S, char *C_string) ;
#line 344 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_wide_string(text_stream *S, wchar_t *C_string) ;
#line 353 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__eq(text_stream *S1, text_stream *S2) ;
#line 358 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__eq_insensitive(text_stream *S1, text_stream *S2) ;
#line 363 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__ne(text_stream *S1, text_stream *S2) ;
#line 368 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__ne_insensitive(text_stream *S1, text_stream *S2) ;
#line 390 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__cmp(text_stream *S1, text_stream *S2) ;
#line 400 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__cmp_insensitive(text_stream *S1, text_stream *S2) ;
#line 421 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__prefix_eq(text_stream *S1, text_stream *S2, int N) ;
#line 430 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__suffix_eq(text_stream *S1, text_stream *S2, int N) ;
#line 439 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__begins_with_wide_string(text_stream *S, wchar_t *prefix) ;
#line 448 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__ends_with_wide_string(text_stream *S, wchar_t *suffix) ;
#line 458 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__eq_wide_string(text_stream *S1, wchar_t *S2) ;
#line 469 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__eq_narrow_string(text_stream *S1, char *S2) ;
#line 480 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__ne_wide_string(text_stream *S1, wchar_t *S2) ;
#line 487 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__is_whitespace(text_stream *S) ;
#line 497 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__trim_white_space(text_stream *S) ;
#line 526 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__trim_white_space_at_end(text_stream *S) ;
#line 537 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__trim_all_white_space_at_end(text_stream *S) ;
#line 551 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__delete_first_character(text_stream *S) ;
#line 555 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__delete_last_character(text_stream *S) ;
#line 560 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__delete_nth_character(text_stream *S, int n) ;
#line 565 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__delete_n_characters(text_stream *S, int n) ;
#line 578 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__substr(OUTPUT_STREAM, string_position from, string_position to) ;
#line 584 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__includes_character(text_stream *S, wchar_t c) ;
#line 592 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__includes_wide_string_at(text_stream *S, wchar_t *prefix, int j) ;
#line 601 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__includes_wide_string_at_insensitive(text_stream *S, wchar_t *prefix, int j) ;
#line 610 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__includes(text_stream *S, text_stream *T) ;
#line 625 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__includes_at(text_stream *line, int i, text_stream *pattern) ;
#line 648 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream * Str__literal(wchar_t *wide_C_string) ;
#line 20 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__exists(filename *F) ;
#line 52 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__get_line_count(text_file_position *tfp) ;
#line 60 "inweb/foundation-module/Chapter 4/Text Files.w"
text_file_position TextFiles__nowhere(void) ;
#line 70 "inweb/foundation-module/Chapter 4/Text Files.w"
text_file_position TextFiles__at(filename *F, int line) ;
#line 84 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__read(filename *F, int escape_oddities, char *message, int serious, void (iterator)(text_stream *, text_file_position *, void *), text_file_position *start_at, void *state) ;
#line 176 "inweb/foundation-module/Chapter 4/Text Files.w"
void TextFiles__read_line(OUTPUT_STREAM, int escape_oddities, text_file_position *tfp) ;
#line 200 "inweb/foundation-module/Chapter 4/Text Files.w"
void TextFiles__lose_interest(text_file_position *tfp) ;
#line 233 "inweb/foundation-module/Chapter 4/Text Files.w"
unicode_file_buffer TextFiles__create_ufb(void) ;
#line 239 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, unicode_file_buffer *ufb) ;
#line 28 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *header, linked_list *special_macros, general_pointer specifics, wchar_t comment_char, int encoding) ;
#line 95 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__set_loop_var_name(preprocessor_loop *loop, text_stream *name) ;
#line 98 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__add_loop_iteration(preprocessor_loop *loop, text_stream *value) ;
#line 110 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__scan_line(text_stream *line, text_file_position *tfp, void *X) ;
#line 218 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__expand(text_stream *text, text_file_position *tfp, preprocessor_state *PPS) ;
#line 457 "inweb/foundation-module/Chapter 4/Preprocessor.w"
int Preprocessor__acceptable_variable_name(text_stream *name) ;
#line 477 "inweb/foundation-module/Chapter 4/Preprocessor.w"
text_stream * Preprocessor__read_variable(preprocessor_variable *var) ;
#line 481 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__write_variable(preprocessor_variable *var, text_stream *val) ;
#line 497 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_variable_set * Preprocessor__new_variable_set(preprocessor_variable_set *outer) ;
#line 504 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_variable * Preprocessor__find_variable_in_one(text_stream *name, preprocessor_variable_set *set) ;
#line 514 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_variable * Preprocessor__find_variable(text_stream *name, preprocessor_variable_set *set) ;
#line 528 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_variable * Preprocessor__ensure_variable(text_stream *name, preprocessor_variable_set *in_set) ;
#line 605 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_macro * Preprocessor__new_macro(linked_list *L, text_stream *name, text_stream *parameter_specification, void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *), text_file_position *tfp) ;
#line 665 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__add_line_to_macro(preprocessor_macro *mm, text_stream *line, text_file_position *tfp) ;
#line 683 "inweb/foundation-module/Chapter 4/Preprocessor.w"
linked_list * Preprocessor__list_of_reserved_macros(linked_list *special_macros) ;
#line 696 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__do_not_suppress_whitespace(preprocessor_macro *mm) ;
#line 701 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__new_loop_macro(linked_list *L, text_stream *name, text_stream *parameter_specification, void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *), text_file_position *tfp) ;
#line 740 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_macro * Preprocessor__find_macro(linked_list *L, text_stream *name) ;
#line 755 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__default_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 772 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__set_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 787 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__repeat_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 816 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__end_loop_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 77 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
wchar_t * Tries__search(match_trie *T, text_stream *p, wchar_t *add_outcome) ;
#line 237 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
int Tries__matches(match_trie *pos, int c) ;
#line 257 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
int Tries__is_ambiguous(match_trie *pos) ;
#line 267 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
match_trie * Tries__new(int mc) ;
#line 293 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
match_avinue * Tries__new_avinue(int from_start) ;
#line 300 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
void Tries__add_to_avinue(match_avinue *mt, text_stream *from, wchar_t *to) ;
#line 309 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
match_avinue * Tries__duplicate_avinue(match_avinue *A) ;
#line 327 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
wchar_t * Tries__search_avinue(match_avinue *T, text_stream *p) ;
#line 339 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
void Tries__log_avinue(OUTPUT_STREAM, void *vA) ;
#line 352 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
void Tries__log(OUTPUT_STREAM, match_trie *T) ;
#line 10 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__white_space(int c) ;
#line 20 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__identifier_char(int c) ;
#line 35 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__find_expansion(text_stream *text, wchar_t on1, wchar_t on2, wchar_t off1, wchar_t off2, int *len) ;
#line 51 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__find_open_brace(text_stream *text) ;
#line 62 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__string_is_white_space(text_stream *text) ;
#line 144 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
match_results Regexp__create_mr(void) ;
#line 154 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
void Regexp__dispose_of(match_results *mr) ;
#line 168 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match(match_results *mr, text_stream *text, wchar_t *pattern) ;
#line 175 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match_from(match_results *mr, text_stream *text, wchar_t *pattern, int x, int allow_partial) ;
#line 191 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
void Regexp__prepare(match_results *mr) ;
#line 207 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match_r(match_results *mr, text_stream *text, wchar_t *pattern, match_position *scan_from, int allow_partial) ;
#line 338 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__get_cclass(wchar_t *pattern, int ppos, int *len, int *from, int *to, int *reverse) ;
#line 368 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__test_cclass(int c, int chcl, int range_from, int range_to, wchar_t *drawn_from, int reverse) ;
#line 415 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__replace(text_stream *text, wchar_t *pattern, wchar_t *replacement, int options) ;
#line 47 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__write_type(OUTPUT_STREAM, int t) ;
#line 80 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__new_null(void) ;
#line 94 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__new_boolean(int b) ;
#line 102 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__new_number(int b) ;
#line 109 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__new_double(double d) ;
#line 116 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__new_string(text_stream *S) ;
#line 127 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__new_array(void) ;
#line 134 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__add_to_array(JSON_value *array, JSON_value *new_entry) ;
#line 148 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__new_object(void) ;
#line 156 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__add_to_object(JSON_value *obj, text_stream *key, JSON_value *value) ;
#line 173 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__look_up_object(JSON_value *obj, text_stream *key) ;
#line 186 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__error(text_stream *msg) ;
#line 197 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__eq(JSON_value *val1, JSON_value *val2) ;
#line 221 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode(text_stream *T, text_file_position *tfp) ;
#line 225 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_error(text_stream *err, text_file_position *tfp) ;
#line 234 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_error_q(text_stream *err, text_file_position *tfp, text_stream *T, int from, int to) ;
#line 260 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_range(text_stream *T, int from, int to, text_file_position *tfp) ;
#line 307 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_array(JSON_value *array, text_stream *T, int from, int to, text_file_position *tfp) ;
#line 335 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_array_entry(JSON_value *array, text_stream *T, int from, int to, text_file_position *tfp) ;
#line 344 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_object(JSON_value *obj, text_stream *T, int from, int to, text_file_position *tfp) ;
#line 380 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_object_entry(JSON_value *obj, text_stream *T, int from, int to, text_file_position *tfp) ;
#line 418 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_number(text_stream *T, int from, int to, text_file_position *tfp) ;
#line 455 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value * JSON__decode_string(text_stream *T, int from, int to, text_file_position *tfp) ;
#line 507 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode(OUTPUT_STREAM, JSON_value *J) ;
#line 567 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode_string(OUTPUT_STREAM, text_stream *T) ;
#line 600 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement * JSON__single_choice(JSON_single_requirement *sing) ;
#line 607 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement * JSON__add_alternative(JSON_requirement *so_far, JSON_single_requirement *sing) ;
#line 630 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__require_requirement(JSON_requirement *req) ;
#line 638 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__require_value(JSON_value *value) ;
#line 646 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__require_type(int t) ;
#line 676 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_type * JSON__new_type_requirement(int t) ;
#line 704 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__require_array_of(JSON_requirement *E_req) ;
#line 715 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__require_entry(JSON_single_requirement *array_sr, JSON_requirement *entry_sr) ;
#line 727 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__require_pair(JSON_single_requirement *obj_sr, text_stream *key, JSON_requirement *req) ;
#line 731 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__allow_pair(JSON_single_requirement *obj_sr, text_stream *key, JSON_requirement *req) ;
#line 735 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__require_pair_inner(JSON_single_requirement *obj_sr, text_stream *key, JSON_requirement *req, int opt) ;
#line 754 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_pair_requirement * JSON__look_up_pair(JSON_single_requirement *obj_sr, text_stream *key) ;
#line 767 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__error_sr(text_stream *msg) ;
#line 785 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__validate(JSON_value *val, JSON_requirement *req, linked_list *errs) ;
#line 796 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__validation_error(linked_list *errs, text_stream *err, lifo_stack *location) ;
#line 819 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__validate_r(JSON_value *val, JSON_requirement *req, linked_list *errs, lifo_stack *location) ;
#line 838 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__validate_single_r(JSON_value *val, JSON_single_requirement *req, linked_list *errs, lifo_stack *location) ;
#line 988 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement * JSON__decode_req(text_stream *T, dictionary *known_names) ;
#line 996 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement * JSON__decode_req_range(text_stream *T, int from, int to, dictionary *known_names) ;
#line 1029 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement * JSON__decode_req_alternative(JSON_requirement *req, text_stream *T, int from, int to, dictionary *known_names) ;
#line 1041 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__decode_sreq_range(text_stream *T, int from, int to, dictionary *known_names) ;
#line 1128 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__decode_req_array(JSON_single_requirement *array_sr, text_stream *T, int from, int to, dictionary *known_names) ;
#line 1161 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__decode_req_array_entry(JSON_single_requirement *array_sr, text_stream *T, int from, int to, dictionary *known_names) ;
#line 1171 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__decode_req_object(JSON_single_requirement *obj, text_stream *T, int from, int to, dictionary *known_names) ;
#line 1199 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement * JSON__decode_req_object_entry(JSON_single_requirement *obj, text_stream *T, int from, int to, dictionary *known_names) ;
#line 1247 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode_req(OUTPUT_STREAM, JSON_requirement *req) ;
#line 1251 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode_req_r(OUTPUT_STREAM, JSON_requirement *req) ;
#line 1264 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode_sreq_r(OUTPUT_STREAM, JSON_single_requirement *sing) ;
#line 1270 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode_type(OUTPUT_STREAM, JSON_type *type) ;
#line 1347 "inweb/foundation-module/Chapter 4/JSON.w"
dictionary * JSON__read_requirements_file(dictionary *known, filename *F) ;
#line 1359 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__read_requirements_file_helper(text_stream *text, text_file_position *tfp, void *v_state) ;
#line 1383 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__process_req_defn(JSON_rrf_state *state) ;
#line 1396 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement * JSON__decode_printing_errors(text_stream *defn, dictionary *dict, text_file_position *tfp) ;
#line 1415 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement * JSON__look_up_requirements(dictionary *known, text_stream *name) ;
#line 8 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__header(OUTPUT_STREAM, text_stream *title, filename *css1, filename *css2, filename *js1, filename *js2, void *state) ;
#line 25 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__footer(OUTPUT_STREAM) ;
#line 64 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__declare_as_HTML(OUTPUT_STREAM, int XHTML) ;
#line 87 "inweb/foundation-module/Chapter 5/HTML.w"
int HTML__push_tag(OUTPUT_STREAM, char *tag, char *fn, int lc) ;
#line 102 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__pop_tag(OUTPUT_STREAM, char *tag, char *fn, int lc) ;
#line 122 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__completed(OUTPUT_STREAM) ;
#line 154 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__tag(OUTPUT_STREAM, char *tag, text_stream *details) ;
#line 163 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__tag_sc(OUTPUT_STREAM, char *tag, text_stream *details) ;
#line 170 "inweb/foundation-module/Chapter 5/HTML.w"
int HTML__tag_formatting(char *tag) ;
#line 179 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__open(OUTPUT_STREAM, char *tag, text_stream *details, char *fn, int lc) ;
#line 188 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__close(OUTPUT_STREAM, char *tag, char *fn, int lc) ;
#line 197 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__open_indented_p(OUTPUT_STREAM, int depth, char *class) ;
#line 205 "inweb/foundation-module/Chapter 5/HTML.w"
int HTML__pair_formatting(char *tag) ;
#line 227 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_head(OUTPUT_STREAM, filename *CSS_file) ;
#line 245 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_head(OUTPUT_STREAM) ;
#line 250 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__title(OUTPUT_STREAM, text_stream *title) ;
#line 259 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__open_javascript(OUTPUT_STREAM, int define_project) ;
#line 268 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__close_javascript(OUTPUT_STREAM) ;
#line 274 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_javascript(OUTPUT_STREAM, int define_project, filename *M) ;
#line 294 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_javascript_from_file(OUTPUT_STREAM, filename *M) ;
#line 301 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__open_CSS(OUTPUT_STREAM) ;
#line 306 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__close_CSS(OUTPUT_STREAM) ;
#line 311 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_CSS(OUTPUT_STREAM, filename *M) ;
#line 329 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_CSS_from_file(OUTPUT_STREAM, filename *M) ;
#line 336 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_HTML(OUTPUT_STREAM, filename *M) ;
#line 352 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_HTML_from_file(OUTPUT_STREAM, filename *M) ;
#line 360 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_helper(text_stream *line_of_template, text_file_position *tfp, void *OUT) ;
#line 368 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_body(OUTPUT_STREAM, text_stream *class) ;
#line 373 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_body(OUTPUT_STREAM) ;
#line 381 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_div_with_id(OUTPUT_STREAM, char *id) ;
#line 385 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_div_with_class(OUTPUT_STREAM, char *cl) ;
#line 389 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_div_with_class_and_id(OUTPUT_STREAM, char *cl, char *id, int hide) ;
#line 394 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_div_with_id_S(OUTPUT_STREAM, text_stream *id, char *fn, int lc) ;
#line 401 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_div_with_class_S(OUTPUT_STREAM, text_stream *cl, char *fn, int lc) ;
#line 408 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_div_with_class_and_id_S(OUTPUT_STREAM, text_stream *cl, text_stream *id, int hide, char *fn, int lc) ;
#line 417 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_div(OUTPUT_STREAM) ;
#line 424 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__image(OUTPUT_STREAM, filename *F) ;
#line 428 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__image_to_dimensions(OUTPUT_STREAM, filename *F, int w, int h) ;
#line 449 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__icon_with_tooltip(OUTPUT_STREAM, text_stream *icon_name, text_stream *tip, text_stream *tip2) ;
#line 465 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__anchor(OUTPUT_STREAM, text_stream *id) ;
#line 469 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__anchor_with_class(OUTPUT_STREAM, text_stream *id, text_stream *cl) ;
#line 473 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_link(OUTPUT_STREAM, text_stream *to) ;
#line 477 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_download_link(OUTPUT_STREAM, text_stream *to) ;
#line 481 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_link_with_class(OUTPUT_STREAM, text_stream *cl, text_stream *to) ;
#line 485 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_link_with_class_title(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *ti) ;
#line 489 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_link_with_class_onclick(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *on) ;
#line 493 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_link_with_class_title_onclick(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *ti, text_stream *on) ;
#line 500 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_link(OUTPUT_STREAM) ;
#line 509 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__set_link_abbreviation_path(pathname *P) ;
#line 512 "inweb/foundation-module/Chapter 5/HTML.w"
pathname * HTML__get_link_abbreviation_path(void) ;
#line 520 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_plain_html_table(OUTPUT_STREAM) ;
#line 524 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_wide_html_table(OUTPUT_STREAM) ;
#line 531 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_html_table(OUTPUT_STREAM, text_stream *classname, int full_width, int border, int cellspacing, int cellpadding, int height, int width) ;
#line 543 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_html_table_bg(OUTPUT_STREAM, text_stream *classname, int full_width, int border, int cellspacing, int cellpadding, int height, int width, text_stream *bg) ;
#line 556 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__first_html_column(OUTPUT_STREAM, int width) ;
#line 561 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__first_html_column_nowrap(OUTPUT_STREAM, int width, text_stream *classname) ;
#line 572 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__first_html_column_spaced(OUTPUT_STREAM, int width) ;
#line 580 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__first_html_column_coloured(OUTPUT_STREAM, int width, text_stream *classname, int cs) ;
#line 593 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column(OUTPUT_STREAM, int width) ;
#line 599 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column_centred(OUTPUT_STREAM, int width) ;
#line 605 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) ;
#line 611 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) ;
#line 617 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) ;
#line 623 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column_nw(OUTPUT_STREAM, int width) ;
#line 629 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column_w(OUTPUT_STREAM, int width) ;
#line 635 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) ;
#line 640 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_html_row(OUTPUT_STREAM) ;
#line 644 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_html_table(OUTPUT_STREAM) ;
#line 655 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__open_coloured_box(OUTPUT_STREAM, text_stream *classname, int rounding) ;
#line 663 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__close_coloured_box(OUTPUT_STREAM, text_stream *classname, int rounding) ;
#line 669 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__box_corner(OUTPUT_STREAM, text_stream *classname, text_stream *corner) ;
#line 679 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__comment(OUTPUT_STREAM, text_stream *text) ;
#line 683 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__heading(OUTPUT_STREAM, char *tag, text_stream *text) ;
#line 690 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__hr(OUTPUT_STREAM, char *class) ;
#line 855 "inweb/foundation-module/Chapter 5/HTML.w"
wchar_t * HTML__translate_colour_name(wchar_t *original) ;
#line 863 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_colour(OUTPUT_STREAM, text_stream *col) ;
#line 866 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_colour(OUTPUT_STREAM) ;
#line 873 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_span(OUTPUT_STREAM, text_stream *class_name) ;
#line 880 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__end_span(OUTPUT_STREAM) ;
#line 888 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__write_xml_safe_text(OUTPUT_STREAM, text_stream *txt) ;
#line 919 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__put(OUTPUT_STREAM, int charcode) ;
#line 106 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook * Epub__new(text_stream *title, char *prefix) ;
#line 122 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
void Epub__use_CSS_throughout(ebook *B, filename *F) ;
#line 126 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
void Epub__use_CSS(ebook_volume *V, filename *F) ;
#line 130 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
text_stream * Epub__attach_metadata(ebook *B, wchar_t *K, text_stream *V) ;
#line 144 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
text_stream * Epub__get_metadata(ebook *B, wchar_t *K) ;
#line 152 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
text_stream * Epub__ensure_metadata(ebook *B, wchar_t *K) ;
#line 158 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page * Epub__note_page(ebook *B, filename *F, text_stream *title, text_stream *type) ;
#line 178 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
void Epub__note_image(ebook *B, filename *F) ;
#line 186 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_volume * Epub__starts_volume(ebook *B, ebook_page *P, text_stream *title) ;
#line 197 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_chapter * Epub__starts_chapter(ebook *B, ebook_page *P, text_stream *title, text_stream *URL) ;
#line 210 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
void Epub__set_mark_in_chapter(ebook_chapter *C, text_stream *text, text_stream *URL) ;
#line 223 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
pathname * Epub__begin_construction(ebook *B, pathname *P, filename *cover_image) ;
#line 307 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
void Epub__end_construction(ebook *B) ;
#line 10 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_int8(FILE *binary_file, unsigned int *result) ;
#line 18 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_int16(FILE *binary_file, unsigned int *result) ;
#line 29 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_int32(FILE *binary_file, unsigned int *result) ;
#line 44 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_int64(FILE *binary_file, unsigned long long *result) ;
#line 70 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__write_int32(FILE *binary_file, unsigned int val) ;
#line 87 "inweb/foundation-module/Chapter 6/Binary Files.w"
void BinaryFiles__swap_bytes32(unsigned int *value) ;
#line 95 "inweb/foundation-module/Chapter 6/Binary Files.w"
void BinaryFiles__swap_bytes64(unsigned long long *value) ;
#line 113 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_variable_length_integer(FILE *binary_file, unsigned int *result) ;
#line 130 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_float80(FILE *binary_file, unsigned int *result) ;
#line 155 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_string(FILE *binary_file, char *string, unsigned int length) ;
#line 167 "inweb/foundation-module/Chapter 6/Binary Files.w"
long int BinaryFiles__size(filename *F) ;
#line 184 "inweb/foundation-module/Chapter 6/Binary Files.w"
FILE * BinaryFiles__open_for_reading(filename *F) ;
#line 190 "inweb/foundation-module/Chapter 6/Binary Files.w"
FILE * BinaryFiles__try_to_open_for_reading(filename *F) ;
#line 194 "inweb/foundation-module/Chapter 6/Binary Files.w"
FILE * BinaryFiles__open_for_writing(filename *F) ;
#line 200 "inweb/foundation-module/Chapter 6/Binary Files.w"
FILE * BinaryFiles__try_to_open_for_writing(filename *F) ;
#line 204 "inweb/foundation-module/Chapter 6/Binary Files.w"
void BinaryFiles__close(FILE *handle) ;
#line 213 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__copy(filename *from, filename *to, int suppress_error) ;
#line 259 "inweb/foundation-module/Chapter 6/Binary Files.w"
void BinaryFiles__md5(OUTPUT_STREAM, filename *F, int (*mask)(uint64_t)) ;
#line 383 "inweb/foundation-module/Chapter 6/Binary Files.w"
uint32_t BinaryFiles__rotate(uint32_t value, uint32_t shift) ;
#line 24 "inweb/foundation-module/Chapter 6/Image Dimensions.w"
int ImageFiles__get_JPEG_dimensions(FILE *JPEG_file, unsigned int *width, unsigned int *height) ;
#line 77 "inweb/foundation-module/Chapter 6/Image Dimensions.w"
int ImageFiles__get_PNG_dimensions(FILE *PNG_file, unsigned int *width, unsigned int *height) ;
#line 12 "inweb/foundation-module/Chapter 6/Sound Durations.w"
int SoundFiles__get_AIFF_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
#line 59 "inweb/foundation-module/Chapter 6/Sound Durations.w"
int SoundFiles__get_OggVorbis_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
#line 181 "inweb/foundation-module/Chapter 6/Sound Durations.w"
int SoundFiles__get_MIDI_information(FILE *pFile, unsigned int *pType, unsigned int *pNumTracks) ;
#line 77 "inweb/foundation-module/Chapter 7/Version Numbers.w"
semantic_version_number VersionNumbers__null(void) ;
#line 88 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__is_null(semantic_version_number V) ;
#line 102 "inweb/foundation-module/Chapter 7/Version Numbers.w"
void VersionNumbers__to_text(OUTPUT_STREAM, semantic_version_number V) ;
#line 125 "inweb/foundation-module/Chapter 7/Version Numbers.w"
void VersionNumbers__writer(OUTPUT_STREAM, char *format_string, void *vE) ;
#line 143 "inweb/foundation-module/Chapter 7/Version Numbers.w"
semantic_version_number VersionNumbers__from_text(text_stream *T) ;
#line 218 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__le(semantic_version_number V1, semantic_version_number V2) ;
#line 256 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__floor(int N) ;
#line 266 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__strict_atoi(text_stream *T) ;
#line 282 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__eq(semantic_version_number V1, semantic_version_number V2) ;
#line 288 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__ne(semantic_version_number V1, semantic_version_number V2) ;
#line 292 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__gt(semantic_version_number V1, semantic_version_number V2) ;
#line 296 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__ge(semantic_version_number V1, semantic_version_number V2) ;
#line 300 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__lt(semantic_version_number V1, semantic_version_number V2) ;
#line 307 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__cmp(semantic_version_number V1, semantic_version_number V2) ;
#line 39 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
void VersionNumberRanges__write_range(OUTPUT_STREAM, semver_range *R) ;
#line 58 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
semver_range * VersionNumberRanges__any_range(void) ;
#line 67 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__is_any_range(semver_range *R) ;
#line 87 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
semver_range * VersionNumberRanges__compatibility_range(semantic_version_number V) ;
#line 106 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
semver_range * VersionNumberRanges__at_least_range(semantic_version_number V) ;
#line 113 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
semver_range * VersionNumberRanges__at_most_range(semantic_version_number V) ;
#line 123 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__version_ge_end(semantic_version_number V, range_end E) ;
#line 139 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__version_le_end(semantic_version_number V, range_end E) ;
#line 158 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__in_range(semantic_version_number V, semver_range *R) ;
#line 178 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__stricter(range_end E1, range_end E2, int lower) ;
#line 202 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__intersect_range(semver_range *R1, semver_range *R2) ;
#line 92 "inweb/foundation-module/Chapter 8/Web Structure.w"
web_md * WebMetadata__get_without_modules(pathname *P, filename *alt_F) ;
#line 96 "inweb/foundation-module/Chapter 8/Web Structure.w"
web_md * WebMetadata__get(pathname *P, filename *alt_F, int syntax_version, module_search *I, int verbosely, int including_modules, pathname *path_to_inweb) ;
#line 267 "inweb/foundation-module/Chapter 8/Web Structure.w"
void WebMetadata__read_contents_page(web_md *Wm, module *of_module, module_search *import_path, int verbosely, int including_modules, pathname *path, pathname *X) ;
#line 322 "inweb/foundation-module/Chapter 8/Web Structure.w"
void WebMetadata__read_contents_line(text_stream *line, text_file_position *tfp, void *X) ;
#line 662 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__directory_looks_like_a_web(pathname *P) ;
#line 666 "inweb/foundation-module/Chapter 8/Web Structure.w"
filename * WebMetadata__contents_filename(pathname *P) ;
#line 673 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__chapter_count(web_md *Wm) ;
#line 679 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__section_count(web_md *Wm) ;
#line 29 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
int Bibliographic__datum_can_be_declared(web_md *Wm, text_stream *key) ;
#line 35 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
int Bibliographic__datum_on_or_off(web_md *Wm, text_stream *key) ;
#line 45 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
void Bibliographic__initialise_data(web_md *Wm) ;
#line 86 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
void Bibliographic__check_required_data(web_md *Wm) ;
#line 99 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
text_stream * Bibliographic__get_datum(web_md *Wm, text_stream *key) ;
#line 105 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
int Bibliographic__data_exists(web_md *Wm, text_stream *key) ;
#line 111 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
web_bibliographic_datum * Bibliographic__look_up_datum(web_md *Wm, text_stream *key) ;
#line 126 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
web_bibliographic_datum * Bibliographic__set_datum(web_md *Wm, text_stream *key, text_stream *val) ;
#line 31 "inweb/foundation-module/Chapter 8/Web Modules.w"
module * WebModules__new(text_stream *name, pathname *at, int m) ;
#line 52 "inweb/foundation-module/Chapter 8/Web Modules.w"
module * WebModules__create_main_module(web_md *WS) ;
#line 63 "inweb/foundation-module/Chapter 8/Web Modules.w"
void WebModules__dependency(module *A, module *B) ;
#line 79 "inweb/foundation-module/Chapter 8/Web Modules.w"
module_search * WebModules__make_search_path(pathname *ext_path) ;
#line 89 "inweb/foundation-module/Chapter 8/Web Modules.w"
module * WebModules__find(web_md *WS, module_search *ms, text_stream *name, pathname *X) ;
#line 119 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__exists(pathname *P) ;
#line 142 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__named_reference(module **return_M, section_md **return_Sm, int *named_as_module, text_stream *title, module *from_M, text_stream *text, int list, int sections_only) ;
#line 10 "inweb/foundation-module/Chapter 8/Build Files.w"
filename * BuildFiles__build_file_for_web(web_md *WS) ;
#line 30 "inweb/foundation-module/Chapter 8/Build Files.w"
build_file_data BuildFiles__read(filename *F) ;
#line 40 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__build_file_helper(text_stream *text, text_file_position *tfp, void *state) ;
#line 59 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__write(build_file_data bfd, filename *F) ;
#line 77 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__set_bibliographic_data_for(web_md *WS) ;
#line 99 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__deduce_semver(web_md *WS) ;
#line 129 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__advance_for_web(web_md *WS) ;
#line 135 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__advance(filename *F) ;
#line 148 "inweb/foundation-module/Chapter 8/Build Files.w"
int BuildFiles__dated_today(text_stream *dateline) ;
#line 174 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__increment(text_stream *T) ;
#line 31 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
simple_tangle_docket SimpleTangler__new_docket( void (*A)(struct text_stream *, struct simple_tangle_docket *), void (*B)(struct text_stream *, struct text_stream *, struct text_stream *, struct simple_tangle_docket *), void (*C)(struct text_stream *, struct simple_tangle_docket *), void (*D)(char *, struct text_stream *), pathname *web_path, void *initial_state) ;
#line 53 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_text(simple_tangle_docket *docket, text_stream *text) ;
#line 57 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_file(simple_tangle_docket *docket, filename *F) ;
#line 61 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_section(simple_tangle_docket *docket, text_stream *leafname) ;
#line 65 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_web(simple_tangle_docket *docket) ;
#line 70 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_L1(simple_tangle_docket *docket, text_stream *text, filename *F, text_stream *leafname, int whole_web) ;
#line 81 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_L2(OUTPUT_STREAM, text_stream *text, filename *F, text_stream *leafname, simple_tangle_docket *docket, int whole_web) ;
#line 102 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_L3(OUTPUT_STREAM, text_stream *text, text_stream *leafname, simple_tangle_docket *docket, filename *F) ;
#line 64 "inweb/Chapter 1/Program Control.w"
int main(int argc, char **argv) ;
#line 95 "inweb/Chapter 1/Program Control.w"
void Main__follow_instructions(inweb_instructions *ins) ;
#line 275 "inweb/Chapter 1/Program Control.w"
void Main__error_in_web(text_stream *message, source_line *sl) ;
#line 59 "inweb/Chapter 1/Configuration.w"
inweb_instructions Configuration__read(int argc, char **argv) ;
#line 271 "inweb/Chapter 1/Configuration.w"
void Configuration__switch(int id, int val, text_stream *arg, void *state) ;
#line 383 "inweb/Chapter 1/Configuration.w"
void Configuration__member_and_colony(inweb_instructions *args) ;
#line 409 "inweb/Chapter 1/Configuration.w"
void Configuration__bareword(int id, text_stream *opt, void *state) ;
#line 424 "inweb/Chapter 1/Configuration.w"
void Configuration__set_range(inweb_instructions *args, text_stream *opt) ;
#line 456 "inweb/Chapter 1/Configuration.w"
void Configuration__set_fundamental_mode(inweb_instructions *args, int new_material) ;
#line 20 "inweb/Chapter 1/The Swarm.w"
void Swarm__weave(web *W, text_stream *range, int swarm_mode, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, linked_list *breadcrumbs, filename *navigation) ;
#line 51 "inweb/Chapter 1/The Swarm.w"
weave_order * Swarm__weave_subset(web *W, text_stream *range, int open_afterwards, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, linked_list *breadcrumbs, filename *navigation) ;
#line 190 "inweb/Chapter 1/The Swarm.w"
void Swarm__ensure_plugin(weave_order *wv, text_stream *name) ;
#line 199 "inweb/Chapter 1/The Swarm.w"
colour_scheme * Swarm__ensure_colour_scheme(weave_order *wv, text_stream *name, text_stream *pre) ;
#line 219 "inweb/Chapter 1/The Swarm.w"
void Swarm__include_plugins(OUTPUT_STREAM, web *W, weave_order *wv, filename *from) ;
#line 231 "inweb/Chapter 1/The Swarm.w"
void Swarm__weave_index_templates(web *W, text_stream *range, weave_pattern *pattern, pathname *into, filename *nav, linked_list *crumbs) ;
#line 42 "inweb/Chapter 1/Patterns.w"
weave_pattern * Patterns__find(web *W, text_stream *name) ;
#line 106 "inweb/Chapter 1/Patterns.w"
void Patterns__scan_pattern_line(text_stream *line, text_file_position *tfp, void *X) ;
#line 184 "inweb/Chapter 1/Patterns.w"
int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) ;
#line 191 "inweb/Chapter 1/Patterns.w"
text_stream * Patterns__plugin_name(text_stream *arg, text_file_position *tfp) ;
#line 208 "inweb/Chapter 1/Patterns.w"
void Patterns__post_process(weave_pattern *pattern, weave_order *wv) ;
#line 252 "inweb/Chapter 1/Patterns.w"
filename * Patterns__find_template(weave_pattern *pattern, text_stream *leafname) ;
#line 267 "inweb/Chapter 1/Patterns.w"
filename * Patterns__find_file_in_subdirectory(weave_pattern *pattern, text_stream *dirname, text_stream *leafname) ;
#line 278 "inweb/Chapter 1/Patterns.w"
void Patterns__include_plugins(OUTPUT_STREAM, web *W, weave_pattern *pattern, filename *from) ;
#line 19 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
weave_plugin * Assets__new(text_stream *name) ;
#line 43 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
colour_scheme * Assets__find_colour_scheme(weave_pattern *pattern, text_stream *name, text_stream *pre) ;
#line 71 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__include_relevant_plugins(text_stream *OUT, weave_pattern *pattern, web *W, weave_order *wv, filename *from) ;
#line 94 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__include_plugin(OUTPUT_STREAM, web *W, weave_plugin *wp, weave_pattern *pattern, filename *from) ;
#line 135 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__include_colour_scheme(OUTPUT_STREAM, web *W, colour_scheme *cs, weave_pattern *pattern, filename *from) ;
#line 184 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
linked_list * Assets__new_asset_rules_list(void) ;
#line 194 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__add_asset_rule(linked_list *L, text_stream *ext, text_stream *line, text_file_position *tfp) ;
#line 200 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
asset_rule * Assets__new_rule(linked_list *L, text_stream *ext, text_stream *line, text_file_position *tfp) ;
#line 252 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
asset_rule * Assets__applicable_rule(weave_pattern *pattern, filename *F) ;
#line 274 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
pathname * Assets__include_asset(OUTPUT_STREAM, asset_rule *R, web *W, filename *F, text_stream *trans, weave_pattern *pattern, filename *from) ;
#line 353 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__transform(text_stream *OUT, filename *F, text_stream *trans) ;
#line 361 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__transformer(text_stream *line, text_file_position *tfp, void *X) ;
#line 97 "inweb/Chapter 2/The Reader.w"
web_md * Reader__load_web_md(pathname *P, filename *alt_F, module_search *I, int including_modules) ;
#line 103 "inweb/Chapter 2/The Reader.w"
web * Reader__load_web(pathname *P, filename *alt_F, module_search *I, int including_modules) ;
#line 205 "inweb/Chapter 2/The Reader.w"
void Reader__read_web(web *W) ;
#line 219 "inweb/Chapter 2/The Reader.w"
void Reader__read_file(web *W, chapter *C, filename *F, text_stream *titling_line, section *S, int disregard_top) ;
#line 269 "inweb/Chapter 2/The Reader.w"
void Reader__scan_source_line(text_stream *line, text_file_position *tfp, void *state) ;
#line 296 "inweb/Chapter 2/The Reader.w"
pathname * Reader__woven_folder(web *W) ;
#line 302 "inweb/Chapter 2/The Reader.w"
pathname * Reader__tangled_folder(web *W) ;
#line 317 "inweb/Chapter 2/The Reader.w"
chapter * Reader__get_chapter_for_range(web *W, text_stream *range) ;
#line 326 "inweb/Chapter 2/The Reader.w"
section * Reader__get_section_for_range(web *W, text_stream *range) ;
#line 340 "inweb/Chapter 2/The Reader.w"
section * Reader__section_by_filename(web *W, text_stream *filename) ;
#line 362 "inweb/Chapter 2/The Reader.w"
int Reader__range_within(text_stream *range1, text_stream *range2) ;
#line 391 "inweb/Chapter 2/The Reader.w"
tangle_target * Reader__add_tangle_target(web *W, programming_language *language) ;
#line 415 "inweb/Chapter 2/The Reader.w"
void Reader__add_imported_header(web *W, filename *HF) ;
#line 422 "inweb/Chapter 2/The Reader.w"
int Reader__web_has_one_section(web *W) ;
#line 430 "inweb/Chapter 2/The Reader.w"
void Reader__print_web_statistics(web *W) ;
#line 47 "inweb/Chapter 2/Line Categories.w"
source_line * Lines__new_source_line_in(text_stream *line, text_file_position *tfp, section *S) ;
#line 118 "inweb/Chapter 2/Line Categories.w"
char * Lines__category_name(int cat) ;
#line 17 "inweb/Chapter 2/The Parser.w"
void Parser__parse_web(web *W, int inweb_mode) ;
#line 856 "inweb/Chapter 2/The Parser.w"
text_stream * Parser__extract_purpose(text_stream *prologue, source_line *XL, section *S, source_line **adjust) ;
#line 928 "inweb/Chapter 2/The Parser.w"
int Parser__detect_footnote(web *W, text_stream *matter, text_stream *before, text_stream *cue, text_stream *after) ;
#line 971 "inweb/Chapter 2/The Parser.w"
footnote * Parser__find_footnote_in_para(paragraph *P, text_stream *cue) ;
#line 988 "inweb/Chapter 2/The Parser.w"
text_stream * Parser__dimensions(text_stream *item, int *w, int *h, source_line *L) ;
#line 1036 "inweb/Chapter 2/The Parser.w"
void Parser__wrong_version(int using, source_line *L, char *feature, int need) ;
#line 20 "inweb/Chapter 2/Paragraph Macros.w"
para_macro * Macros__create(section *S, paragraph *P, source_line *L, text_stream *name) ;
#line 38 "inweb/Chapter 2/Paragraph Macros.w"
para_macro * Macros__find_by_name(text_stream *name, section *scope) ;
#line 22 "inweb/Chapter 2/Tags.w"
theme_tag * Tags__find_by_name(text_stream *name, int creating_if_necessary) ;
#line 56 "inweb/Chapter 2/Tags.w"
void Tags__add_to_paragraph(paragraph *P, theme_tag *tag, text_stream *caption) ;
#line 71 "inweb/Chapter 2/Tags.w"
theme_tag * Tags__add_by_name(paragraph *P, text_stream *text) ;
#line 91 "inweb/Chapter 2/Tags.w"
text_stream * Tags__retrieve_caption(paragraph *P, theme_tag *tag) ;
#line 107 "inweb/Chapter 2/Tags.w"
int Tags__tagged_with(paragraph *P, theme_tag *tag) ;
#line 119 "inweb/Chapter 2/Tags.w"
void Tags__open_ifdefs(OUTPUT_STREAM, paragraph *P) ;
#line 127 "inweb/Chapter 2/Tags.w"
void Tags__close_ifdefs(OUTPUT_STREAM, paragraph *P) ;
#line 135 "inweb/Chapter 2/Tags.w"
void Tags__show_endnote_on_ifdefs(heterogeneous_tree *tree, tree_node *ap, paragraph *P) ;
#line 27 "inweb/Chapter 2/Enumerated Constants.w"
enumeration_set * Enumerations__find(text_stream *post) ;
#line 40 "inweb/Chapter 2/Enumerated Constants.w"
void Enumerations__define(OUTPUT_STREAM, text_stream *symbol, text_stream *from, source_line *L) ;
#line 95 "inweb/Chapter 2/Enumerated Constants.w"
void Enumerations__define_extents(OUTPUT_STREAM, tangle_target *target, programming_language *lang) ;
#line 19 "inweb/Chapter 2/Paragraph Numbering.w"
void Numbering__number_web(web *W) ;
#line 149 "inweb/Chapter 2/Paragraph Numbering.w"
void Numbering__settle_paragraph_number(paragraph *P) ;
#line 160 "inweb/Chapter 2/Paragraph Numbering.w"
void Numbering__set_parent(paragraph *of, paragraph *to) ;
#line 11 "inweb/Chapter 3/The Analyser.w"
void Analyser__scan_line_categories(web *W, text_stream *range) ;
#line 52 "inweb/Chapter 3/The Analyser.w"
void Analyser__catalogue_the_sections(web *W, text_stream *range, int form) ;
#line 106 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_code(web *W) ;
#line 185 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_as_code(web *W, source_line *L, text_stream *text, int mask, int transf) ;
#line 232 "inweb/Chapter 3/The Analyser.w"
int Analyser__hash_code_from_word(text_stream *text) ;
#line 262 "inweb/Chapter 3/The Analyser.w"
void Analyser__initialise_hash_table(hash_table *HT) ;
#line 285 "inweb/Chapter 3/The Analyser.w"
hash_table_entry * Analyser__find_hash_entry(hash_table *HT, text_stream *text, int create) ;
#line 312 "inweb/Chapter 3/The Analyser.w"
hash_table_entry * Analyser__find_hash_entry_for_section(section *S, text_stream *text, int create) ;
#line 320 "inweb/Chapter 3/The Analyser.w"
hash_table_entry * Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) ;
#line 328 "inweb/Chapter 3/The Analyser.w"
void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) ;
#line 332 "inweb/Chapter 3/The Analyser.w"
hash_table_entry * Analyser__mark_reserved_word_at_line(source_line *L, text_stream *p, int e) ;
#line 340 "inweb/Chapter 3/The Analyser.w"
int Analyser__is_reserved_word(hash_table *HT, text_stream *p, int e) ;
#line 346 "inweb/Chapter 3/The Analyser.w"
int Analyser__is_reserved_word_for_section(section *S, text_stream *p, int e) ;
#line 350 "inweb/Chapter 3/The Analyser.w"
source_line * Analyser__get_defn_line(section *S, text_stream *p, int e) ;
#line 356 "inweb/Chapter 3/The Analyser.w"
language_function * Analyser__get_function(section *S, text_stream *p, int e) ;
#line 379 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_find(web *W, source_line *L, text_stream *identifier, int u) ;
#line 402 "inweb/Chapter 3/The Analyser.w"
void Analyser__write_makefile(web *W, filename *F, module_search *I, text_stream *platform) ;
#line 417 "inweb/Chapter 3/The Analyser.w"
void Analyser__write_gitignore(web *W, filename *F) ;
#line 19 "inweb/Chapter 3/The Collater.w"
void Collater__for_web_and_pattern(text_stream *OUT, web *W, weave_pattern *pattern, filename *F, filename *into) ;
#line 24 "inweb/Chapter 3/The Collater.w"
void Collater__for_order(text_stream *OUT, weave_order *wv, filename *F, filename *into) ;
#line 30 "inweb/Chapter 3/The Collater.w"
void Collater__collate(text_stream *OUT, web *W, text_stream *range, filename *template_filename, weave_pattern *pattern, filename *nav_file, linked_list *crumbs, weave_order *wv, filename *into) ;
#line 73 "inweb/Chapter 3/The Collater.w"
collater_state Collater__initial_state(web *W, text_stream *range, filename *template_filename, weave_pattern *pattern, filename *nav_file, linked_list *crumbs, weave_order *wv, filename *into) ;
#line 118 "inweb/Chapter 3/The Collater.w"
void Collater__temp_line(text_stream *line, text_file_position *tfp, void *v_ies) ;
#line 127 "inweb/Chapter 3/The Collater.w"
void Collater__process(text_stream *OUT, collater_state *cls) ;
#line 423 "inweb/Chapter 3/The Collater.w"
linked_list_item * Collater__heading_topmost_on_stack(collater_state *cls, int level) ;
#line 440 "inweb/Chapter 3/The Collater.w"
void Collater__start_CI_loop(collater_state *cls, int level, linked_list_item *from, linked_list_item *to, int pos) ;
#line 450 "inweb/Chapter 3/The Collater.w"
void Collater__end_CI_loop(collater_state *cls) ;
#line 750 "inweb/Chapter 3/The Collater.w"
text_stream * Collater__module_owner(const module *M, web *W) ;
#line 766 "inweb/Chapter 3/The Collater.w"
void Collater__sort_web(web *W) ;
#line 769 "inweb/Chapter 3/The Collater.w"
int Collater__sort_comparison(const void *ent1, const void *ent2) ;
#line 779 "inweb/Chapter 3/The Collater.w"
int Collater__cmp_owners(text_stream *O1, text_stream *O2) ;
#line 16 "inweb/Chapter 3/The Weaver.w"
int Weaver__weave(weave_order *wv) ;
#line 42 "inweb/Chapter 3/The Weaver.w"
int Weaver__weave_inner(weave_order *wv, heterogeneous_tree *tree, tree_node *body) ;
#line 579 "inweb/Chapter 3/The Weaver.w"
void Weaver__show_endnotes_on_previous_paragraph(heterogeneous_tree *tree, weave_order *wv, tree_node *ap, paragraph *P) ;
#line 694 "inweb/Chapter 3/The Weaver.w"
void Weaver__show_function_usage(heterogeneous_tree *tree, weave_order *wv, tree_node *ap, paragraph *P, language_function *fn, int as_list) ;
#line 759 "inweb/Chapter 3/The Weaver.w"
void Weaver__weave_subheading(heterogeneous_tree *tree, weave_order *wv, tree_node *ap, text_stream *text) ;
#line 765 "inweb/Chapter 3/The Weaver.w"
void Weaver__change_material(heterogeneous_tree *tree, weaver_state *state, int new_material, int plainly, programming_language *pl, text_stream *note) ;
#line 778 "inweb/Chapter 3/The Weaver.w"
void Weaver__change_material_for_para(heterogeneous_tree *tree, weaver_state *state) ;
#line 786 "inweb/Chapter 3/The Weaver.w"
void Weaver__figure(heterogeneous_tree *tree, weave_order *wv, tree_node *ap, text_stream *figname, int w, int h) ;
#line 792 "inweb/Chapter 3/The Weaver.w"
void Weaver__commentary_text(heterogeneous_tree *tree, weave_order *wv, tree_node *ap, text_stream *matter) ;
#line 802 "inweb/Chapter 3/The Weaver.w"
int Weaver__weave_table_of_contents(heterogeneous_tree *tree, tree_node *ap, section *S) ;
#line 12 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__commentary_text(heterogeneous_tree *tree, tree_node *ap, text_stream *matter) ;
#line 15 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__comment_text_in_code(heterogeneous_tree *tree, tree_node *ap, text_stream *matter) ;
#line 19 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__commentary_r(heterogeneous_tree *tree, tree_node *ap, text_stream *matter, int within, int in_code) ;
#line 200 "inweb/Chapter 3/The Weaver of Text.w"
int TextWeaver__boundary_character(int before, wchar_t c) ;
#line 210 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__commentary_fragment(heterogeneous_tree *tree, tree_node *ap, text_stream *fragment, int in_code) ;
#line 216 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__inline_code_fragment(heterogeneous_tree *tree, tree_node *ap, text_stream *fragment) ;
#line 229 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__source_code(heterogeneous_tree *tree, tree_node *ap, text_stream *matter, text_stream *colouring, int linked) ;
#line 334 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__source_code_piece(heterogeneous_tree *tree, tree_node *ap, text_stream *matter, text_stream *colouring, int from, int to) ;
#line 14 "inweb/Chapter 3/The Tangler.w"
void Tangler__tangle(web *W, tangle_target *target, filename *dest_file) ;
#line 141 "inweb/Chapter 3/The Tangler.w"
void Tangler__tangle_paragraph(OUTPUT_STREAM, paragraph *P) ;
#line 176 "inweb/Chapter 3/The Tangler.w"
void Tangler__tangle_line(OUTPUT_STREAM, text_stream *original, section *S, source_line *L) ;
#line 273 "inweb/Chapter 3/The Tangler.w"
tangle_target * Tangler__primary_target(web *W) ;
#line 10 "inweb/Chapter 4/Programming Languages.w"
programming_language * Languages__find_by_name(text_stream *lname, web *W, int error_if_not_found) ;
#line 54 "inweb/Chapter 4/Programming Languages.w"
programming_language * Languages__default(web *W) ;
#line 58 "inweb/Chapter 4/Programming Languages.w"
void Languages__show(OUTPUT_STREAM) ;
#line 75 "inweb/Chapter 4/Programming Languages.w"
int Languages__compare_names(const void *ent1, const void *ent2) ;
#line 84 "inweb/Chapter 4/Programming Languages.w"
void Languages__read_definitions(pathname *P) ;
#line 98 "inweb/Chapter 4/Programming Languages.w"
pathname * Languages__default_directory(void) ;
#line 161 "inweb/Chapter 4/Programming Languages.w"
programming_language * Languages__read_definition(filename *F) ;
#line 226 "inweb/Chapter 4/Programming Languages.w"
void Languages__read_definition_line(text_stream *line, text_file_position *tfp, void *v_state) ;
#line 408 "inweb/Chapter 4/Programming Languages.w"
colouring_language_block * Languages__new_block(colouring_language_block *within, int r) ;
#line 462 "inweb/Chapter 4/Programming Languages.w"
colouring_rule * Languages__new_rule(colouring_language_block *within) ;
#line 486 "inweb/Chapter 4/Programming Languages.w"
void Languages__parse_rule(language_reader_state *state, text_stream *premiss, text_stream *action, text_file_position *tfp) ;
#line 566 "inweb/Chapter 4/Programming Languages.w"
reserved_word * Languages__reserved(programming_language *pl, text_stream *W, wchar_t C, text_file_position *tfp) ;
#line 603 "inweb/Chapter 4/Programming Languages.w"
wchar_t Languages__colour(text_stream *T, text_file_position *tfp) ;
#line 628 "inweb/Chapter 4/Programming Languages.w"
int Languages__boolean(text_stream *T, text_file_position *tfp) ;
#line 642 "inweb/Chapter 4/Programming Languages.w"
text_stream * Languages__text(text_stream *T, text_file_position *tfp, int allow) ;
#line 729 "inweb/Chapter 4/Programming Languages.w"
void Languages__regexp(wchar_t *write_to, text_stream *T, text_file_position *tfp) ;
#line 779 "inweb/Chapter 4/Programming Languages.w"
int Languages__add_to_regexp(wchar_t *write_to, int i, wchar_t c) ;
#line 784 "inweb/Chapter 4/Programming Languages.w"
int Languages__add_escape_to_regexp(wchar_t *write_to, int i, wchar_t c) ;
#line 22 "inweb/Chapter 4/Types and Functions.w"
language_type * Functions__new_struct(web *W, text_stream *name, source_line *L) ;
#line 86 "inweb/Chapter 4/Types and Functions.w"
structure_element * Functions__new_element(language_type *str, text_stream *elname, source_line *L) ;
#line 100 "inweb/Chapter 4/Types and Functions.w"
language_type * Functions__find_structure(web *W, text_stream *name) ;
#line 127 "inweb/Chapter 4/Types and Functions.w"
language_function * Functions__new_function(text_stream *fname, source_line *L) ;
#line 192 "inweb/Chapter 4/Types and Functions.w"
int Functions__used_elsewhere(language_function *fn) ;
#line 213 "inweb/Chapter 4/Types and Functions.w"
void Functions__catalogue(section *S, int functions_too) ;
#line 37 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__parse_types(web *W, programming_language *pl) ;
#line 47 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__parse_functions(web *W, programming_language *pl) ;
#line 59 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__further_parsing(web *W, programming_language *pl) ;
#line 72 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__subcategorise_line(programming_language *pl, source_line *L) ;
#line 86 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__parse_comment(programming_language *pl, text_stream *line, text_stream *before, text_stream *within) ;
#line 105 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__shebang(OUTPUT_STREAM, programming_language *pl, web *W, tangle_target *target) ;
#line 116 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__disclaimer(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ;
#line 130 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__additional_early_matter(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ;
#line 149 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__start_definition(OUTPUT_STREAM, programming_language *pl, text_stream *term, text_stream *start, section *S, source_line *L) ;
#line 157 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__prolong_definition(OUTPUT_STREAM, programming_language *pl, text_stream *more, section *S, source_line *L) ;
#line 165 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__end_definition(OUTPUT_STREAM, programming_language *pl, section *S, source_line *L) ;
#line 178 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__additional_predeclarations(OUTPUT_STREAM, programming_language *pl, web *W) ;
#line 191 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__allow_expansion(programming_language *pl, text_stream *material) ;
#line 206 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__special_tangle_command(OUTPUT_STREAM, programming_language *pl, text_stream *data) ;
#line 223 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__will_insert_in_tangle(programming_language *pl, source_line *L) ;
#line 228 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__insert_in_tangle(OUTPUT_STREAM, programming_language *pl, source_line *L) ;
#line 241 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__insert_line_marker(OUTPUT_STREAM, programming_language *pl, source_line *L) ;
#line 255 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__before_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ;
#line 258 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__after_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ;
#line 272 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__open_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ;
#line 275 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__close_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ;
#line 285 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__comment(OUTPUT_STREAM, programming_language *pl, text_stream *comm) ;
#line 297 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__tangle_line(OUTPUT_STREAM, programming_language *pl, text_stream *original) ;
#line 309 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__gnabehs(OUTPUT_STREAM, programming_language *pl, web *W) ;
#line 321 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__additional_tangling(programming_language *pl, web *W, tangle_target *target) ;
#line 333 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__begin_weave(section *S, weave_order *wv) ;
#line 343 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__skip_in_weaving(programming_language *pl, weave_order *wv, source_line *L) ;
#line 358 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__reset_syntax_colouring(programming_language *pl) ;
#line 371 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__syntax_colour(programming_language *pl, weave_order *wv, source_line *L, text_stream *matter, text_stream *colouring) ;
#line 398 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__weave_code_line(OUTPUT_STREAM, programming_language *pl, weave_order *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
#line 411 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__new_tag_declared(theme_tag *tag) ;
#line 434 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__early_preweave_analysis(programming_language *pl, web *W) ;
#line 437 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__late_preweave_analysis(programming_language *pl, web *W) ;
#line 448 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__share_element(programming_language *pl, text_stream *element_name) ;
#line 457 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__supports_definitions(programming_language *pl) ;
#line 16 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__add_fallbacks(programming_language *pl) ;
#line 62 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__expand(OUTPUT_STREAM, text_stream *prototype, text_stream *S, int N, filename *F) ;
#line 86 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__shebang(programming_language *pl, text_stream *OUT, web *W, tangle_target *target) ;
#line 91 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__before_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ;
#line 96 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__after_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ;
#line 101 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__start_definition(programming_language *pl, text_stream *OUT, text_stream *term, text_stream *start, section *S, source_line *L) ;
#line 110 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__prolong_definition(programming_language *pl, text_stream *OUT, text_stream *more, section *S, source_line *L) ;
#line 119 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__end_definition(programming_language *pl, text_stream *OUT, section *S, source_line *L) ;
#line 127 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__I6_open_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ;
#line 133 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__I6_close_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ;
#line 139 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__insert_line_marker(programming_language *pl, text_stream *OUT, source_line *L) ;
#line 145 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__comment(programming_language *pl, text_stream *OUT, text_stream *comm) ;
#line 166 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__parse_comment(programming_language *pl, text_stream *line, text_stream *part_before_comment, text_stream *part_within_comment) ;
#line 243 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_types(programming_language *self, web *W) ;
#line 262 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_functions(programming_language *self, web *W) ;
#line 287 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__post_analysis(programming_language *self, web *W) ;
#line 323 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__analyse_code(programming_language *self, web *W) ;
#line 341 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__suppress_disclaimer(programming_language *pl) ;
#line 348 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__begin_weave(programming_language *pl, section *S, weave_order *wv) ;
#line 357 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__reset_syntax_colouring(programming_language *pl) ;
#line 361 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__syntax_colour(programming_language *pl, weave_order *wv, source_line *L, text_stream *matter, text_stream *colouring) ;
#line 17 "inweb/Chapter 4/The Painter.w"
void Painter__reset_syntax_colouring(programming_language *pl) ;
#line 38 "inweb/Chapter 4/The Painter.w"
int Painter__syntax_colour(programming_language *pl, hash_table *HT, text_stream *matter, text_stream *colouring, int with_comments) ;
#line 58 "inweb/Chapter 4/The Painter.w"
void Painter__syntax_colour_inner(programming_language *pl, hash_table *HT, text_stream *matter, text_stream *colouring, int from, int to) ;
#line 171 "inweb/Chapter 4/The Painter.w"
int Painter__identifier_at(programming_language *pl, text_stream *matter, text_stream *colouring, int i) ;
#line 204 "inweb/Chapter 4/The Painter.w"
void Painter__execute(hash_table *HT, colouring_language_block *block, text_stream *matter, text_stream *colouring, int from, int to, int N) ;
#line 285 "inweb/Chapter 4/The Painter.w"
void Painter__execute_rule(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to, int N) ;
#line 301 "inweb/Chapter 4/The Painter.w"
int Painter__satisfies(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to, int N) ;
#line 365 "inweb/Chapter 4/The Painter.w"
void Painter__follow(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to) ;
#line 392 "inweb/Chapter 4/The Painter.w"
linked_list * Painter__lines(filename *F) ;
#line 414 "inweb/Chapter 4/The Painter.w"
void Painter__text_file_helper(text_stream *text, text_file_position *tfp, void *state) ;
#line 419 "inweb/Chapter 4/The Painter.w"
void Painter__colour_file(programming_language *pl, filename *F, text_stream *to, text_stream *coloured) ;
#line 9 "inweb/Chapter 4/C-Like Languages.w"
void CLike__make_c_like(programming_language *pl) ;
#line 24 "inweb/Chapter 4/C-Like Languages.w"
void CLike__parse_types(programming_language *self, web *W) ;
#line 187 "inweb/Chapter 4/C-Like Languages.w"
void CLike__parse_functions(programming_language *self, web *W) ;
#line 316 "inweb/Chapter 4/C-Like Languages.w"
void CLike__subcategorise_code(programming_language *self, source_line *L) ;
#line 345 "inweb/Chapter 4/C-Like Languages.w"
void CLike__additional_early_matter(programming_language *self, text_stream *OUT, web *W, tangle_target *target) ;
#line 364 "inweb/Chapter 4/C-Like Languages.w"
void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) ;
#line 402 "inweb/Chapter 4/C-Like Languages.w"
void CLike__tangle_structure(OUTPUT_STREAM, programming_language *self, language_type *str) ;
#line 10 "inweb/Chapter 4/InC Support.w"
void InCSupport__add_features(programming_language *pl) ;
#line 41 "inweb/Chapter 4/InC Support.w"
void InCSupport__further_parsing(programming_language *self, web *W) ;
#line 368 "inweb/Chapter 4/InC Support.w"
int InCSupport__suppress_expansion(programming_language *self, text_stream *material) ;
#line 392 "inweb/Chapter 4/InC Support.w"
int InCSupport__special_tangle_command(programming_language *me, OUTPUT_STREAM, text_stream *data) ;
#line 416 "inweb/Chapter 4/InC Support.w"
void InCSupport__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) ;
#line 445 "inweb/Chapter 4/InC Support.w"
void InCSupport__gnabehs(programming_language *self, text_stream *OUT, web *W) ;
#line 479 "inweb/Chapter 4/InC Support.w"
int InCSupport__will_insert_in_tangle(programming_language *self, source_line *L) ;
#line 500 "inweb/Chapter 4/InC Support.w"
void InCSupport__insert_in_tangle(programming_language *self, text_stream *OUT, source_line *L) ;
#line 633 "inweb/Chapter 4/InC Support.w"
void InCSupport__expand_formula(text_stream *OUT, source_line *AL, preform_nonterminal *pnt, text_stream *formula, int full) ;
#line 661 "inweb/Chapter 4/InC Support.w"
int InCSupport__tangle_line(programming_language *self, text_stream *OUT, text_stream *original) ;
#line 666 "inweb/Chapter 4/InC Support.w"
void InCSupport__tangle_line_inner(text_stream *OUT, source_line *AL, preform_nonterminal *pnt, text_stream *original) ;
#line 916 "inweb/Chapter 4/InC Support.w"
preform_nonterminal * InCSupport__nonterminal_by_name(text_stream *name) ;
#line 930 "inweb/Chapter 4/InC Support.w"
text_stream * InCSupport__nonterminal_variable_identifier(text_stream *name) ;
#line 951 "inweb/Chapter 4/InC Support.w"
void InCSupport__additional_tangling(programming_language *self, web *W, tangle_target *target) ;
#line 1014 "inweb/Chapter 4/InC Support.w"
void InCSupport__weave_grammar_index(OUTPUT_STREAM) ;
#line 1092 "inweb/Chapter 4/InC Support.w"
int InCSupport__skip_in_weaving(programming_language *self, weave_order *wv, source_line *L) ;
#line 1107 "inweb/Chapter 4/InC Support.w"
int InCSupport__weave_code_line(programming_language *self, text_stream *OUT, weave_order *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
#line 1121 "inweb/Chapter 4/InC Support.w"
void InCSupport__new_tag_declared(programming_language *self, theme_tag *tag) ;
#line 1128 "inweb/Chapter 4/InC Support.w"
void InCSupport__analyse_code(programming_language *self, web *W) ;
#line 1135 "inweb/Chapter 4/InC Support.w"
int InCSupport__share_element(programming_language *self, text_stream *elname) ;
#line 301 "inweb/Chapter 5/Weave Tree.w"
heterogeneous_tree * WeaveTree__new_tree(weave_order *wv) ;
#line 404 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__document(heterogeneous_tree *tree, weave_order *wv) ;
#line 411 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__head(heterogeneous_tree *tree, text_stream *banner) ;
#line 418 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__body(heterogeneous_tree *tree) ;
#line 424 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__tail(heterogeneous_tree *tree, text_stream *rennab) ;
#line 431 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__verbatim(heterogeneous_tree *tree, text_stream *content) ;
#line 438 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__section_header(heterogeneous_tree *tree, section *S) ;
#line 445 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__section_footer(heterogeneous_tree *tree, section *S) ;
#line 452 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__chapter(heterogeneous_tree *tree, chapter *Ch) ;
#line 458 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__chapter_header(heterogeneous_tree *tree, chapter *Ch) ;
#line 465 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__chapter_footer(heterogeneous_tree *tree, chapter *Ch) ;
#line 472 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__purpose(heterogeneous_tree *tree, text_stream *P) ;
#line 479 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__subheading(heterogeneous_tree *tree, text_stream *P) ;
#line 486 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__pagebreak(heterogeneous_tree *tree) ;
#line 492 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__linebreak(heterogeneous_tree *tree) ;
#line 498 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__bar(heterogeneous_tree *tree) ;
#line 504 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__paragraph_heading(heterogeneous_tree *tree, paragraph *P, int no_skip) ;
#line 512 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__endnote(heterogeneous_tree *tree) ;
#line 518 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__figure(heterogeneous_tree *tree, text_stream *figname, int w, int h) ;
#line 528 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__raw_extract(heterogeneous_tree *tree, text_stream *extract) ;
#line 536 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__audio(heterogeneous_tree *tree, text_stream *audio_name, int w) ;
#line 545 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__video(heterogeneous_tree *tree, text_stream *video_name, int w, int h) ;
#line 554 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__download(heterogeneous_tree *tree, text_stream *download_name, text_stream *filetype) ;
#line 563 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__material(heterogeneous_tree *tree, int material_type, int plainly, programming_language *styling, text_stream *endnote) ;
#line 573 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__embed(heterogeneous_tree *tree, text_stream *service, text_stream *ID, int w, int h) ;
#line 588 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__pmac(heterogeneous_tree *tree, para_macro *pmac, int defn) ;
#line 600 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__vskip(heterogeneous_tree *tree, int in_comment) ;
#line 606 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__section(heterogeneous_tree *tree, section *sect) ;
#line 612 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__code_line(heterogeneous_tree *tree) ;
#line 617 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__function_usage(heterogeneous_tree *tree, text_stream *url, language_function *fn) ;
#line 625 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__commentary(heterogeneous_tree *tree, text_stream *text, int in_code) ;
#line 632 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__carousel_slide(heterogeneous_tree *tree, text_stream *caption, int c) ;
#line 639 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__table_of_contents(heterogeneous_tree *tree, text_stream *text1) ;
#line 645 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__contents_line(heterogeneous_tree *tree, text_stream *text1, text_stream *text2, paragraph *P) ;
#line 654 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__weave_chapter_title_page_node(heterogeneous_tree *tree) ;
#line 659 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__weave_defn_node(heterogeneous_tree *tree, text_stream *keyword) ;
#line 676 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__source_code(heterogeneous_tree *tree, text_stream *matter, text_stream *colouring) ;
#line 708 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__url(heterogeneous_tree *tree, text_stream *url, text_stream *content, int external) ;
#line 717 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__footnote_cue(heterogeneous_tree *tree, text_stream *cue) ;
#line 723 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__footnote(heterogeneous_tree *tree, text_stream *cue) ;
#line 733 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__function_defn(heterogeneous_tree *tree, language_function *fn) ;
#line 743 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__display_line(heterogeneous_tree *tree, text_stream *text) ;
#line 762 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__weave_item_node(heterogeneous_tree *tree, int depth, text_stream *label) ;
#line 769 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__grammar_index(heterogeneous_tree *tree) ;
#line 774 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__inline(heterogeneous_tree *tree) ;
#line 779 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__locale(heterogeneous_tree *tree, paragraph *par1, paragraph *par2) ;
#line 786 "inweb/Chapter 5/Weave Tree.w"
tree_node * WeaveTree__mathematics(heterogeneous_tree *tree, text_stream *content, int displayed) ;
#line 793 "inweb/Chapter 5/Weave Tree.w"
void WeaveTree__show(text_stream *OUT, heterogeneous_tree *T) ;
#line 800 "inweb/Chapter 5/Weave Tree.w"
void WeaveTree__prune(heterogeneous_tree *T) ;
#line 804 "inweb/Chapter 5/Weave Tree.w"
int WeaveTree__prune_visit(tree_node *N, void *state) ;
#line 18 "inweb/Chapter 5/Format Methods.w"
weave_format * Formats__create_weave_format(text_stream *name, text_stream *ext) ;
#line 26 "inweb/Chapter 5/Format Methods.w"
weave_format * Formats__find_by_name(text_stream *name) ;
#line 40 "inweb/Chapter 5/Format Methods.w"
text_stream * Formats__file_extension(weave_format *wf) ;
#line 48 "inweb/Chapter 5/Format Methods.w"
void Formats__create_weave_formats(void) ;
#line 72 "inweb/Chapter 5/Format Methods.w"
int Formats__begin_weaving(web *W, weave_pattern *pattern) ;
#line 78 "inweb/Chapter 5/Format Methods.w"
void Formats__end_weaving(web *W, weave_pattern *pattern) ;
#line 95 "inweb/Chapter 5/Format Methods.w"
void Formats__render(text_stream *OUT, heterogeneous_tree *tree, filename *into) ;
#line 120 "inweb/Chapter 5/Format Methods.w"
int Formats__preform_document(OUTPUT_STREAM, weave_order *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
#line 139 "inweb/Chapter 5/Format Methods.w"
void Formats__post_process_weave(weave_order *wv, int open_afterwards) ;
#line 151 "inweb/Chapter 5/Format Methods.w"
void Formats__report_on_post_processing(weave_order *wv) ;
#line 164 "inweb/Chapter 5/Format Methods.w"
int Formats__substitute_post_processing_data(OUTPUT_STREAM, weave_order *wv, text_stream *detail, weave_pattern *pattern) ;
#line 9 "inweb/Chapter 5/Plain Text Format.w"
void PlainText__create(void) ;
#line 23 "inweb/Chapter 5/Plain Text Format.w"
void PlainText__render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) ;
#line 31 "inweb/Chapter 5/Plain Text Format.w"
int PlainText__render_visit(tree_node *N, void *state, int L) ;
#line 9 "inweb/Chapter 5/TeX Format.w"
void TeX__create(void) ;
#line 25 "inweb/Chapter 5/TeX Format.w"
void TeX__render_TeX(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) ;
#line 39 "inweb/Chapter 5/TeX Format.w"
void TeX__render_inner(text_stream *OUT, heterogeneous_tree *tree, int form) ;
#line 51 "inweb/Chapter 5/TeX Format.w"
int TeX__render_visit(tree_node *N, void *state, int L) ;
#line 399 "inweb/Chapter 5/TeX Format.w"
void TeX__general_heading(text_stream *OUT, weave_order *wv, section *S, paragraph *P, text_stream *heading_text, int weight, int no_skip) ;
#line 496 "inweb/Chapter 5/TeX Format.w"
void TeX__source_code(text_stream *OUT, weave_order *wv, text_stream *matter, text_stream *colouring, int starts) ;
#line 515 "inweb/Chapter 5/TeX Format.w"
void TeX__change_colour_PDF(text_stream *OUT, int col, int in_code) ;
#line 538 "inweb/Chapter 5/TeX Format.w"
void TeX__para_macro(text_stream *OUT, weave_order *wv, para_macro *pmac, int defn) ;
#line 558 "inweb/Chapter 5/TeX Format.w"
void TeX__commentary_text(text_stream *OUT, weave_order *wv, text_stream *id) ;
#line 583 "inweb/Chapter 5/TeX Format.w"
int TeX__preform_document(weave_format *self, text_stream *OUT, web *W, weave_order *wv, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
#line 9 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__create(void) ;
#line 45 "inweb/Chapter 5/HTML Formats.w"
HTML_render_state HTMLFormat__initial_state(text_stream *OUT, weave_order *wv, int EPUB_mode, filename *into) ;
#line 67 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) ;
#line 74 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__render_EPUB(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) ;
#line 86 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__render_visit(tree_node *N, void *state, int L) ;
#line 917 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__interior_material(tree_node *N) ;
#line 931 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__go_to_depth(HTML_render_state *hrs, int from_depth, int to_depth) ;
#line 949 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__paragraph_number(text_stream *OUT, paragraph *P) ;
#line 964 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__change_colour(text_stream *OUT, int col, colour_scheme *cs) ;
#line 988 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__escape_text(text_stream *OUT, text_stream *id) ;
#line 1000 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ;
#line 1015 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__end_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ;
#line 9 "inweb/Chapter 5/Debugging Format.w"
void Debugging__create(void) ;
#line 23 "inweb/Chapter 5/Debugging Format.w"
void Debugging__render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) ;
#line 31 "inweb/Chapter 5/Debugging Format.w"
int Debugging__render_visit(tree_node *N, void *state, int L) ;
#line 274 "inweb/Chapter 5/Debugging Format.w"
void Debugging__show_text(text_stream *OUT, text_stream *text, int limit) ;
#line 285 "inweb/Chapter 5/Debugging Format.w"
void Debugging__show_para(text_stream *OUT, paragraph *P) ;
#line 290 "inweb/Chapter 5/Debugging Format.w"
void Debugging__show_mat(text_stream *OUT, int m) ;
#line 30 "inweb/Chapter 5/TeX Utilities.w"
tex_results * TeXUtilities__new_results(weave_order *wv, filename *CF) ;
#line 44 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__post_process_weave(weave_order *wv, filename *CF) ;
#line 52 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__scan_console_line(text_stream *line, text_file_position *tfp, void *res_V) ;
#line 72 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__report_on_post_processing(weave_order *wv) ;
#line 86 "inweb/Chapter 5/TeX Utilities.w"
int TeXUtilities__substitute_post_processing_data(text_stream *to, weave_order *wv, text_stream *detail) ;
#line 126 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__remove_math_mode(OUTPUT_STREAM, text_stream *text) ;
#line 133 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) ;
#line 12 "inweb/Chapter 6/Makefiles.w"
void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I, text_stream *platform) ;
#line 72 "inweb/Chapter 6/Makefiles.w"
void Makefiles__identity_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 94 "inweb/Chapter 6/Makefiles.w"
void Makefiles__platform_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 119 "inweb/Chapter 6/Makefiles.w"
void Makefiles__seek_INWEBPLATFORM(text_stream *line, text_file_position *tfp, void *X) ;
#line 129 "inweb/Chapter 6/Makefiles.w"
void Makefiles__modify_filenames_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 185 "inweb/Chapter 6/Makefiles.w"
void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 235 "inweb/Chapter 6/Makefiles.w"
void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 268 "inweb/Chapter 6/Makefiles.w"
void Makefiles__dependent_files_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 324 "inweb/Chapter 6/Makefiles.w"
void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) ;
#line 365 "inweb/Chapter 6/Makefiles.w"
void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) ;
#line 8 "inweb/Chapter 6/Git Support.w"
void Git__write_gitignore(web *W, filename *prototype, filename *F) ;
#line 22 "inweb/Chapter 6/Git Support.w"
void Git__basics_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 35 "inweb/Chapter 6/Ctags Support.w"
void Ctags__write(web *W, filename *F) ;
#line 146 "inweb/Chapter 6/Ctags Support.w"
void Ctags__write_line_ref(OUTPUT_STREAM, source_line *L, pathname *P) ;
#line 182 "inweb/Chapter 6/Ctags Support.w"
void Ctags__note_defined_constant(source_line *L, text_stream *name) ;
#line 10 "inweb/Chapter 6/Readme Writeme.w"
void Readme__write(filename *prototype, filename *F) ;
#line 23 "inweb/Chapter 6/Readme Writeme.w"
void Readme__bibliographic_expander(preprocessor_macro *mm, preprocessor_state *PPS, text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) ;
#line 50 "inweb/Chapter 6/Readme Writeme.w"
void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) ;
#line 60 "inweb/Chapter 6/Readme Writeme.w"
writeme_asset * Readme__find_asset(text_stream *program) ;
#line 111 "inweb/Chapter 6/Readme Writeme.w"
void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) ;
#line 123 "inweb/Chapter 6/Readme Writeme.w"
void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) ;
#line 137 "inweb/Chapter 6/Readme Writeme.w"
void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) ;
#line 153 "inweb/Chapter 6/Readme Writeme.w"
void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) ;
#line 66 "inweb/Chapter 6/Colonies.w"
void Colonies__load(filename *F) ;
#line 84 "inweb/Chapter 6/Colonies.w"
void Colonies__read_line(text_stream *line, text_file_position *tfp, void *v_crs) ;
#line 151 "inweb/Chapter 6/Colonies.w"
void Colonies__add_crumb(linked_list *L, text_stream *spec, text_file_position *tfp) ;
#line 169 "inweb/Chapter 6/Colonies.w"
breadcrumb_request * Colonies__request_breadcrumb(text_stream *arg) ;
#line 184 "inweb/Chapter 6/Colonies.w"
void Colonies__drop_initial_breadcrumbs(OUTPUT_STREAM, filename *F, linked_list *crumbs) ;
#line 194 "inweb/Chapter 6/Colonies.w"
void Colonies__write_breadcrumb(OUTPUT_STREAM, text_stream *text, text_stream *link) ;
#line 215 "inweb/Chapter 6/Colonies.w"
colony_member * Colonies__find(text_stream *T) ;
#line 233 "inweb/Chapter 6/Colonies.w"
module * Colonies__as_module(colony_member *CM, source_line *L, web_md *Wm) ;
#line 270 "inweb/Chapter 6/Colonies.w"
text_stream * Colonies__home(void) ;
#line 277 "inweb/Chapter 6/Colonies.w"
pathname * Colonies__assets_path(void) ;
#line 284 "inweb/Chapter 6/Colonies.w"
pathname * Colonies__patterns_path(void) ;
#line 310 "inweb/Chapter 6/Colonies.w"
int Colonies__resolve_reference_in_weave(text_stream *url, text_stream *title, filename *for_HTML_file, text_stream *text, web_md *Wm, source_line *L, int *ext) ;
#line 327 "inweb/Chapter 6/Colonies.w"
int Colonies__resolve_reference_in_weave_inner(text_stream *url, text_stream *title, filename *for_HTML_file, text_stream *text, web_md *Wm, source_line *L, int *ext) ;
#line 468 "inweb/Chapter 6/Colonies.w"
void Colonies__link_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) ;
#line 477 "inweb/Chapter 6/Colonies.w"
void Colonies__reference_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) ;
#line 488 "inweb/Chapter 6/Colonies.w"
void Colonies__section_URL(OUTPUT_STREAM, section_md *Sm) ;
#line 498 "inweb/Chapter 6/Colonies.w"
void Colonies__paragraph_URL(OUTPUT_STREAM, paragraph *P, filename *from) ;
#line 519 "inweb/Chapter 6/Colonies.w"
void Colonies__paragraph_anchor(OUTPUT_STREAM, paragraph *P) ;
void register_tangled_nonterminals(void);
text_stream *TL_IS_0 = NULL;
text_stream *TL_IS_1 = NULL;
text_stream *TL_IS_2 = NULL;
text_stream *TL_IS_3 = NULL;
text_stream *TL_IS_4 = NULL;
text_stream *TL_IS_5 = NULL;
text_stream *TL_IS_6 = NULL;
text_stream *TL_IS_7 = NULL;
text_stream *TL_IS_8 = NULL;
text_stream *TL_IS_9 = NULL;
text_stream *TL_IS_10 = NULL;
text_stream *TL_IS_11 = NULL;
text_stream *TL_IS_12 = NULL;
text_stream *TL_IS_13 = NULL;
text_stream *TL_IS_14 = NULL;
text_stream *TL_IS_15 = NULL;
text_stream *TL_IS_16 = NULL;
text_stream *TL_IS_17 = NULL;
text_stream *TL_IS_18 = NULL;
text_stream *TL_IS_19 = NULL;
text_stream *TL_IS_20 = NULL;
text_stream *TL_IS_21 = NULL;
text_stream *TL_IS_22 = NULL;
text_stream *TL_IS_23 = NULL;
text_stream *TL_IS_24 = NULL;
text_stream *TL_IS_25 = NULL;
text_stream *TL_IS_26 = NULL;
text_stream *TL_IS_27 = NULL;
text_stream *TL_IS_28 = NULL;
text_stream *TL_IS_29 = NULL;
text_stream *TL_IS_30 = NULL;
text_stream *TL_IS_31 = NULL;
text_stream *TL_IS_32 = NULL;
text_stream *TL_IS_33 = NULL;
text_stream *TL_IS_34 = NULL;
text_stream *TL_IS_35 = NULL;
text_stream *TL_IS_36 = NULL;
text_stream *TL_IS_37 = NULL;
text_stream *TL_IS_38 = NULL;
text_stream *TL_IS_39 = NULL;
text_stream *TL_IS_40 = NULL;
text_stream *TL_IS_41 = NULL;
text_stream *TL_IS_42 = NULL;
text_stream *TL_IS_43 = NULL;
text_stream *TL_IS_44 = NULL;
text_stream *TL_IS_45 = NULL;
text_stream *TL_IS_46 = NULL;
text_stream *TL_IS_47 = NULL;
text_stream *TL_IS_48 = NULL;
text_stream *TL_IS_49 = NULL;
text_stream *TL_IS_50 = NULL;
text_stream *TL_IS_51 = NULL;
text_stream *TL_IS_52 = NULL;
text_stream *TL_IS_53 = NULL;
text_stream *TL_IS_54 = NULL;
text_stream *TL_IS_55 = NULL;
text_stream *TL_IS_56 = NULL;
text_stream *TL_IS_57 = NULL;
text_stream *TL_IS_58 = NULL;
text_stream *TL_IS_59 = NULL;
text_stream *TL_IS_60 = NULL;
text_stream *TL_IS_61 = NULL;
text_stream *TL_IS_62 = NULL;
text_stream *TL_IS_63 = NULL;
text_stream *TL_IS_64 = NULL;
text_stream *TL_IS_65 = NULL;
text_stream *TL_IS_66 = NULL;
text_stream *TL_IS_67 = NULL;
text_stream *TL_IS_68 = NULL;
text_stream *TL_IS_69 = NULL;
text_stream *TL_IS_70 = NULL;
text_stream *TL_IS_71 = NULL;
text_stream *TL_IS_72 = NULL;
text_stream *TL_IS_73 = NULL;
text_stream *TL_IS_74 = NULL;
text_stream *TL_IS_75 = NULL;
text_stream *TL_IS_76 = NULL;
text_stream *TL_IS_77 = NULL;
text_stream *TL_IS_78 = NULL;
text_stream *TL_IS_79 = NULL;
text_stream *TL_IS_80 = NULL;
text_stream *TL_IS_81 = NULL;
text_stream *TL_IS_82 = NULL;
text_stream *TL_IS_83 = NULL;
text_stream *TL_IS_84 = NULL;
text_stream *TL_IS_85 = NULL;
text_stream *TL_IS_86 = NULL;
text_stream *TL_IS_87 = NULL;
text_stream *TL_IS_88 = NULL;
text_stream *TL_IS_89 = NULL;
text_stream *TL_IS_90 = NULL;
text_stream *TL_IS_91 = NULL;
text_stream *TL_IS_92 = NULL;
text_stream *TL_IS_93 = NULL;
text_stream *TL_IS_94 = NULL;
text_stream *TL_IS_95 = NULL;
text_stream *TL_IS_96 = NULL;
text_stream *TL_IS_97 = NULL;
text_stream *TL_IS_98 = NULL;
text_stream *TL_IS_99 = NULL;
text_stream *TL_IS_100 = NULL;
text_stream *TL_IS_101 = NULL;
text_stream *TL_IS_102 = NULL;
text_stream *TL_IS_103 = NULL;
text_stream *TL_IS_104 = NULL;
text_stream *TL_IS_105 = NULL;
text_stream *TL_IS_106 = NULL;
text_stream *TL_IS_107 = NULL;
text_stream *TL_IS_108 = NULL;
text_stream *TL_IS_109 = NULL;
text_stream *TL_IS_110 = NULL;
text_stream *TL_IS_111 = NULL;
text_stream *TL_IS_112 = NULL;
text_stream *TL_IS_113 = NULL;
text_stream *TL_IS_114 = NULL;
text_stream *TL_IS_115 = NULL;
text_stream *TL_IS_116 = NULL;
text_stream *TL_IS_117 = NULL;
text_stream *TL_IS_118 = NULL;
text_stream *TL_IS_119 = NULL;
text_stream *TL_IS_120 = NULL;
text_stream *TL_IS_121 = NULL;
text_stream *TL_IS_122 = NULL;
text_stream *TL_IS_123 = NULL;
text_stream *TL_IS_124 = NULL;
text_stream *TL_IS_125 = NULL;
text_stream *TL_IS_126 = NULL;
text_stream *TL_IS_127 = NULL;
text_stream *TL_IS_128 = NULL;
text_stream *TL_IS_129 = NULL;
text_stream *TL_IS_130 = NULL;
text_stream *TL_IS_131 = NULL;
text_stream *TL_IS_132 = NULL;
text_stream *TL_IS_133 = NULL;
text_stream *TL_IS_134 = NULL;
text_stream *TL_IS_135 = NULL;
text_stream *TL_IS_136 = NULL;
text_stream *TL_IS_137 = NULL;
text_stream *TL_IS_138 = NULL;
text_stream *TL_IS_139 = NULL;
text_stream *TL_IS_140 = NULL;
text_stream *TL_IS_141 = NULL;
text_stream *TL_IS_142 = NULL;
text_stream *TL_IS_143 = NULL;
text_stream *TL_IS_144 = NULL;
text_stream *TL_IS_145 = NULL;
text_stream *TL_IS_146 = NULL;
text_stream *TL_IS_147 = NULL;
text_stream *TL_IS_148 = NULL;
text_stream *TL_IS_149 = NULL;
text_stream *TL_IS_150 = NULL;
text_stream *TL_IS_151 = NULL;
text_stream *TL_IS_152 = NULL;
text_stream *TL_IS_153 = NULL;
text_stream *TL_IS_154 = NULL;
text_stream *TL_IS_155 = NULL;
text_stream *TL_IS_156 = NULL;
text_stream *TL_IS_157 = NULL;
text_stream *TL_IS_158 = NULL;
text_stream *TL_IS_159 = NULL;
text_stream *TL_IS_160 = NULL;
text_stream *TL_IS_161 = NULL;
text_stream *TL_IS_162 = NULL;
text_stream *TL_IS_163 = NULL;
text_stream *TL_IS_164 = NULL;
text_stream *TL_IS_165 = NULL;
text_stream *TL_IS_166 = NULL;
text_stream *TL_IS_167 = NULL;
text_stream *TL_IS_168 = NULL;
text_stream *TL_IS_169 = NULL;
text_stream *TL_IS_170 = NULL;
text_stream *TL_IS_171 = NULL;
text_stream *TL_IS_172 = NULL;
text_stream *TL_IS_173 = NULL;
text_stream *TL_IS_174 = NULL;
text_stream *TL_IS_175 = NULL;
text_stream *TL_IS_176 = NULL;
text_stream *TL_IS_177 = NULL;
text_stream *TL_IS_178 = NULL;
text_stream *TL_IS_179 = NULL;
text_stream *TL_IS_180 = NULL;
text_stream *TL_IS_181 = NULL;
text_stream *TL_IS_182 = NULL;
text_stream *TL_IS_183 = NULL;
text_stream *TL_IS_184 = NULL;
text_stream *TL_IS_185 = NULL;
text_stream *TL_IS_186 = NULL;
text_stream *TL_IS_187 = NULL;
text_stream *TL_IS_188 = NULL;
text_stream *TL_IS_189 = NULL;
text_stream *TL_IS_190 = NULL;
text_stream *TL_IS_191 = NULL;
text_stream *TL_IS_192 = NULL;
text_stream *TL_IS_193 = NULL;
text_stream *TL_IS_194 = NULL;
text_stream *TL_IS_195 = NULL;
text_stream *TL_IS_196 = NULL;
text_stream *TL_IS_197 = NULL;
text_stream *TL_IS_198 = NULL;
text_stream *TL_IS_199 = NULL;
text_stream *TL_IS_200 = NULL;
text_stream *TL_IS_201 = NULL;
text_stream *TL_IS_202 = NULL;
text_stream *TL_IS_203 = NULL;
text_stream *TL_IS_204 = NULL;
text_stream *TL_IS_205 = NULL;
text_stream *TL_IS_206 = NULL;
text_stream *TL_IS_207 = NULL;
text_stream *TL_IS_208 = NULL;
text_stream *TL_IS_209 = NULL;
text_stream *TL_IS_210 = NULL;
text_stream *TL_IS_211 = NULL;
text_stream *TL_IS_212 = NULL;
text_stream *TL_IS_213 = NULL;
text_stream *TL_IS_214 = NULL;
text_stream *TL_IS_215 = NULL;
text_stream *TL_IS_216 = NULL;
text_stream *TL_IS_217 = NULL;
text_stream *TL_IS_218 = NULL;
text_stream *TL_IS_219 = NULL;
text_stream *TL_IS_220 = NULL;
text_stream *TL_IS_221 = NULL;
text_stream *TL_IS_222 = NULL;
text_stream *TL_IS_223 = NULL;
text_stream *TL_IS_224 = NULL;
text_stream *TL_IS_225 = NULL;
text_stream *TL_IS_226 = NULL;
text_stream *TL_IS_227 = NULL;
text_stream *TL_IS_228 = NULL;
text_stream *TL_IS_229 = NULL;
text_stream *TL_IS_230 = NULL;
text_stream *TL_IS_231 = NULL;
text_stream *TL_IS_232 = NULL;
text_stream *TL_IS_233 = NULL;
text_stream *TL_IS_234 = NULL;
text_stream *TL_IS_235 = NULL;
text_stream *TL_IS_236 = NULL;
text_stream *TL_IS_237 = NULL;
text_stream *TL_IS_238 = NULL;
text_stream *TL_IS_239 = NULL;
text_stream *TL_IS_240 = NULL;
text_stream *TL_IS_241 = NULL;
text_stream *TL_IS_242 = NULL;
text_stream *TL_IS_243 = NULL;
text_stream *TL_IS_244 = NULL;
text_stream *TL_IS_245 = NULL;
text_stream *TL_IS_246 = NULL;
text_stream *TL_IS_247 = NULL;
text_stream *TL_IS_248 = NULL;
text_stream *TL_IS_249 = NULL;
text_stream *TL_IS_250 = NULL;
text_stream *TL_IS_251 = NULL;
text_stream *TL_IS_252 = NULL;
text_stream *TL_IS_253 = NULL;
text_stream *TL_IS_254 = NULL;
text_stream *TL_IS_255 = NULL;
text_stream *TL_IS_256 = NULL;
text_stream *TL_IS_257 = NULL;
text_stream *TL_IS_258 = NULL;
text_stream *TL_IS_259 = NULL;
text_stream *TL_IS_260 = NULL;
text_stream *TL_IS_261 = NULL;
text_stream *TL_IS_262 = NULL;
text_stream *TL_IS_263 = NULL;
text_stream *TL_IS_264 = NULL;
text_stream *TL_IS_265 = NULL;
text_stream *TL_IS_266 = NULL;
text_stream *TL_IS_267 = NULL;
text_stream *TL_IS_268 = NULL;
text_stream *TL_IS_269 = NULL;
text_stream *TL_IS_270 = NULL;
text_stream *TL_IS_271 = NULL;
text_stream *TL_IS_272 = NULL;
text_stream *TL_IS_273 = NULL;
text_stream *TL_IS_274 = NULL;
text_stream *TL_IS_275 = NULL;
text_stream *TL_IS_276 = NULL;
text_stream *TL_IS_277 = NULL;
text_stream *TL_IS_278 = NULL;
text_stream *TL_IS_279 = NULL;
text_stream *TL_IS_280 = NULL;
text_stream *TL_IS_281 = NULL;
text_stream *TL_IS_282 = NULL;
text_stream *TL_IS_283 = NULL;
text_stream *TL_IS_284 = NULL;
text_stream *TL_IS_285 = NULL;
text_stream *TL_IS_286 = NULL;
text_stream *TL_IS_287 = NULL;
text_stream *TL_IS_288 = NULL;
text_stream *TL_IS_289 = NULL;
text_stream *TL_IS_290 = NULL;
text_stream *TL_IS_291 = NULL;
text_stream *TL_IS_292 = NULL;
text_stream *TL_IS_293 = NULL;
text_stream *TL_IS_294 = NULL;
text_stream *TL_IS_295 = NULL;
text_stream *TL_IS_296 = NULL;
text_stream *TL_IS_297 = NULL;
text_stream *TL_IS_298 = NULL;
text_stream *TL_IS_299 = NULL;
text_stream *TL_IS_300 = NULL;
text_stream *TL_IS_301 = NULL;
text_stream *TL_IS_302 = NULL;
text_stream *TL_IS_303 = NULL;
text_stream *TL_IS_304 = NULL;
text_stream *TL_IS_305 = NULL;
text_stream *TL_IS_306 = NULL;
text_stream *TL_IS_307 = NULL;
text_stream *TL_IS_308 = NULL;
text_stream *TL_IS_309 = NULL;
text_stream *TL_IS_310 = NULL;
text_stream *TL_IS_311 = NULL;
text_stream *TL_IS_312 = NULL;
text_stream *TL_IS_313 = NULL;
text_stream *TL_IS_314 = NULL;
text_stream *TL_IS_315 = NULL;
text_stream *TL_IS_316 = NULL;
text_stream *TL_IS_317 = NULL;
text_stream *TL_IS_318 = NULL;
text_stream *TL_IS_319 = NULL;
text_stream *TL_IS_320 = NULL;
text_stream *TL_IS_321 = NULL;
text_stream *TL_IS_322 = NULL;
text_stream *TL_IS_323 = NULL;
text_stream *TL_IS_324 = NULL;
text_stream *TL_IS_325 = NULL;
text_stream *TL_IS_326 = NULL;
text_stream *TL_IS_327 = NULL;
text_stream *TL_IS_328 = NULL;
text_stream *TL_IS_329 = NULL;
text_stream *TL_IS_330 = NULL;
text_stream *TL_IS_331 = NULL;
text_stream *TL_IS_332 = NULL;
text_stream *TL_IS_333 = NULL;
text_stream *TL_IS_334 = NULL;
text_stream *TL_IS_335 = NULL;
text_stream *TL_IS_336 = NULL;
text_stream *TL_IS_337 = NULL;
text_stream *TL_IS_338 = NULL;
text_stream *TL_IS_339 = NULL;
text_stream *TL_IS_340 = NULL;
text_stream *TL_IS_341 = NULL;
text_stream *TL_IS_342 = NULL;
text_stream *TL_IS_343 = NULL;
text_stream *TL_IS_344 = NULL;
text_stream *TL_IS_345 = NULL;
text_stream *TL_IS_346 = NULL;
text_stream *TL_IS_347 = NULL;
text_stream *TL_IS_348 = NULL;
text_stream *TL_IS_349 = NULL;
text_stream *TL_IS_350 = NULL;
text_stream *TL_IS_351 = NULL;
text_stream *TL_IS_352 = NULL;
text_stream *TL_IS_353 = NULL;
text_stream *TL_IS_354 = NULL;
text_stream *TL_IS_355 = NULL;
text_stream *TL_IS_356 = NULL;
text_stream *TL_IS_357 = NULL;
text_stream *TL_IS_358 = NULL;
text_stream *TL_IS_359 = NULL;
text_stream *TL_IS_360 = NULL;
text_stream *TL_IS_361 = NULL;
text_stream *TL_IS_362 = NULL;
text_stream *TL_IS_363 = NULL;
text_stream *TL_IS_364 = NULL;
text_stream *TL_IS_365 = NULL;
text_stream *TL_IS_366 = NULL;
text_stream *TL_IS_367 = NULL;
text_stream *TL_IS_368 = NULL;
text_stream *TL_IS_369 = NULL;
text_stream *TL_IS_370 = NULL;
text_stream *TL_IS_371 = NULL;
text_stream *TL_IS_372 = NULL;
text_stream *TL_IS_373 = NULL;
text_stream *TL_IS_374 = NULL;
text_stream *TL_IS_375 = NULL;
text_stream *TL_IS_376 = NULL;
text_stream *TL_IS_377 = NULL;
text_stream *TL_IS_378 = NULL;
text_stream *TL_IS_379 = NULL;
text_stream *TL_IS_380 = NULL;
text_stream *TL_IS_381 = NULL;
text_stream *TL_IS_382 = NULL;
text_stream *TL_IS_383 = NULL;
text_stream *TL_IS_384 = NULL;
text_stream *TL_IS_385 = NULL;
text_stream *TL_IS_386 = NULL;
text_stream *TL_IS_387 = NULL;
text_stream *TL_IS_388 = NULL;
text_stream *TL_IS_389 = NULL;
text_stream *TL_IS_390 = NULL;
text_stream *TL_IS_391 = NULL;
text_stream *TL_IS_392 = NULL;
text_stream *TL_IS_393 = NULL;
text_stream *TL_IS_394 = NULL;
text_stream *TL_IS_395 = NULL;
text_stream *TL_IS_396 = NULL;
text_stream *TL_IS_397 = NULL;
text_stream *TL_IS_398 = NULL;
text_stream *TL_IS_399 = NULL;
text_stream *TL_IS_400 = NULL;
text_stream *TL_IS_401 = NULL;
text_stream *TL_IS_402 = NULL;
text_stream *TL_IS_403 = NULL;
text_stream *TL_IS_404 = NULL;
text_stream *TL_IS_405 = NULL;
text_stream *TL_IS_406 = NULL;
text_stream *TL_IS_407 = NULL;
text_stream *TL_IS_408 = NULL;
text_stream *TL_IS_409 = NULL;
text_stream *TL_IS_410 = NULL;
text_stream *TL_IS_411 = NULL;
text_stream *TL_IS_412 = NULL;
text_stream *TL_IS_413 = NULL;
text_stream *TL_IS_414 = NULL;
text_stream *TL_IS_415 = NULL;
text_stream *TL_IS_416 = NULL;
text_stream *TL_IS_417 = NULL;
text_stream *TL_IS_418 = NULL;
text_stream *TL_IS_419 = NULL;
text_stream *TL_IS_420 = NULL;
text_stream *TL_IS_421 = NULL;
text_stream *TL_IS_422 = NULL;
text_stream *TL_IS_423 = NULL;
text_stream *TL_IS_424 = NULL;
text_stream *TL_IS_425 = NULL;
text_stream *TL_IS_426 = NULL;
text_stream *TL_IS_427 = NULL;
text_stream *TL_IS_428 = NULL;
text_stream *TL_IS_429 = NULL;
text_stream *TL_IS_430 = NULL;
text_stream *TL_IS_431 = NULL;
text_stream *TL_IS_432 = NULL;
text_stream *TL_IS_433 = NULL;
text_stream *TL_IS_434 = NULL;
text_stream *TL_IS_435 = NULL;
text_stream *TL_IS_436 = NULL;
text_stream *TL_IS_437 = NULL;
text_stream *TL_IS_438 = NULL;
text_stream *TL_IS_439 = NULL;
text_stream *TL_IS_440 = NULL;
text_stream *TL_IS_441 = NULL;
text_stream *TL_IS_442 = NULL;
text_stream *TL_IS_443 = NULL;
text_stream *TL_IS_444 = NULL;
text_stream *TL_IS_445 = NULL;
text_stream *TL_IS_446 = NULL;
text_stream *TL_IS_447 = NULL;
text_stream *TL_IS_448 = NULL;
text_stream *TL_IS_449 = NULL;
text_stream *TL_IS_450 = NULL;
text_stream *TL_IS_451 = NULL;
text_stream *TL_IS_452 = NULL;
text_stream *TL_IS_453 = NULL;
text_stream *TL_IS_454 = NULL;
text_stream *TL_IS_455 = NULL;
text_stream *TL_IS_456 = NULL;
text_stream *TL_IS_457 = NULL;
text_stream *TL_IS_458 = NULL;
text_stream *TL_IS_459 = NULL;
text_stream *TL_IS_460 = NULL;
text_stream *TL_IS_461 = NULL;
text_stream *TL_IS_462 = NULL;
text_stream *TL_IS_463 = NULL;
text_stream *TL_IS_464 = NULL;
text_stream *TL_IS_465 = NULL;
text_stream *TL_IS_466 = NULL;
text_stream *TL_IS_467 = NULL;
text_stream *TL_IS_468 = NULL;
text_stream *TL_IS_469 = NULL;
text_stream *TL_IS_470 = NULL;
text_stream *TL_IS_471 = NULL;
text_stream *TL_IS_472 = NULL;
text_stream *TL_IS_473 = NULL;
text_stream *TL_IS_474 = NULL;
text_stream *TL_IS_475 = NULL;
text_stream *TL_IS_476 = NULL;
text_stream *TL_IS_477 = NULL;
text_stream *TL_IS_478 = NULL;
text_stream *TL_IS_479 = NULL;
text_stream *TL_IS_480 = NULL;
text_stream *TL_IS_481 = NULL;
text_stream *TL_IS_482 = NULL;
text_stream *TL_IS_483 = NULL;
text_stream *TL_IS_484 = NULL;
text_stream *TL_IS_485 = NULL;
text_stream *TL_IS_486 = NULL;
text_stream *TL_IS_487 = NULL;
text_stream *TL_IS_488 = NULL;
text_stream *TL_IS_489 = NULL;
text_stream *TL_IS_490 = NULL;
text_stream *TL_IS_491 = NULL;
text_stream *TL_IS_492 = NULL;
text_stream *TL_IS_493 = NULL;
text_stream *TL_IS_494 = NULL;
text_stream *TL_IS_495 = NULL;
text_stream *TL_IS_496 = NULL;
text_stream *TL_IS_497 = NULL;
text_stream *TL_IS_498 = NULL;
text_stream *TL_IS_499 = NULL;
text_stream *TL_IS_500 = NULL;
text_stream *TL_IS_501 = NULL;
text_stream *TL_IS_502 = NULL;
text_stream *TL_IS_503 = NULL;
text_stream *TL_IS_504 = NULL;
text_stream *TL_IS_505 = NULL;
text_stream *TL_IS_506 = NULL;
text_stream *TL_IS_507 = NULL;
text_stream *TL_IS_508 = NULL;
text_stream *TL_IS_509 = NULL;
text_stream *TL_IS_510 = NULL;
text_stream *TL_IS_511 = NULL;
text_stream *TL_IS_512 = NULL;
text_stream *TL_IS_513 = NULL;
text_stream *TL_IS_514 = NULL;
text_stream *TL_IS_515 = NULL;
text_stream *TL_IS_516 = NULL;
text_stream *TL_IS_517 = NULL;
text_stream *TL_IS_518 = NULL;
text_stream *TL_IS_519 = NULL;
text_stream *TL_IS_520 = NULL;
text_stream *TL_IS_521 = NULL;
text_stream *TL_IS_522 = NULL;
text_stream *TL_IS_523 = NULL;
text_stream *TL_IS_524 = NULL;
text_stream *TL_IS_525 = NULL;
text_stream *TL_IS_526 = NULL;
text_stream *TL_IS_527 = NULL;
text_stream *TL_IS_528 = NULL;
text_stream *TL_IS_529 = NULL;
text_stream *TL_IS_530 = NULL;
text_stream *TL_IS_531 = NULL;
text_stream *TL_IS_532 = NULL;
text_stream *TL_IS_533 = NULL;
text_stream *TL_IS_534 = NULL;
text_stream *TL_IS_535 = NULL;
text_stream *TL_IS_536 = NULL;
text_stream *TL_IS_537 = NULL;
text_stream *TL_IS_538 = NULL;
text_stream *TL_IS_539 = NULL;
text_stream *TL_IS_540 = NULL;
text_stream *TL_IS_541 = NULL;
text_stream *TL_IS_542 = NULL;
text_stream *TL_IS_543 = NULL;
text_stream *TL_IS_544 = NULL;
text_stream *TL_IS_545 = NULL;
text_stream *TL_IS_546 = NULL;
text_stream *TL_IS_547 = NULL;
text_stream *TL_IS_548 = NULL;
text_stream *TL_IS_549 = NULL;
text_stream *TL_IS_550 = NULL;
text_stream *TL_IS_551 = NULL;
text_stream *TL_IS_552 = NULL;
text_stream *TL_IS_553 = NULL;
text_stream *TL_IS_554 = NULL;
text_stream *TL_IS_555 = NULL;
text_stream *TL_IS_556 = NULL;
text_stream *TL_IS_557 = NULL;
text_stream *TL_IS_558 = NULL;
text_stream *TL_IS_559 = NULL;
text_stream *TL_IS_560 = NULL;
text_stream *TL_IS_561 = NULL;
text_stream *TL_IS_562 = NULL;
text_stream *TL_IS_563 = NULL;
text_stream *TL_IS_564 = NULL;
text_stream *TL_IS_565 = NULL;
text_stream *TL_IS_566 = NULL;
text_stream *TL_IS_567 = NULL;
text_stream *TL_IS_568 = NULL;
text_stream *TL_IS_569 = NULL;
text_stream *TL_IS_570 = NULL;
text_stream *TL_IS_571 = NULL;
text_stream *TL_IS_572 = NULL;
text_stream *TL_IS_573 = NULL;
text_stream *TL_IS_574 = NULL;
text_stream *TL_IS_575 = NULL;
text_stream *TL_IS_576 = NULL;
text_stream *TL_IS_577 = NULL;
text_stream *TL_IS_578 = NULL;
text_stream *TL_IS_579 = NULL;
text_stream *TL_IS_580 = NULL;
text_stream *TL_IS_581 = NULL;
text_stream *TL_IS_582 = NULL;
text_stream *TL_IS_583 = NULL;
text_stream *TL_IS_584 = NULL;
text_stream *TL_IS_585 = NULL;
text_stream *TL_IS_586 = NULL;
text_stream *TL_IS_587 = NULL;
text_stream *TL_IS_588 = NULL;
text_stream *TL_IS_589 = NULL;
text_stream *TL_IS_590 = NULL;
text_stream *TL_IS_591 = NULL;
text_stream *TL_IS_592 = NULL;
text_stream *TL_IS_593 = NULL;
text_stream *TL_IS_594 = NULL;
text_stream *TL_IS_595 = NULL;
text_stream *TL_IS_596 = NULL;
text_stream *TL_IS_597 = NULL;
text_stream *TL_IS_598 = NULL;
text_stream *TL_IS_599 = NULL;
text_stream *TL_IS_600 = NULL;
text_stream *TL_IS_601 = NULL;
text_stream *TL_IS_602 = NULL;
text_stream *TL_IS_603 = NULL;
text_stream *TL_IS_604 = NULL;
text_stream *TL_IS_605 = NULL;
text_stream *TL_IS_606 = NULL;
text_stream *TL_IS_607 = NULL;
text_stream *TL_IS_608 = NULL;
text_stream *TL_IS_609 = NULL;
text_stream *TL_IS_610 = NULL;
text_stream *TL_IS_611 = NULL;
text_stream *TL_IS_612 = NULL;
text_stream *TL_IS_613 = NULL;
text_stream *TL_IS_614 = NULL;
text_stream *TL_IS_615 = NULL;
text_stream *TL_IS_616 = NULL;
text_stream *TL_IS_617 = NULL;
text_stream *TL_IS_618 = NULL;
text_stream *TL_IS_619 = NULL;
text_stream *TL_IS_620 = NULL;
text_stream *TL_IS_621 = NULL;
text_stream *TL_IS_622 = NULL;
text_stream *TL_IS_623 = NULL;
text_stream *TL_IS_624 = NULL;
text_stream *TL_IS_625 = NULL;
text_stream *TL_IS_626 = NULL;
text_stream *TL_IS_627 = NULL;
text_stream *TL_IS_628 = NULL;
text_stream *TL_IS_629 = NULL;
text_stream *TL_IS_630 = NULL;
text_stream *TL_IS_631 = NULL;
text_stream *TL_IS_632 = NULL;
text_stream *TL_IS_633 = NULL;
text_stream *TL_IS_634 = NULL;
text_stream *TL_IS_635 = NULL;
text_stream *TL_IS_636 = NULL;
text_stream *TL_IS_637 = NULL;
text_stream *TL_IS_638 = NULL;
text_stream *TL_IS_639 = NULL;
text_stream *TL_IS_640 = NULL;
text_stream *TL_IS_641 = NULL;
text_stream *TL_IS_642 = NULL;
text_stream *TL_IS_643 = NULL;
text_stream *TL_IS_644 = NULL;
text_stream *TL_IS_645 = NULL;
text_stream *TL_IS_646 = NULL;
text_stream *TL_IS_647 = NULL;
text_stream *TL_IS_648 = NULL;
text_stream *TL_IS_649 = NULL;
text_stream *TL_IS_650 = NULL;
text_stream *TL_IS_651 = NULL;
text_stream *TL_IS_652 = NULL;
text_stream *TL_IS_653 = NULL;
text_stream *TL_IS_654 = NULL;
text_stream *TL_IS_655 = NULL;
text_stream *TL_IS_656 = NULL;
text_stream *TL_IS_657 = NULL;
text_stream *TL_IS_658 = NULL;
text_stream *TL_IS_659 = NULL;
text_stream *TL_IS_660 = NULL;
text_stream *TL_IS_661 = NULL;
text_stream *TL_IS_662 = NULL;
text_stream *TL_IS_663 = NULL;
text_stream *TL_IS_664 = NULL;
text_stream *TL_IS_665 = NULL;
text_stream *TL_IS_666 = NULL;
text_stream *TL_IS_667 = NULL;
text_stream *TL_IS_668 = NULL;
text_stream *TL_IS_669 = NULL;
text_stream *TL_IS_670 = NULL;
text_stream *TL_IS_671 = NULL;
text_stream *TL_IS_672 = NULL;
text_stream *TL_IS_673 = NULL;
text_stream *TL_IS_674 = NULL;
text_stream *TL_IS_675 = NULL;
text_stream *TL_IS_676 = NULL;
text_stream *TL_IS_677 = NULL;
text_stream *TL_IS_678 = NULL;
text_stream *TL_IS_679 = NULL;
text_stream *TL_IS_680 = NULL;
text_stream *TL_IS_681 = NULL;
text_stream *TL_IS_682 = NULL;
text_stream *TL_IS_683 = NULL;
text_stream *TL_IS_684 = NULL;
text_stream *TL_IS_685 = NULL;
text_stream *TL_IS_686 = NULL;
text_stream *TL_IS_687 = NULL;
text_stream *TL_IS_688 = NULL;
text_stream *TL_IS_689 = NULL;
text_stream *TL_IS_690 = NULL;
text_stream *TL_IS_691 = NULL;
text_stream *TL_IS_692 = NULL;
text_stream *TL_IS_693 = NULL;
text_stream *TL_IS_694 = NULL;
text_stream *TL_IS_695 = NULL;
text_stream *TL_IS_696 = NULL;
text_stream *TL_IS_697 = NULL;
text_stream *TL_IS_698 = NULL;
text_stream *TL_IS_699 = NULL;
text_stream *TL_IS_700 = NULL;
text_stream *TL_IS_701 = NULL;
text_stream *TL_IS_702 = NULL;
text_stream *TL_IS_703 = NULL;
text_stream *TL_IS_704 = NULL;
text_stream *TL_IS_705 = NULL;
text_stream *TL_IS_706 = NULL;
text_stream *TL_IS_707 = NULL;
text_stream *TL_IS_708 = NULL;
text_stream *TL_IS_709 = NULL;
text_stream *TL_IS_710 = NULL;
text_stream *TL_IS_711 = NULL;
text_stream *TL_IS_712 = NULL;
text_stream *TL_IS_713 = NULL;
text_stream *TL_IS_714 = NULL;
text_stream *TL_IS_715 = NULL;
text_stream *TL_IS_716 = NULL;
text_stream *TL_IS_717 = NULL;
text_stream *TL_IS_718 = NULL;
text_stream *TL_IS_719 = NULL;
text_stream *TL_IS_720 = NULL;
text_stream *TL_IS_721 = NULL;
text_stream *TL_IS_722 = NULL;
text_stream *TL_IS_723 = NULL;
void register_tangled_text_literals(void);
#line 57 "inweb/foundation-module/Chapter 2/Streams.w"
#define WRITE(args...) Writers__printf(OUT, args)
#define PRINT(args...) Writers__printf(STDOUT, args)
#define WRITE_TO(stream, args...) Writers__printf(stream, args)
#define LOG(args...) Writers__printf(DL, args)
#define LOGIF(aspect, args...) { \
if (Log__aspect_switched_on(aspect##_DA)) Writers__printf(DL, args); \
}
#line 51 "inweb/foundation-module/Chapter 1/Foundation Module.w"
text_stream *DL = NULL; /* Current destination of debugging text: kept |NULL| until opened */
#line 80 "inweb/foundation-module/Chapter 1/Foundation Module.w"
#line 90 "inweb/foundation-module/Chapter 1/Foundation Module.w"
void Foundation__start(int argc, char **argv) {
CommandLine__set_locale(argc, argv);
Platform__configure_terminal();
Memory__start();
{
#line 109 "inweb/foundation-module/Chapter 1/Foundation Module.w"
Writers__register_writer('f', &Filenames__writer);
Writers__register_writer('p', &Pathnames__writer);
Writers__register_writer('v', &VersionNumbers__writer);
Writers__register_writer('S', &Streams__writer);
}
#line 94 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
register_tangled_text_literals();
;
Time__begin();
Pathnames__start();
{
#line 120 "inweb/foundation-module/Chapter 1/Foundation Module.w"
Log__declare_aspect(DEBUGGING_LOG_INCLUSIONS_DA, L"debugging log inclusions", FALSE, FALSE);
Log__declare_aspect(SHELL_USAGE_DA, L"shell usage", FALSE, FALSE);
Log__declare_aspect(MEMORY_USAGE_DA, L"memory usage", FALSE, FALSE);
Log__declare_aspect(TEXT_FILES_DA, L"text files", FALSE, FALSE);
}
#line 98 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
{
#line 131 "inweb/foundation-module/Chapter 1/Foundation Module.w"
Writers__register_logger('a', &Tries__log_avinue);
Writers__register_logger('S', &Streams__log);
}
#line 99 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
{
#line 151 "inweb/foundation-module/Chapter 1/Foundation Module.w"
CommandLine__begin_group(FOUNDATION_CLSG, NULL);
CommandLine__declare_switch(LOG_CLSW, L"log", 2,
L"write the debugging log to include diagnostics on X");
CommandLine__declare_switch(VERSION_CLSW, L"version", 1,
L"print out version number");
CommandLine__declare_boolean_switch(CRASH_CLSW, L"crash", 1,
L"intentionally crash on internal errors, for backtracing", FALSE);
CommandLine__declare_switch(HELP_CLSW, L"help", 1,
L"print this help information");
CommandLine__declare_boolean_switch(FIXTIME_CLSW, L"fixtime", 1,
L"pretend the time is 11 a.m. on 28 March 2016 for testing", FALSE);
CommandLine__declare_switch(AT_CLSW, L"at", 2,
L"specify that this tool is installed at X");
CommandLine__declare_switch(LOCALE_CLSW, L"locale", 2,
L"set locales as 'L=E', L being shell or console, E platform, utf-8 or iso-latin1");
CommandLine__end_group();
}
#line 100 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
}
#line 149 "inweb/foundation-module/Chapter 1/Foundation Module.w"
#line 174 "inweb/foundation-module/Chapter 1/Foundation Module.w"
void Foundation__end(void) {
if (Log__aspect_switched_on(MEMORY_USAGE_DA)) Memory__log_statistics();
Log__close();
Memory__free();
}
#ifdef PLATFORM_POSIX
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 81 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__is_folder_separator(wchar_t c) {
return (c == FOLDER_SEPARATOR);
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 93 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#ifndef LOCALE_IS_ISO
#ifndef LOCALE_IS_UTF8
#define LOCALE_IS_UTF8 1
#endif
#endif
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 102 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
char *Platform__getenv(const char *name) {
return getenv(name);
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#line 115 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__where_am_i(wchar_t *p, size_t length) {
char buffer[PATH_MAX + 1];
{
#ifdef PLATFORM_POSIX
#line 127 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
ssize_t link_len = readlink("/proc/self/exe", buffer, PATH_MAX);
if (link_len < 0)
{
#ifdef PLATFORM_POSIX
#line 180 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
p[0] = '\0';
return;
#endif /* PLATFORM_POSIX */
}
#line 128 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
; // unable to find
buffer[link_len] = '\0';
#endif /* PLATFORM_POSIX */
}
#line 117 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
;
{
#ifdef PLATFORM_POSIX
#line 136 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
size_t convert_len = mbstowcs(p, buffer, length);
if (convert_len == (size_t)-1)
{
#ifdef PLATFORM_POSIX
#line 180 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
p[0] = '\0';
return;
#endif /* PLATFORM_POSIX */
}
#line 137 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
; // wouldn't fit
#endif /* PLATFORM_POSIX */
}
#line 118 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
;
}
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_UNIX
#ifdef PLATFORM_POSIX
#line 166 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__where_am_i(wchar_t *p, size_t length) {
{
#ifdef PLATFORM_POSIX
#line 180 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
p[0] = '\0';
return;
#endif /* PLATFORM_POSIX */
}
#line 167 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
;
}
#endif /* PLATFORM_UNIX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#line 173 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__where_am_i(wchar_t *p, size_t length) {
{
#ifdef PLATFORM_POSIX
#line 180 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
p[0] = '\0';
return;
#endif /* PLATFORM_POSIX */
}
#line 174 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
;
}
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifndef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 186 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__system(const char *cmd) {
return system(cmd);
}
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 211 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <spawn.h>
#include <sys/wait.h>
extern char **environ;
int Platform__system(const char *cmd) {
char *argv[] = {"sh", "-c", (char *) cmd, NULL};
pid_t pid;
int status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
if (status == 0) {
if (waitpid(pid, &status, 0) != -1) return status;
internal_error("waitpid failed");
} else {
WRITE_TO(STDERR, "posix_spawn: %s\n", strerror(status));
internal_error("posix_spawn failed");
}
return -1;
}
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 233 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__mkdir(char *transcoded_pathname) {
errno = 0;
int rv = mkdir(transcoded_pathname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (rv == 0) return TRUE;
if (errno == EEXIST) return TRUE;
return FALSE;
}
void *Platform__opendir(char *dir_name) {
DIR *dirp = opendir(dir_name);
return (void *) dirp;
}
int Platform__readdir(void *D, char *dir_name, char *leafname) {
char path_to[2*MAX_FILENAME_LENGTH+2];
struct stat file_status;
int rv;
DIR *dirp = (DIR *) D;
struct dirent *dp;
if ((dp = readdir(dirp)) == NULL) return FALSE;
sprintf(path_to, "%s%c%s", dir_name, FOLDER_SEPARATOR, dp->d_name);
rv = stat(path_to, &file_status);
if (rv != 0) return FALSE;
if (S_ISDIR(file_status.st_mode)) sprintf(leafname, "%s/", dp->d_name);
else strcpy(leafname, dp->d_name);
return TRUE;
}
void Platform__closedir(void *D) {
DIR *dirp = (DIR *) D;
closedir(dirp);
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 274 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
time_t Platform__never_time(void) {
return (time_t) 0;
}
time_t Platform__timestamp(char *transcoded_filename) {
struct stat filestat;
if (stat(transcoded_filename, &filestat) != -1) return filestat.st_mtime;
return Platform__never_time();
}
off_t Platform__size(char *transcoded_filename) {
struct stat filestat;
if (stat(transcoded_filename, &filestat) != -1) return filestat.st_size;
return (off_t) 0;
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 298 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__rsync(char *transcoded_source, char *transcoded_dest) {
char rsync_command[10*MAX_FILENAME_LENGTH];
sprintf(rsync_command, "rsync -a --delete ");
Platform__quote_text(rsync_command + strlen(rsync_command), transcoded_source, TRUE);
sprintf(rsync_command + strlen(rsync_command), " ");
Platform__quote_text(rsync_command + strlen(rsync_command), transcoded_dest, FALSE);
Platform__system(rsync_command);
}
void Platform__quote_text(char *quoted, char *raw, int terminate) {
quoted[0] = SHELL_QUOTE_CHARACTER;
int qp = 1;
for (int rp = 0; raw[rp]; rp++) {
char c = raw[rp];
if (c == SHELL_QUOTE_CHARACTER) quoted[qp++] = '\\';
quoted[qp++] = c;
}
if (terminate) quoted[qp++] = FOLDER_SEPARATOR;
quoted[qp++] = SHELL_QUOTE_CHARACTER;
quoted[qp++] = 0;
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 323 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__sleep(int seconds) {
sleep((unsigned int) seconds);
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 339 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__notification(text_stream *text, int happy) {
char *sound_name = "Bell.aiff";
if (happy == FALSE) sound_name = "Submarine.aiff";
TEMPORARY_TEXT(TEMP)
WRITE_TO(TEMP, "osascript -e 'display notification \"%S\" "
"sound name \"%s\" with title \"intest Results\"'", text, sound_name);
Shell__run(TEMP);
DISCARD_TEXT(TEMP)
}
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifndef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 352 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__notification(text_stream *text, int happy) {
}
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 365 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
void Platform__configure_terminal(void) {
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 377 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__create_thread(foundation_thread *pt,
const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) {
return pthread_create(pt, pa, fn, arg);
}
int Platform__join_thread(foundation_thread pt, void** rv) {
return pthread_join(pt, rv);
}
void Platform__init_thread(foundation_thread_attributes *pa, size_t size) {
if (pthread_attr_init(pa) != 0) internal_error("thread initialisation failed");
if (pthread_attr_setstacksize(pa, size) != 0) internal_error("thread stack sizing failed");
}
size_t Platform__get_thread_stack_size(foundation_thread_attributes *pa) {
size_t mystacksize;
pthread_attr_getstacksize(pa, &mystacksize);
return mystacksize;
}
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#line 412 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__get_core_count(void) {
int N = get_nprocs();
if (N < 1) return 1;
return N;
}
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 426 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__get_core_count(void) {
int N;
size_t N_size = sizeof(int);
sysctlbyname("hw.logicalcpu", &N, &N_size, NULL, 0);
if (N < 1) return 1;
return N;
}
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#line 438 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
int Platform__get_core_count(void) {
return 1;
}
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_WINDOWS
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 48 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__Windows_isdigit(int c) {
return ((c >= '0') && (c <= '9')) ? 1 : 0;
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 60 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__is_folder_separator(wchar_t c) {
return ((c == '\\') || (c == '/'));
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 92 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__where_am_i(wchar_t *p, size_t length) {
DWORD result = GetModuleFileNameW(NULL, p, (DWORD)length);
if ((result == 0) || (result == length)) p[0] = 0;
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 189 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__mkdir(char *transcoded_pathname) {
errno = 0;
int rv = mkdir(transcoded_pathname);
if (rv == 0) return TRUE;
if (errno == EEXIST) return TRUE;
return FALSE;
}
void *Platform__opendir(char *dir_name) {
DIR *dirp = opendir(dir_name);
return (void *) dirp;
}
int Platform__readdir(void *D, char *dir_name,
char *leafname) {
char path_to[2*MAX_FILENAME_LENGTH+2];
struct _stat file_status;
int rv;
DIR *dirp = (DIR *) D;
struct dirent *dp;
if ((dp = readdir(dirp)) == NULL) return FALSE;
sprintf(path_to, "%s%c%s", dir_name, FOLDER_SEPARATOR, dp->d_name);
rv = _stat(path_to, &file_status);
if (rv != 0) return FALSE;
if (S_ISDIR(file_status.st_mode))
sprintf(leafname, "%s%c", dp->d_name, FOLDER_SEPARATOR);
else strcpy(leafname, dp->d_name);
return TRUE;
}
void Platform__closedir(void *D) {
DIR *dirp = (DIR *) D;
closedir(dirp);
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 227 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__path_add(const char* base, const char* add, char* path) {
char last;
strcpy(path, base);
last = path[strlen(path) - 1];
if ((last != '/') && (last != '\\'))
strcat(path, "\\");
strcat(path, add);
}
void Platform__rsync(char *transcoded_source, char *transcoded_dest) {
char srcPath[MAX_PATH], destPath[MAX_PATH];
WIN32_FIND_DATA findData = { 0 };
SHCreateDirectoryExA(0, transcoded_dest, NULL);
Platform__path_add(transcoded_dest, "*", destPath);
HANDLE findHandle = FindFirstFileA(destPath, &findData);
if (findHandle != INVALID_HANDLE_VALUE) {
do {
if ((strcmp(findData.cFileName, ".") == 0) || (strcmp(findData.cFileName, "..") == 0))
continue;
Platform__path_add(transcoded_source, findData.cFileName, srcPath);
int remove = 1;
{
DWORD srcAttrs = GetFileAttributesA(srcPath);
if (srcAttrs != INVALID_FILE_ATTRIBUTES) {
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == (srcAttrs & FILE_ATTRIBUTE_DIRECTORY))
remove = 0;
}
}
if (remove) {
Platform__path_add(transcoded_dest, findData.cFileName, destPath);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
SHFILEOPSTRUCTA oper = { 0 };
oper.wFunc = FO_DELETE;
oper.pFrom = destPath;
oper.fFlags = FOF_NO_UI;
SHFileOperationA(&oper);
}
else DeleteFileA(destPath);
}
}
while (FindNextFileA(findHandle, &findData) != 0);
FindClose(findHandle);
}
Platform__path_add(transcoded_source, "*", srcPath);
findHandle = FindFirstFileA(srcPath, &findData);
if (findHandle != INVALID_HANDLE_VALUE) {
do {
if ((strcmp(findData.cFileName, ".") == 0) || (strcmp(findData.cFileName, "..") == 0))
continue;
Platform__path_add(transcoded_source, findData.cFileName, srcPath);
Platform__path_add(transcoded_dest, findData.cFileName, destPath);
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
CreateDirectoryA(destPath, 0);
Platform__rsync(srcPath, destPath);
} else {
int needCopy = 1;
{
WIN32_FIND_DATA destFindData = { 0 };
HANDLE destFindHandle = FindFirstFileA(destPath, &destFindData);
if (destFindHandle != INVALID_HANDLE_VALUE) {
if ((findData.nFileSizeLow == destFindData.nFileSizeLow) && (findData.nFileSizeHigh == destFindData.nFileSizeHigh)) {
if (CompareFileTime(&(findData.ftLastWriteTime), &(destFindData.ftLastWriteTime)) == 0)
needCopy = 0;
}
FindClose(destFindHandle);
}
}
if (needCopy)
CopyFileA(srcPath, destPath, 0);
}
}
while (FindNextFileA(findHandle, &findData) != 0);
FindClose(findHandle);
}
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 316 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__sleep(int seconds) {
Sleep((DWORD)(1000*seconds));
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 323 "inweb/foundation-module/Chapter 1/Windows Platform.w"
void Platform__notification(text_stream *text, int happy) {
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 334 "inweb/foundation-module/Chapter 1/Windows Platform.w"
#define WIN32CONS_RESET_MODE 1
#define WIN32CONS_RESET_OUTCP 2
int Win32_ResetConsole = 0;
DWORD Win32_ConsoleMode = 0;
UINT Win32_ConsoleOutCP = 0;
void Platform__Win32_ResetConsole(void) {
if (Win32_ResetConsole & WIN32CONS_RESET_MODE) {
HANDLE cons = GetStdHandle(STD_ERROR_HANDLE);
if (cons) SetConsoleMode(cons, Win32_ConsoleMode);
}
if (Win32_ResetConsole & WIN32CONS_RESET_OUTCP)
SetConsoleOutputCP(Win32_ConsoleOutCP);
}
void Platform__configure_terminal(void) {
HANDLE cons = GetStdHandle(STD_ERROR_HANDLE);
if (cons) {
if (GetConsoleMode(cons, &Win32_ConsoleMode)) {
if ((Win32_ConsoleMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0) {
if (SetConsoleMode(cons, Win32_ConsoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
Win32_ResetConsole |= WIN32CONS_RESET_MODE;
}
}
}
}
Win32_ConsoleOutCP = GetConsoleOutputCP();
UINT newCP = 0;
int loc = Locales__get(CONSOLE_LOCALE);
if (loc == FILE_ENCODING_ISO_STRF)
newCP = 28591; /* ISO 8859-1 Latin */
else if (loc == FILE_ENCODING_UTF8_STRF)
newCP = CP_UTF8;
if ((newCP != 0) && SetConsoleOutputCP(newCP))
Win32_ResetConsole |= WIN32CONS_RESET_OUTCP;
if (Win32_ResetConsole != 0) atexit(Platform__Win32_ResetConsole);
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 385 "inweb/foundation-module/Chapter 1/Windows Platform.w"
DWORD WINAPI Platform__Win32_Thread_Func(LPVOID param) {
struct Win32_Thread_Start* start = (struct Win32_Thread_Start*)param;
(start->fn)(start->arg);
free(start);
return 0;
}
int Platform__create_thread(foundation_thread *pt, const foundation_thread_attributes *pa,
void *(*fn)(void *), void *arg) {
struct Win32_Thread_Start* start = (struct Win32_Thread_Start*) malloc(sizeof (struct Win32_Thread_Start));
start->fn = fn;
start->arg = arg;
HANDLE thread = CreateThread(0, 0, Platform__Win32_Thread_Func, start, 0, 0);
if (thread == 0) {
free(start);
return 1;
} else {
*pt = thread;
return 0;
}
}
int Platform__join_thread(foundation_thread pt, void** rv) {
return (WaitForSingleObject(pt, INFINITE) == WAIT_OBJECT_0) ? 0 : 1;
}
void Platform__init_thread(foundation_thread_attributes* pa, size_t size) {
}
size_t Platform__get_thread_stack_size(foundation_thread_attributes* pa) {
return 0;
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 424 "inweb/foundation-module/Chapter 1/Windows Platform.w"
int Platform__get_core_count(void) {
int count = 0;
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
count = (int) sysInfo.dwNumberOfProcessors;
/* Leave one core idle by default */
if (count > 1)
count--;
return count;
}
#endif /* PLATFORM_WINDOWS */
#ifdef PLATFORM_WINDOWS
#line 445 "inweb/foundation-module/Chapter 1/Windows Platform.w"
time_t Platform__never_time(void) {
return (time_t) 0;
}
time_t Platform__timestamp(char *transcoded_filename) {
struct stat filestat;
if (stat(transcoded_filename, &filestat) != -1) return filestat.st_mtime;
return Platform__never_time();
}
off_t Platform__size(char *transcoded_filename) {
struct stat filestat;
if (stat(transcoded_filename, &filestat) != -1) return filestat.st_size;
return (off_t) 0;
}
#endif /* PLATFORM_WINDOWS */
#line 10 "inweb/foundation-module/Chapter 2/Debugging Log.w"
text_stream debug_log_file_struct; /* The actual debugging log file */
text_stream *debug_log_file = &debug_log_file_struct; /* The actual debugging log file */
#line 49 "inweb/foundation-module/Chapter 2/Debugging Log.w"
#line 59 "inweb/foundation-module/Chapter 2/Debugging Log.w"
#line 61 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int das_created = FALSE;
debugging_aspect the_debugging_aspects[NO_DEFINED_DA_VALUES];
void Log__declare_aspect(int a, wchar_t *name, int def, int alt) {
if (das_created == FALSE) {
das_created = TRUE;
{
#line 76 "inweb/foundation-module/Chapter 2/Debugging Log.w"
for (int a=0; a<NO_DEFINED_DA_VALUES; a++) {
debugging_aspect *da = &(the_debugging_aspects[a]);
da->hyphenated_name = Str__new();
da->unhyphenated_name = Str__new();
da->negated_name = Str__new();
da->on_or_off = FALSE;
da->alternate = FALSE;
}
}
#line 67 "inweb/foundation-module/Chapter 2/Debugging Log.w"
;
}
if ((a < 0) || (a >= NO_DEFINED_DA_VALUES)) internal_error("aspect out of range");
debugging_aspect *da = &(the_debugging_aspects[a]);
{
#line 86 "inweb/foundation-module/Chapter 2/Debugging Log.w"
WRITE_TO(da->negated_name, "no-");
for (int i=0; name[i]; i++) {
wchar_t c = name[i];
PUT_TO(da->unhyphenated_name, c);
if (Characters__is_space_or_tab(c)) c = '-';
PUT_TO(da->hyphenated_name, c);
PUT_TO(da->negated_name, c);
}
da->on_or_off = def;
da->alternate = alt;
}
#line 72 "inweb/foundation-module/Chapter 2/Debugging Log.w"
;
}
#line 109 "inweb/foundation-module/Chapter 2/Debugging Log.w"
filename *debug_log_filename = NULL;
filename *Log__get_debug_log_filename(void) {
return debug_log_filename;
}
void Log__set_debug_log_filename(filename *F) {
debug_log_filename = F;
}
int Log__open(void) {
if ((debug_log_filename) && (DL == NULL)) {
if (STREAM_OPEN_TO_FILE(debug_log_file, debug_log_filename, ISO_ENC) == FALSE)
return FALSE;
DL = debug_log_file;
Streams__enable_debugging(DL);
LOG("Debugging log of %s\n", PROGRAM_NAME);
return TRUE;
}
return FALSE;
}
int Log__open_alternative(filename *F, text_stream *at) {
if (STREAM_OPEN_TO_FILE(at, F, ISO_ENC) == FALSE)
return FALSE;
DL = at;
Streams__enable_debugging(DL);
LOG("Debugging log of %s\n", PROGRAM_NAME);
return TRUE;
}
void Log__close(void) {
if (DL) {
Log__show_debugging_contents();
STREAM_CLOSE(DL); DL = NULL;
}
}
#line 153 "inweb/foundation-module/Chapter 2/Debugging Log.w"
char debug_log_phase[32];
int debug_log_subheading = 1;
void Log__new_phase(char *p, text_stream *q) {
CStrings__truncated_strcpy(debug_log_phase, p, 32);
LOG("\n\n-----------------------------------------------------\n");
LOG("Phase %s ... %S", p, q);
LOG("\n-----------------------------------------------------\n\n");
STREAM_FLUSH(DL);
debug_log_subheading = 1;
}
void Log__new_stage(text_stream *p) {
LOG("\n\n==== Phase %s.%d ... %S ====\n\n", debug_log_phase, debug_log_subheading, p);
debug_log_subheading++;
STREAM_FLUSH(DL);
}
#line 178 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int Log__aspect_switched_on(int aspect) {
int decision = the_debugging_aspects[aspect].on_or_off;
if (aspect == DEBUGGING_LOG_INCLUSIONS_DA) decision = TRUE;
if (decision) STREAM_FLUSH(DL);
return decision;
}
void Log__set_aspect(int aspect, int state) {
the_debugging_aspects[aspect].on_or_off = state;
}
#line 192 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__set_all_aspects(int new_state) {
if (DL) LOGIF(DEBUGGING_LOG_INCLUSIONS, "Set debugging aspect: everything -> %s\n",
new_state?"TRUE":"FALSE");
for (int a=0; a<NO_DEFINED_DA_VALUES; a++) {
debugging_aspect *da = &(the_debugging_aspects[a]);
da->on_or_off = new_state;
}
}
#line 210 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int Log__set_aspect_from_command_line(text_stream *name, int give_error) {
int list_mode = FALSE;
if (Str__eq_wide_string(name, L"everything")) { Log__set_all_aspects(TRUE); return TRUE; }
if (Str__eq_wide_string(name, L"nothing")) { Log__set_all_aspects(FALSE); return TRUE; }
if (Str__eq_wide_string(name, L"list")) list_mode = TRUE;
for (int i=0; i<NO_DEFINED_DA_VALUES; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
if (Str__eq(name, da->negated_name)) {
da->on_or_off = FALSE; return TRUE;
}
if ((Str__eq(name, da->hyphenated_name)) ||
(Str__eq(name, da->unhyphenated_name))) {
da->on_or_off = TRUE; return TRUE;
}
if ((list_mode) && (Str__len(da->hyphenated_name) > 0)) {
PRINT("--log %S (%s)\n", da->hyphenated_name, (da->on_or_off)?"on":"off");
}
}
if ((list_mode == FALSE) && (give_error))
PRINT("No such debugging log aspect as '%S'.\n"
"(Try running -log list for a list of the valid aspects.)\n", name);
if (list_mode == TRUE) return TRUE;
return FALSE;
}
#line 241 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__tracing_on(int starred, text_stream *heading) {
if (starred) {
LOG("\n*** Entering sentence trace mode: %S ***\n", heading);
} else {
LOG("\n*** Leaving sentence trace mode: %S ***\n\n", heading);
}
for (int i=0; i<NO_DEFINED_DA_VALUES; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
int j = da->on_or_off;
da->on_or_off = da->alternate;
da->alternate = j;
}
}
#line 261 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__show_debugging_settings_with_state(int state) {
int c = 0;
for (int i=0; i<NO_DEFINED_DA_VALUES; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
if (da->on_or_off == state) {
c++;
LOG(" %S", da->hyphenated_name);
if (c % 6 == 0) LOG("\n");
}
}
if (c == 0) { LOG(" (nothing)\n"); } else { LOG("\n"); }
}
void Log__show_debugging_contents(void) {
if (Log__aspect_switched_on(DEBUGGING_LOG_INCLUSIONS_DA) == FALSE) return;
LOG("\n\nThat concludes the debugging log from this run.\n"
"Its contents were as follows -\n\n");
LOG("Included:\n"); Log__show_debugging_settings_with_state(TRUE);
LOG("Omitted:\n"); Log__show_debugging_settings_with_state(FALSE);
}
#line 70 "inweb/foundation-module/Chapter 2/Memory.w"
#line 76 "inweb/foundation-module/Chapter 2/Memory.w"
allocation_status_structure alloc_status[NO_DEFINED_CLASS_VALUES];
void Memory__start(void) {
for (int i=0; i<NO_DEFINED_CLASS_VALUES; i++) {
alloc_status[i].first_in_memory = NULL;
alloc_status[i].last_in_memory = NULL;
alloc_status[i].objects_allocated = 0;
alloc_status[i].objects_count = 0;
alloc_status[i].bytes_allocated = 0;
alloc_status[i].no_allocated_together = 1;
alloc_status[i].name_of_type = "unused";
}
Memory__name_fundamental_reasons();
}
#line 127 "inweb/foundation-module/Chapter 2/Memory.w"
int no_blocks_allocated = 0;
int total_objects_allocated = 0; /* a potentially larger number, used only for the debugging log */
#line 141 "inweb/foundation-module/Chapter 2/Memory.w"
#line 143 "inweb/foundation-module/Chapter 2/Memory.w"
memblock_header *first_memblock_header = NULL; /* head of list of memory blocks */
memblock_header *current_memblock_header = NULL; /* tail of list of memory blocks */
int used_in_current_memblock = 0; /* number of bytes so far used in the tail memory block */
CREATE_MUTEX(memory_single_allocation_mutex)
CREATE_MUTEX(memory_array_allocation_mutex)
CREATE_MUTEX(memory_statistics_mutex)
#line 156 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__allocate_another_block(void) {
unsigned char *cp;
memblock_header *mh;
{
#line 173 "inweb/foundation-module/Chapter 2/Memory.w"
Memory__check_memory_integrity();
cp = (unsigned char *) (Memory__paranoid_calloc(MEMORY_GRANULARITY, 1));
if (cp == NULL) Errors__fatal("Run out of memory: malloc failed");
for (int i=0; i<MEMORY_GRANULARITY; i++) cp[i] = 0;
}
#line 160 "inweb/foundation-module/Chapter 2/Memory.w"
;
mh = (memblock_header *) cp;
used_in_current_memblock = sizeof(memblock_header) + SAFETY_MARGIN;
mh->the_memory = (void *) (cp + used_in_current_memblock);
{
#line 182 "inweb/foundation-module/Chapter 2/Memory.w"
if (current_memblock_header == NULL) {
mh->block_number = 0;
first_memblock_header = mh;
} else {
mh->block_number = current_memblock_header->block_number + 1;
current_memblock_header->next = mh;
}
current_memblock_header = mh;
}
#line 166 "inweb/foundation-module/Chapter 2/Memory.w"
;
}
#line 196 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__free(void) {
CStrings__free_ssas();
memblock_header *mh = first_memblock_header;
while (mh != NULL) {
memblock_header *next_mh = mh->next;
void *p = (void *) mh;
free(p);
mh = next_mh;
}
}
#line 223 "inweb/foundation-module/Chapter 2/Memory.w"
#line 229 "inweb/foundation-module/Chapter 2/Memory.w"
memory_frame *first_memory_frame = NULL; /* earliest memory frame ever allocated */
memory_frame *last_memory_frame = NULL; /* most recent memory frame allocated */
#line 240 "inweb/foundation-module/Chapter 2/Memory.w"
int calls_to_cmi = 0;
void Memory__check_memory_integrity(void) {
int c;
memory_frame *mf;
c = calls_to_cmi++;
if (!((c<10) || (c == 100) || (c == 1000) || (c == 10000))) return;
for (c = 0, mf = first_memory_frame; mf; c++, mf = mf->next_frame)
if (mf->integrity_check != INTEGRITY_NUMBER)
Errors__fatal("Memory manager failed integrity check");
}
void Memory__debug_memory_frames(int from, int to) {
int c;
memory_frame *mf;
for (c = 0, mf = first_memory_frame; (mf) && (c <= to); c++, mf = mf->next_frame)
if (c >= from) {
char *desc = "corrupt";
if (mf->integrity_check == INTEGRITY_NUMBER)
desc = alloc_status[mf->mem_type].name_of_type;
}
}
#line 269 "inweb/foundation-module/Chapter 2/Memory.w"
void *Memory__allocate(int mem_type, int extent) {
unsigned char *cp;
memory_frame *mf;
int bytes_free_in_current_memblock, extent_without_overheads = extent;
extent += sizeof(memory_frame); /* each allocation is preceded by a memory frame */
extent += SAFETY_MARGIN; /* each allocation is followed by |SAFETY_MARGIN| null bytes */
{
#line 301 "inweb/foundation-module/Chapter 2/Memory.w"
if (current_memblock_header == NULL) Memory__allocate_another_block();
bytes_free_in_current_memblock = MEMORY_GRANULARITY - (used_in_current_memblock + extent);
if (bytes_free_in_current_memblock < BLANK_END_SIZE) {
Memory__allocate_another_block();
if (extent+BLANK_END_SIZE >= MEMORY_GRANULARITY)
Errors__fatal("Memory manager failed because granularity too low");
}
}
#line 277 "inweb/foundation-module/Chapter 2/Memory.w"
;
cp = ((unsigned char *) (current_memblock_header->the_memory)) + used_in_current_memblock;
used_in_current_memblock += extent;
mf = (memory_frame *) cp; /* the new memory frame, */
cp = cp + sizeof(memory_frame); /* following which is the actual allocated data */
mf->integrity_check = INTEGRITY_NUMBER;
mf->allocation_id = alloc_status[mem_type].objects_allocated;
mf->mem_type = mem_type;
{
#line 312 "inweb/foundation-module/Chapter 2/Memory.w"
mf->next_frame = NULL;
if (first_memory_frame == NULL) first_memory_frame = mf;
else last_memory_frame->next_frame = mf;
last_memory_frame = mf;
}
#line 289 "inweb/foundation-module/Chapter 2/Memory.w"
;
{
#line 320 "inweb/foundation-module/Chapter 2/Memory.w"
if (alloc_status[mem_type].first_in_memory == NULL)
alloc_status[mem_type].first_in_memory = (void *) cp;
alloc_status[mem_type].last_in_memory = (void *) cp;
alloc_status[mem_type].objects_allocated++;
alloc_status[mem_type].bytes_allocated += extent_without_overheads;
}
#line 290 "inweb/foundation-module/Chapter 2/Memory.w"
;
total_objects_allocated++;
return (void *) cp;
}
#line 470 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__name_fundamental_reasons(void) {
Memory__reason_name(STREAM_MREASON, "text stream storage");
Memory__reason_name(FILENAME_STORAGE_MREASON, "filename/pathname storage");
Memory__reason_name(STRING_STORAGE_MREASON, "string storage");
Memory__reason_name(DICTIONARY_MREASON, "dictionary storage");
Memory__reason_name(ARRAY_SORTING_MREASON, "sorting");
}
#line 481 "inweb/foundation-module/Chapter 2/Memory.w"
char *memory_needs[NO_DEFINED_MREASON_VALUES];
void Memory__reason_name(int r, char *reason) {
if ((r < 0) || (r >= NO_DEFINED_MREASON_VALUES)) internal_error("MR out of range");
memory_needs[r] = reason;
}
char *Memory__description_of_reason(int r) {
if ((r < 0) || (r >= NO_DEFINED_MREASON_VALUES)) internal_error("MR out of range");
return memory_needs[r];
}
#line 501 "inweb/foundation-module/Chapter 2/Memory.w"
int max_memory_at_once_for_each_need[NO_DEFINED_MREASON_VALUES],
memory_claimed_for_each_need[NO_DEFINED_MREASON_VALUES],
number_of_claims_for_each_need[NO_DEFINED_MREASON_VALUES];
int total_claimed_simply = 0;
#line 513 "inweb/foundation-module/Chapter 2/Memory.w"
void *Memory__calloc(int how_many, int size_in_bytes, int reason) {
return Memory__alloc_inner(how_many, size_in_bytes, reason);
}
void *Memory__malloc(int size_in_bytes, int reason) {
return Memory__alloc_inner(-1, size_in_bytes, reason);
}
#line 523 "inweb/foundation-module/Chapter 2/Memory.w"
void *Memory__alloc_inner(int N, int S, int R) {
void *pointer;
int bytes_needed;
if ((R < 0) || (R >= NO_DEFINED_MREASON_VALUES)) internal_error("no such memory reason");
if (total_claimed_simply == 0)
{
#line 554 "inweb/foundation-module/Chapter 2/Memory.w"
LOCK_MUTEX(memory_statistics_mutex);
for (int i=0; i<NO_DEFINED_MREASON_VALUES; i++) {
max_memory_at_once_for_each_need[i] = 0;
memory_claimed_for_each_need[i] = 0;
number_of_claims_for_each_need[i] = 0;
}
UNLOCK_MUTEX(memory_statistics_mutex);
}
#line 527 "inweb/foundation-module/Chapter 2/Memory.w"
;
{
#line 538 "inweb/foundation-module/Chapter 2/Memory.w"
if (N > 0) {
pointer = Memory__paranoid_calloc((size_t) N, (size_t) S);
bytes_needed = N*S;
} else {
pointer = Memory__paranoid_calloc(1, (size_t) S);
bytes_needed = S;
}
if (pointer == NULL) {
Errors__fatal_with_C_string("Out of memory for %s", Memory__description_of_reason(R));
}
}
#line 528 "inweb/foundation-module/Chapter 2/Memory.w"
;
{
#line 563 "inweb/foundation-module/Chapter 2/Memory.w"
LOCK_MUTEX(memory_statistics_mutex);
memory_claimed_for_each_need[R] += bytes_needed;
total_claimed_simply += bytes_needed;
number_of_claims_for_each_need[R]++;
if (memory_claimed_for_each_need[R] > max_memory_at_once_for_each_need[R])
max_memory_at_once_for_each_need[R] = memory_claimed_for_each_need[R];
UNLOCK_MUTEX(memory_statistics_mutex);
}
#line 529 "inweb/foundation-module/Chapter 2/Memory.w"
;
return pointer;
}
#line 574 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__I7_free(void *pointer, int R, int bytes_freed) {
if ((R < 0) || (R >= NO_DEFINED_MREASON_VALUES)) internal_error("no such memory reason");
if (pointer == NULL) internal_error("can't free NULL memory");
LOCK_MUTEX(memory_statistics_mutex);
memory_claimed_for_each_need[R] -= bytes_freed;
UNLOCK_MUTEX(memory_statistics_mutex);
free(pointer);
}
void Memory__I7_array_free(void *pointer, int R, int num_cells, size_t cell_size) {
Memory__I7_free(pointer, R, num_cells*((int) cell_size));
}
#line 591 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__log_statistics(void) {
int total_for_objects = MEMORY_GRANULARITY*no_blocks_allocated; /* usage in bytes */
int total_for_SMAs = Memory__log_usage(0); /* usage in bytes */
int sorted_usage[NO_DEFINED_CLASS_VALUES]; /* memory type numbers, in usage order */
int total = (total_for_objects + total_for_SMAs)/1024; /* total memory usage in KB */
{
#line 624 "inweb/foundation-module/Chapter 2/Memory.w"
for (int i=0; i<NO_DEFINED_CLASS_VALUES; i++) sorted_usage[i] = i;
qsort(sorted_usage, (size_t) NO_DEFINED_CLASS_VALUES, sizeof(int), Memory__compare_usage);
}
#line 597 "inweb/foundation-module/Chapter 2/Memory.w"
;
int total_for_objects_used = 0; /* out of the |total_for_objects|, the bytes used */
int total_objects = 0;
{
#line 607 "inweb/foundation-module/Chapter 2/Memory.w"
int i, j;
for (j=0; j<NO_DEFINED_CLASS_VALUES; j++) {
i = sorted_usage[j];
if (alloc_status[i].objects_allocated != 0) {
if (alloc_status[i].no_allocated_together == 1)
total_objects += alloc_status[i].objects_allocated;
else
total_objects += alloc_status[i].objects_allocated*
alloc_status[i].no_allocated_together;
total_for_objects_used += alloc_status[i].bytes_allocated;
}
}
}
#line 601 "inweb/foundation-module/Chapter 2/Memory.w"
;
int overhead_for_objects = total_for_objects - total_for_objects_used; /* bytes wasted */
{
#line 630 "inweb/foundation-module/Chapter 2/Memory.w"
LOG("Total memory consumption was %dK = %d MB\n\n",
total, (total+512)/1024);
Memory__log_percentage(total_for_objects, total);
LOG(" was used for %d objects, in %d frames in %d x %dK = %dK = %d MB:\n\n",
total_objects, total_objects_allocated, no_blocks_allocated,
MEMORY_GRANULARITY/1024,
total_for_objects/1024, (total_for_objects+512)/1024/1024);
for (int j=0; j<NO_DEFINED_CLASS_VALUES; j++) {
int i = sorted_usage[j];
if (alloc_status[i].objects_allocated != 0) {
LOG(" ");
Memory__log_percentage(alloc_status[i].bytes_allocated, total);
LOG(" %s", alloc_status[i].name_of_type);
for (int n=(int) strlen(alloc_status[i].name_of_type); n<41; n++) LOG(" ");
if (alloc_status[i].no_allocated_together == 1) {
LOG("%d ", alloc_status[i].objects_count);
if (alloc_status[i].objects_count != alloc_status[i].objects_allocated)
LOG("(+%d deleted) ",
alloc_status[i].objects_allocated - alloc_status[i].objects_count);
LOG("object");
if (alloc_status[i].objects_allocated > 1) LOG("s");
} else {
if (alloc_status[i].objects_allocated > 1)
LOG("%d x %d = %d ",
alloc_status[i].objects_allocated, alloc_status[i].no_allocated_together,
alloc_status[i].objects_allocated*alloc_status[i].no_allocated_together);
else
LOG("1 x %d ", alloc_status[i].no_allocated_together);
LOG("objects");
}
LOG(", %d bytes\n", alloc_status[i].bytes_allocated);
}
}
LOG("\n");
Memory__log_percentage(1024*total-total_for_objects, total);
LOG(" was used for memory not allocated for objects:\n\n");
Memory__log_usage(total);
LOG("\n"); Memory__log_percentage(overhead_for_objects, total);
LOG(" was overhead - %d bytes = %dK = %d MB\n\n", overhead_for_objects,
overhead_for_objects/1024, (overhead_for_objects+512)/1024/1024);
}
#line 603 "inweb/foundation-module/Chapter 2/Memory.w"
;
}
#line 673 "inweb/foundation-module/Chapter 2/Memory.w"
int Memory__log_usage(int total) {
if (total_claimed_simply == 0) return 0;
int i, t = 0;
for (i=0; i<NO_DEFINED_MREASON_VALUES; i++) {
t += max_memory_at_once_for_each_need[i];
if ((total > 0) && (max_memory_at_once_for_each_need[i] > 0)) {
LOG(" ");
Memory__log_percentage(max_memory_at_once_for_each_need[i], total);
LOG(" %s", Memory__description_of_reason(i));
for (int n=(int) strlen(Memory__description_of_reason(i)); n<41; n++) LOG(" ");
LOG("%d bytes in %d claim%s\n",
max_memory_at_once_for_each_need[i],
number_of_claims_for_each_need[i],
(number_of_claims_for_each_need[i] == 1)?"":"s");
}
}
return t;
}
#line 693 "inweb/foundation-module/Chapter 2/Memory.w"
int Memory__compare_usage(const void *ent1, const void *ent2) {
int ix1 = *((const int *) ent1);
int ix2 = *((const int *) ent2);
return alloc_status[ix2].bytes_allocated - alloc_status[ix1].bytes_allocated;
}
#line 703 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__log_percentage(int bytes, int total) {
float B = (float) bytes, T = (float) total;
float P = (1000*B)/(1024*T);
int N = (int) P;
if (N == 0) LOG(" ----");
else LOG("%2d.%01d%%", N/10, N%10);
}
#line 716 "inweb/foundation-module/Chapter 2/Memory.w"
void *Memory__paranoid_calloc(size_t N, size_t S) {
void *P = calloc(N, S);
return P;
}
#line 747 "inweb/foundation-module/Chapter 2/Memory.w"
general_pointer Memory__store_gp_null(void) {
general_pointer gp;
gp.pointer_to_data = NULL;
gp.run_time_type_code = -1; /* guaranteed to differ from all |_CLASS| values */
return gp;
}
int Memory__test_gp_null(general_pointer gp) {
if (gp.run_time_type_code == -1) return TRUE;
return FALSE;
}
#line 806 "inweb/foundation-module/Chapter 2/Memory.w"
MAKE_REFERENCE_ROUTINES(char, 1000)
#line 59 "inweb/foundation-module/Chapter 2/Foundation Classes.w"
DECLARE_CLASS(chapter_md)
DECLARE_CLASS(command_line_switch)
DECLARE_CLASS(debugging_aspect)
DECLARE_CLASS(dictionary)
DECLARE_CLASS(ebook_chapter)
DECLARE_CLASS(ebook_datum)
DECLARE_CLASS(ebook_image)
DECLARE_CLASS(ebook_mark)
DECLARE_CLASS(ebook_page)
DECLARE_CLASS(ebook_volume)
DECLARE_CLASS(ebook)
DECLARE_CLASS(filename)
DECLARE_CLASS(heterogeneous_tree)
DECLARE_CLASS(HTML_file_state)
DECLARE_CLASS(JSON_pair_requirement)
DECLARE_CLASS(JSON_requirement)
DECLARE_CLASS(JSON_single_requirement)
DECLARE_CLASS(JSON_type)
DECLARE_CLASS(JSON_value)
DECLARE_CLASS(linked_list)
DECLARE_CLASS(method_set)
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)
DECLARE_CLASS(semver_range)
DECLARE_CLASS(stopwatch_timer)
DECLARE_CLASS(string_storage_area)
DECLARE_CLASS(tree_node_type)
DECLARE_CLASS(tree_node)
DECLARE_CLASS(tree_type)
DECLARE_CLASS(web_bibliographic_datum)
DECLARE_CLASS(web_md)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(dict_entry, 100)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(HTML_tag, 1000)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(linked_list_item, 1000)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(match_avinue, 1000)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(match_trie, 1000)
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(text_stream, 100)
#line 12 "inweb/foundation-module/Chapter 2/Locales.w"
char *Locales__name(int L) {
switch (L) {
case SHELL_LOCALE: return "shell";
case CONSOLE_LOCALE: return "console";
}
return "";
}
int Locales__parse_locale(char *name) {
for (int i=0; i<NO_DEFINED_LOCALE_VALUES; i++)
if (strcmp(name, Locales__name(i)) == 0)
return i;
return -1;
}
#line 32 "inweb/foundation-module/Chapter 2/Locales.w"
int locales_unset = TRUE;
int locale_settings[NO_DEFINED_LOCALE_VALUES];
int Locales__get(int L) {
if ((L < 0) || (L >= NO_DEFINED_LOCALE_VALUES)) Errors__fatal("locale out of range");
if (locales_unset) return Locales__platform_locale();
if (locale_settings[L] >= 0) return locale_settings[L];
return Locales__platform_locale();
}
void Locales__set(int L, int E) {
if ((L < 0) || (L >= NO_DEFINED_LOCALE_VALUES)) Errors__fatal("locale out of range");
if (locales_unset) {
for (int i=0; i<NO_DEFINED_LOCALE_VALUES; i++) locale_settings[i] = -1;
locales_unset = FALSE;
}
locale_settings[L] = E;
}
#line 60 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__parse_encoding(char *name) {
if (strcmp(name, "platform") == 0) return -1;
if (strcmp(name, "iso-latin1") == 0) return FILE_ENCODING_ISO_STRF;
if (strcmp(name, "utf-8") == 0) return FILE_ENCODING_UTF8_STRF;
return 0;
}
#line 72 "inweb/foundation-module/Chapter 2/Locales.w"
void Locales__write_locales(OUTPUT_STREAM) {
WRITE("Locales are: ");
for (int i=0; i<NO_DEFINED_LOCALE_VALUES; i++) {
if (i > 0) WRITE(", ");
WRITE("%s = ", Locales__name(i));
Locales__write_locale(OUT, Locales__get(i));
}
WRITE("\n");
}
void Locales__write_locale(OUTPUT_STREAM, int L) {
switch (L) {
case -1:
WRITE("platform (= ");
Locales__write_locale(OUT, Locales__platform_locale());
WRITE(")"); break;
case FILE_ENCODING_ISO_STRF: WRITE("iso-latin1"); break;
case FILE_ENCODING_UTF8_STRF: WRITE("utf-8"); break;
default: WRITE("?"); break;
}
}
#line 98 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__platform_locale(void) {
#ifdef LOCALE_IS_ISO
return FILE_ENCODING_ISO_STRF;
#endif
#ifndef LOCALE_IS_ISO
#ifdef LOCALE_IS_UTF8
return FILE_ENCODING_UTF8_STRF;
#endif
#ifndef LOCALE_IS_UTF8
Errors__fatal("built without either LOCALE_IS_ISO or LOCALE_IS_UTF8");
return FILE_ENCODING_UTF8_STRF;
#endif
#endif
}
#line 118 "inweb/foundation-module/Chapter 2/Locales.w"
int Locales__set_locales(char *text) {
if (text == NULL) return FALSE;
for (int at=0; ((at >= 0) && (text[at])); ) {
int c = -1;
for (int i=at; text[i]; i++) if (text[i] == '=') { c = i; break; }
if (c == -1) return FALSE;
if (c-at >= 16) return FALSE;
char L1[16], L2[16];
for (int i=0; i<16; i++) { L1[i] = 0; L2[i] = 0; }
for (int i=0; i<c-at; i++) L1[i] = (char) tolower((int) text[at+i]);
int next_at = -1;
for (int i=0; (text[c+1+i]) && (i<16); i++) {
if (text[c+1+i] == ',') { next_at = c+1+i+1; break; }
L2[i] = (char) tolower((int) text[c+1+i]);
}
int L = Locales__parse_locale(L1), E = Locales__parse_encoding(L2);
if ((L < 0) || (L >= NO_DEFINED_LOCALE_VALUES)) return FALSE;
if (E == 0) return FALSE;
Locales__set(L, E);
at = next_at;
}
return TRUE;
}
#line 245 "inweb/foundation-module/Chapter 2/Streams.w"
#line 260 "inweb/foundation-module/Chapter 2/Streams.w"
int total_file_writes = 0; /* number of text files opened for writing during the run */
#line 274 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__initialise(text_stream *stream, int from) {
if (stream == NULL) internal_error("tried to initialise NULL stream");
stream->stream_flags = from;
stream->write_to_file = NULL;
stream->write_to_memory = NULL;
stream->chars_written = 0;
stream->chars_capacity = 2147483647;
stream->stream_continues = NULL;
stream->as_HTML = NULL;
stream->file_written = NULL;
}
#line 292 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__enable_XML_escapes(text_stream *stream) {
if (stream) stream->stream_flags |= USES_XML_ESCAPES_STRF;
}
void Streams__disable_XML_escapes(text_stream *stream) {
if ((stream) && (stream->stream_flags & USES_XML_ESCAPES_STRF))
stream->stream_flags -= USES_XML_ESCAPES_STRF;
}
int I6_escapes_globally_enabled = FALSE;
void Streams__enable_I6_escapes(text_stream *stream) {
if (stream) stream->stream_flags |= USES_I6_ESCAPES_STRF;
I6_escapes_globally_enabled = TRUE;
}
void Streams__disable_I6_escapes(text_stream *stream) {
if ((stream) && (stream->stream_flags & USES_I6_ESCAPES_STRF))
stream->stream_flags -= USES_I6_ESCAPES_STRF;
I6_escapes_globally_enabled = FALSE;
}
int Streams__I6_escapes_enabled(text_stream *stream) {
return I6_escapes_globally_enabled;
}
void Streams__enable_debugging(text_stream *stream) {
if (stream) stream->stream_flags |= USES_LOG_ESCAPES_STRF;
}
void Streams__disable_debugging(text_stream *stream) {
if ((stream) && (stream->stream_flags & USES_LOG_ESCAPES_STRF))
stream->stream_flags -= USES_LOG_ESCAPES_STRF;
}
void Streams__mark_as_read_only(text_stream *stream) {
if (stream) stream->stream_flags |= READ_ONLY_STRF;
}
void Streams__declare_as_HTML(text_stream *stream, HTML_file_state *hs) {
if (stream) stream->as_HTML = hs;
}
HTML_file_state *Streams__get_HTML_file_state(text_stream *stream) {
return stream->as_HTML;
}
#line 341 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__log(OUTPUT_STREAM, void *vS) {
text_stream *stream = (text_stream *) vS;
if (stream == NULL) {
WRITE("NULL");
} else if (stream->write_to_file) {
WRITE("F'%f'(%d)", stream->file_written, stream->chars_written);
} else {
WRITE("S%x(", (long int) stream);
while (stream) {
WRITE("%d/%d", stream->chars_written, stream->chars_capacity);
if (stream->stream_continues) WRITE("+");
stream = stream->stream_continues;
}
WRITE(")");
}
}
#line 363 "inweb/foundation-module/Chapter 2/Streams.w"
text_stream STDOUT_struct; int stdout_wrapper_initialised = FALSE;
text_stream *Streams__get_stdout(void) {
if (stdout_wrapper_initialised == FALSE) {
Streams__initialise(&STDOUT_struct, 0); STDOUT_struct.write_to_file = stdout;
stdout_wrapper_initialised = TRUE;
#ifdef STDOUT_LOCALE_TEST
STDOUT_struct.stream_flags |= ECHO_BYTES_STRF;
#endif
if (Locales__get(CONSOLE_LOCALE) == FILE_ENCODING_ISO_STRF)
STDOUT_struct.stream_flags |= FILE_ENCODING_ISO_STRF;
if (Locales__get(CONSOLE_LOCALE) == FILE_ENCODING_UTF8_STRF)
STDOUT_struct.stream_flags |= FILE_ENCODING_UTF8_STRF;
}
return &STDOUT_struct;
}
#line 382 "inweb/foundation-module/Chapter 2/Streams.w"
text_stream STDERR_struct; int stderr_wrapper_initialised = FALSE;
text_stream *Streams__get_stderr(void) {
if (stderr_wrapper_initialised == FALSE) {
Streams__initialise(&STDERR_struct, 0); STDERR_struct.write_to_file = stderr;
stderr_wrapper_initialised = TRUE;
if (Locales__get(CONSOLE_LOCALE) == FILE_ENCODING_ISO_STRF)
STDERR_struct.stream_flags |= FILE_ENCODING_ISO_STRF;
if (Locales__get(CONSOLE_LOCALE) == FILE_ENCODING_UTF8_STRF)
STDERR_struct.stream_flags |= FILE_ENCODING_UTF8_STRF;
}
return &STDERR_struct;
}
#line 400 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_to_file(text_stream *stream, filename *name, int encoding) {
if (stream == NULL) internal_error("tried to open NULL stream");
if (name == NULL) internal_error("stream_open_to_file on null filename");
Streams__initialise(stream, FOR_FI_STRF);
switch(encoding) {
case UTF8_ENC: stream->stream_flags |= FILE_ENCODING_UTF8_STRF; break;
case ISO_ENC: stream->stream_flags |= FILE_ENCODING_ISO_STRF; break;
default: internal_error("stream has unknown text encoding");
}
stream->write_to_file = Filenames__fopen(name, "w");
if (stream->write_to_file == NULL) return FALSE;
stream->file_written = name;
total_file_writes++;
return TRUE;
}
#line 419 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_to_file_append(text_stream *stream, filename *name, int encoding) {
if (stream == NULL) internal_error("tried to open NULL stream");
if (name == NULL) internal_error("stream_open_to_file on null filename");
Streams__initialise(stream, FOR_FI_STRF);
switch(encoding) {
case UTF8_ENC: stream->stream_flags |= FILE_ENCODING_UTF8_STRF; break;
case ISO_ENC: stream->stream_flags |= FILE_ENCODING_ISO_STRF; break;
default: internal_error("stream has unknown text encoding");
}
stream->write_to_file = Filenames__fopen(name, "a");
if (stream->write_to_file == NULL) return FALSE;
total_file_writes++;
return TRUE;
}
#line 440 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_to_memory(text_stream *stream, int capacity) {
if (stream == NULL) internal_error("tried to open NULL stream");
capacity += SPACE_AT_END_OF_STREAM;
Streams__initialise(stream, FOR_OM_STRF);
stream->write_to_memory = Memory__calloc(capacity, sizeof(wchar_t), STREAM_MREASON);
if (stream->write_to_memory == NULL) return FALSE;
(stream->write_to_memory)[0] = 0;
stream->stream_flags |= MALLOCED_STRF;
stream->chars_capacity = capacity;
return TRUE;
}
#line 456 "inweb/foundation-module/Chapter 2/Streams.w"
text_stream Streams__new_buffer(int capacity, wchar_t *at) {
if (at == NULL) internal_error("tried to make stream wrapper for NULL string");
if (capacity < SPACE_AT_END_OF_STREAM)
internal_error("memory stream too small");
text_stream stream;
Streams__initialise(&stream, FOR_TT_STRF);
stream.write_to_memory = at;
(stream.write_to_memory)[0] = 0;
stream.chars_capacity = capacity - SPACE_AT_END_OF_STREAM;
return stream;
}
#line 474 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_wide_string(text_stream *stream, const wchar_t *c_string) {
if (stream == NULL) internal_error("tried to open NULL stream");
int capacity = (c_string)?((int) wcslen(c_string)):0;
{
#line 523 "inweb/foundation-module/Chapter 2/Streams.w"
if (capacity < 8) capacity = 8;
capacity += 1+SPACE_AT_END_OF_STREAM;
int rv = Streams__open_to_memory(stream, capacity);
if (rv == FALSE) return FALSE;
}
#line 477 "inweb/foundation-module/Chapter 2/Streams.w"
;
if (c_string) Streams__write_wide_string(stream, c_string);
return TRUE;
}
void Streams__write_wide_string(text_stream *stream, const wchar_t *c_string) {
for (int i=0; c_string[i]; i++) Streams__putc(c_string[i], stream);
}
#line 490 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_ISO_string(text_stream *stream, const char *c_string) {
if (stream == NULL) internal_error("tried to open NULL stream");
int capacity = (c_string)?((int) strlen(c_string)):0;
{
#line 523 "inweb/foundation-module/Chapter 2/Streams.w"
if (capacity < 8) capacity = 8;
capacity += 1+SPACE_AT_END_OF_STREAM;
int rv = Streams__open_to_memory(stream, capacity);
if (rv == FALSE) return FALSE;
}
#line 493 "inweb/foundation-module/Chapter 2/Streams.w"
;
if (c_string) Streams__write_ISO_string(stream, c_string);
return TRUE;
}
void Streams__write_ISO_string(text_stream *stream, const char *c_string) {
for (int i=0; c_string[i]; i++) Streams__putc(c_string[i], stream);
}
#line 505 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_UTF8_string(text_stream *stream, const char *c_string) {
if (stream == NULL) internal_error("tried to open NULL stream");
int capacity = (c_string)?((int) strlen(c_string)):0;
{
#line 523 "inweb/foundation-module/Chapter 2/Streams.w"
if (capacity < 8) capacity = 8;
capacity += 1+SPACE_AT_END_OF_STREAM;
int rv = Streams__open_to_memory(stream, capacity);
if (rv == FALSE) return FALSE;
}
#line 508 "inweb/foundation-module/Chapter 2/Streams.w"
;
if (c_string) Streams__write_UTF8_string(stream, c_string);
return TRUE;
}
void Streams__write_UTF8_string(text_stream *stream, const char *c_string) {
unicode_file_buffer ufb = TextFiles__create_ufb();
int c;
while ((c = TextFiles__utf8_fgetc(NULL, &c_string, FALSE, &ufb)) != 0)
Streams__putc(c, stream);
}
#line 532 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_as_wide_string(wchar_t *C_string, text_stream *stream, int buffer_size) {
if (buffer_size == 0) return;
if (stream == NULL) { C_string[0] = 0; return; }
if (stream->write_to_file) internal_error("stream_get_text on file stream");
int i = 0;
while (stream) {
for (int j=0; j<stream->chars_written; j++) {
if (i >= buffer_size-1) break;
C_string[i++] = stream->write_to_memory[j];
}
stream = stream->stream_continues;
}
C_string[i] = 0;
}
#line 551 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_as_ISO_string(char *C_string, text_stream *stream, int buffer_size) {
if (buffer_size == 0) return;
if (stream == NULL) { C_string[0] = 0; return; }
if (stream->write_to_file) internal_error("stream_get_text on file stream");
int i = 0;
while (stream) {
for (int j=0; j<stream->chars_written; j++) {
if (i >= buffer_size-1) break;
wchar_t c = stream->write_to_memory[j];
if (c < 256) C_string[i++] = (char) c; else C_string[i++] = '?';
}
stream = stream->stream_continues;
}
C_string[i] = 0;
}
#line 568 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__write_as_UTF8_string(char *C_string, text_stream *stream, int buffer_size) {
if (buffer_size == 0) return;
if (stream == NULL) { C_string[0] = 0; return; }
if (stream->write_to_file) internal_error("stream_get_text on file stream");
unsigned char *to = (unsigned char *) C_string;
int i = 0;
while (stream) {
for (int j=0; j<stream->chars_written; j++) {
unsigned int c = (unsigned int) stream->write_to_memory[j];
if (c >= 0x800) {
if (i >= buffer_size-3) break;
to[i++] = 0xE0 + (unsigned char) (c >> 12);
to[i++] = 0x80 + (unsigned char) ((c >> 6) & 0x3f);
to[i++] = 0x80 + (unsigned char) (c & 0x3f);
} else if (c >= 0x80) {
if (i >= buffer_size-2) break;
to[i++] = 0xC0 + (unsigned char) (c >> 6);
to[i++] = 0x80 + (unsigned char) (c & 0x3f);
} else {
if (i >= buffer_size-1) break;
to[i++] = (unsigned char) c;
}
}
stream = stream->stream_continues;
}
to[i] = 0;
}
#line 599 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__open_from_locale_string(text_stream *stream, const char *C_string) {
if (Locales__get(SHELL_LOCALE) == FILE_ENCODING_UTF8_STRF)
return Streams__open_from_UTF8_string(stream, C_string);
if (Locales__get(SHELL_LOCALE) == FILE_ENCODING_ISO_STRF)
return Streams__open_from_ISO_string(stream, C_string);
Errors__fatal("unknown command line locale");
return FALSE;
}
void Streams__write_as_locale_string(char *C_string, text_stream *stream, int buffer_size) {
if (Locales__get(SHELL_LOCALE) == FILE_ENCODING_UTF8_STRF)
Streams__write_as_UTF8_string(C_string, stream, buffer_size);
else if (Locales__get(SHELL_LOCALE) == FILE_ENCODING_ISO_STRF)
Streams__write_as_ISO_string(C_string, stream, buffer_size);
else Errors__fatal("unknown command line locale");
}
void Streams__write_locale_string(text_stream *stream, char *C_string) {
if (Locales__get(SHELL_LOCALE) == FILE_ENCODING_UTF8_STRF)
Streams__write_UTF8_string(stream, C_string);
else if (Locales__get(SHELL_LOCALE) == FILE_ENCODING_ISO_STRF)
Streams__write_ISO_string(stream, C_string);
else Errors__fatal("unknown command line locale");
}
#line 629 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__flush(text_stream *stream) {
if (stream == NULL) return;
if (stream->write_to_file) fflush(stream->write_to_file);
}
#line 637 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__close(text_stream *stream) {
if (stream == NULL) internal_error("tried to close NULL stream");
if (stream == &STDOUT_struct) internal_error("tried to close STDOUT stream");
if (stream == &STDERR_struct) internal_error("tried to close STDERR stream");
if (stream->chars_capacity == -1) internal_error("stream closed twice");
if (stream->stream_continues) {
Streams__close(stream->stream_continues);
stream->stream_continues = NULL;
}
stream->chars_capacity = -1; /* mark as closed */
if (stream->write_to_file)
{
#line 658 "inweb/foundation-module/Chapter 2/Streams.w"
if ((ferror(stream->write_to_file)) || (fclose(stream->write_to_file) == EOF))
Errors__fatal("The host computer reported an error trying to write a text file");
if (stream != DL)
LOGIF(TEXT_FILES, "Text file '%f' (%s): %d characters written\n",
stream->file_written,
(stream->stream_flags & FILE_ENCODING_UTF8_STRF)?"UTF8":"ISO",
stream->chars_written);
stream->write_to_file = NULL;
}
#line 647 "inweb/foundation-module/Chapter 2/Streams.w"
;
if (stream->write_to_memory)
{
#line 677 "inweb/foundation-module/Chapter 2/Streams.w"
if ((stream->stream_flags) & MALLOCED_STRF) {
wchar_t *mem = stream->write_to_memory;
stream->write_to_memory = NULL;
Memory__I7_free(mem, STREAM_MREASON, stream->chars_capacity*((int) sizeof(wchar_t)));
stream = NULL;
}
}
#line 648 "inweb/foundation-module/Chapter 2/Streams.w"
;
}
#line 688 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__putc(int c_int, text_stream *stream) {
unsigned int c;
if (c_int >= 0) c = (unsigned int) c_int; else c = (unsigned int) (c_int + 256);
if (stream == NULL) return;
text_stream *first_stream = stream;
if (c != '\n')
{
#line 748 "inweb/foundation-module/Chapter 2/Streams.w"
if (first_stream->stream_flags & INDENT_PENDING_STRF) {
first_stream->stream_flags -= INDENT_PENDING_STRF;
int L = (first_stream->stream_flags & INDENTATION_MASK_STRF)/INDENTATION_BASE_STRF;
for (int i=0; i<L; i++) {
Streams__putc(' ', first_stream); Streams__putc(' ', first_stream);
Streams__putc(' ', first_stream); Streams__putc(' ', first_stream);
}
}
}
#line 693 "inweb/foundation-module/Chapter 2/Streams.w"
;
if (stream->stream_flags & READ_ONLY_STRF) internal_error("modifying read-only stream");
if ((stream->stream_flags) & USES_XML_ESCAPES_STRF) {
switch(c) {
case NEWLINE_IN_STRING: Streams__literal(stream, "<br>"); return;
case '&': Streams__literal(stream, "&amp;"); return;
case '<': Streams__literal(stream, "&lt;"); return;
case '>': Streams__literal(stream, "&gt;"); return;
}
}
while (stream->stream_continues) stream = stream->stream_continues;
{
#line 775 "inweb/foundation-module/Chapter 2/Streams.w"
if (stream->chars_written + SPACE_AT_END_OF_STREAM >= stream->chars_capacity) {
if (stream->write_to_file) return; /* write nothing further */
if (stream->write_to_memory) {
int offset = (32 + 2*(stream->chars_capacity))*((int) sizeof(wchar_t));
int needed = offset + ((int) sizeof(text_stream)) + 32;
void *further_allocation = Memory__malloc(needed, STREAM_MREASON);
if (further_allocation == NULL) Errors__fatal("Out of memory");
text_stream *continuation = (text_stream *) (further_allocation + offset);
Streams__initialise(continuation, FOR_CO_STRF);
continuation->write_to_memory = further_allocation;
continuation->chars_capacity = 2*stream->chars_capacity;
(continuation->write_to_memory)[0] = 0;
stream->stream_continues = continuation;
stream = continuation;
}
}
}
#line 704 "inweb/foundation-module/Chapter 2/Streams.w"
;
if (stream->write_to_file) {
if (stream->stream_flags & FILE_ENCODING_UTF8_STRF)
{
#line 738 "inweb/foundation-module/Chapter 2/Streams.w"
if (c >= 0x800) {
fputc(0xE0 + (c >> 12), stream->write_to_file);
fputc(0x80 + ((c >> 6) & 0x3f), stream->write_to_file);
fputc(0x80 + (c & 0x3f), stream->write_to_file);
} else if (c >= 0x80) {
fputc(0xC0 + (c >> 6), stream->write_to_file);
fputc(0x80 + (c & 0x3f), stream->write_to_file);
} else fputc((int) c, stream->write_to_file);
}
#line 707 "inweb/foundation-module/Chapter 2/Streams.w"
else if (stream->stream_flags & FILE_ENCODING_ISO_STRF) {
if (c >= 0x100) c = '?';
fputc((int) c, stream->write_to_file);
} else internal_error("stream has unknown text encoding");
if (stream->stream_flags & ECHO_BYTES_STRF) {
fputc(' ', stream->write_to_file);
fputc('0'+(c/100), stream->write_to_file);
fputc('0'+(c%100)/10, stream->write_to_file);
fputc('0'+(c%10), stream->write_to_file);
if (stream->stream_flags & FILE_ENCODING_UTF8_STRF)
fputc('u', stream->write_to_file);
if (stream->stream_flags & FILE_ENCODING_ISO_STRF)
fputc('i', stream->write_to_file);
fputc(' ', stream->write_to_file);
}
} else if (stream->write_to_memory) {
if ((c >= 0x0300) && (c <= 0x036F) && (stream->chars_written > 0)) {
c = (unsigned int) Characters__combine_accent(
(int) c, (stream->write_to_memory)[stream->chars_written - 1]);
stream->chars_written--;
}
(stream->write_to_memory)[stream->chars_written] = (wchar_t) c;
}
if (c == '\n') first_stream->stream_flags |= INDENT_PENDING_STRF;
stream->chars_written++;
}
#line 795 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__literal(text_stream *stream, char *p) {
if (stream == NULL) return;
int i, x = ((stream->stream_flags) & USES_XML_ESCAPES_STRF);
if (x) stream->stream_flags -= USES_XML_ESCAPES_STRF;
for (i=0; p[i]; i++) Streams__putc((int) p[i], stream);
if (x) stream->stream_flags += USES_XML_ESCAPES_STRF;
}
#line 809 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__indent(text_stream *stream) {
if (stream == NULL) return;
stream->stream_flags += INDENTATION_BASE_STRF;
}
void Streams__outdent(text_stream *stream) {
if (stream == NULL) return;
if ((stream->stream_flags & INDENTATION_MASK_STRF) == 0) {
if (Errors__have_occurred() == FALSE) internal_error("stream indentation negative");
return;
}
stream->stream_flags -= INDENTATION_BASE_STRF;
}
void Streams__set_indentation(text_stream *stream, int N) {
if (stream == NULL) return;
int B = stream->stream_flags & INDENTATION_MASK_STRF;
stream->stream_flags -= B;
stream->stream_flags += N*INDENTATION_BASE_STRF;
}
#line 837 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__get_position(text_stream *stream) {
int t = 0;
while (stream) {
t += stream->chars_written;
stream = stream->stream_continues;
}
return t;
}
#line 851 "inweb/foundation-module/Chapter 2/Streams.w"
int Streams__latest(text_stream *stream) {
if (stream == NULL) return 0;
if (stream->write_to_file) internal_error("stream_latest on file stream");
while ((stream->stream_continues) && (stream->stream_continues->chars_written > 0))
stream = stream->stream_continues;
if (stream->write_to_memory) {
if (stream->chars_written > 0)
return (int) ((stream->write_to_memory)[stream->chars_written - 1]);
}
return 0;
}
#line 867 "inweb/foundation-module/Chapter 2/Streams.w"
wchar_t Streams__get_char_at_index(text_stream *stream, int position) {
if (stream == NULL) internal_error("examining null stream");
if (stream->write_to_file) internal_error("examining file stream");
while (position >= stream->chars_written) {
position = position - stream->chars_written;
stream = stream->stream_continues;
if (stream == NULL) return 0;
}
if (stream->write_to_memory == NULL) return 0;
return (stream->write_to_memory)[position];
}
void Streams__put_char_at_index(text_stream *stream, int position, wchar_t C) {
if (stream == NULL) internal_error("modifying null stream");
if (stream->write_to_file) internal_error("modifying file stream");
if (stream->stream_flags & READ_ONLY_STRF) internal_error("modifying read-only stream");
while (position >= stream->chars_written) {
position = position - stream->chars_written;
stream = stream->stream_continues;
if (stream == NULL) internal_error("overrun memory stream");
}
(stream->write_to_memory)[position] = C;
if (C == 0) {
stream->chars_written = position;
if (stream->stream_continues) {
Streams__close(stream->stream_continues);
stream->stream_continues = NULL;
}
}
}
#line 905 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__set_position(text_stream *stream, int position) {
if (stream == NULL) return;
if (position < 0) position = 0; /* to simplify the implementation of backspacing */
if (stream->write_to_file) internal_error("stream_set_position on file stream");
if (stream->stream_flags & READ_ONLY_STRF) internal_error("modifying read-only stream");
if (stream->write_to_memory) {
while (position > stream->chars_written) {
position = position - stream->chars_written;
stream = stream->stream_continues;
if (stream == NULL) internal_error("can't set position forwards");
}
stream->chars_written = position;
(stream->write_to_memory)[stream->chars_written] = 0;
if (stream->stream_continues) {
Streams__close(stream->stream_continues);
stream->stream_continues = NULL;
}
}
}
#line 929 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__copy(text_stream *to, text_stream *from) {
if ((from == NULL) || (to == NULL)) return;
if (from == to) internal_error("tried to copy a stream to itself");
if (from->write_to_file) internal_error("stream_copy from file stream");
if (from->write_to_memory) {
for (int i=0; i<from->chars_written; i++) {
int c = (int) ((from->write_to_memory)[i]);
Streams__putc(c, to);
}
if (from->stream_continues) Streams__copy(to, from->stream_continues);
}
}
#line 946 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__writer(OUTPUT_STREAM, char *format_string, void *vS) {
text_stream *S = (text_stream *) vS;
Streams__copy(OUT, S);
}
#line 37 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
int escapes_registered = FALSE;
int escapes_category[2][128]; /* one of the |*_ECAT| values above */
void *the_escapes[2][128]; /* the function to call to implement this */
#line 45 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
#ifdef WORDS_MODULE
typedef void (*writer_function_W)(text_stream *, char *, wording);
typedef void (*log_function_W)(text_stream *, wording);
#endif
#line 51 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__log_escape_usage(void) {
for (int cat = 0; cat < 2; cat++) {
char *alphanum = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
LOG("Vacant escapes: %s: ", (cat == 0)?"%":"$");
for (int i=0; alphanum[i]; i++)
if (escapes_category[cat][(int) alphanum[i]] == VACANT_ECAT)
LOG("%c", alphanum[i]);
else
LOG(".");
LOG("\n");
}
}
#line 67 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__register_writer(int esc, void (*f)(text_stream *, char *, void *)) {
Writers__register_writer_p(0, esc, (void *) f, POINTER_ECAT);
}
void Writers__register_logger(int esc, void (*f)(text_stream *, void *)) {
Writers__register_writer_p(1, esc, (void *) f, POINTER_ECAT);
}
void Writers__register_writer_I(int esc, void (*f)(text_stream *, char *, int)) {
Writers__register_writer_p(0, esc, (void *) f, INTSIZED_ECAT);
}
void Writers__register_logger_I(int esc, void (*f)(text_stream *, int)) {
Writers__register_writer_p(1, esc, (void *) f, INTSIZED_ECAT);
}
#ifdef WORDS_MODULE
#define Writers__register_writer_W(esc, f) Writers__register_writer_p(0, esc, (void *) f, WORDING_ECAT);
#define Writers__register_logger_W(esc, f) Writers__register_writer_p(1, esc, (void *) f, WORDING_ECAT);
#endif
#line 87 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__register_writer_p(int set, int esc, void *f, int cat) {
if (escapes_registered == FALSE)
{
#line 108 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
escapes_registered = TRUE;
for (int e=0; e<2; e++)
for (int i=0; i<128; i++) {
the_escapes[e][i] = NULL; escapes_category[e][i] = VACANT_ECAT;
}
escapes_category[0]['c'] = DIRECT_ECAT;
escapes_category[0]['d'] = DIRECT_ECAT;
escapes_category[0]['g'] = DIRECT_ECAT;
escapes_category[0]['i'] = DIRECT_ECAT;
escapes_category[0]['s'] = DIRECT_ECAT;
escapes_category[0]['w'] = DIRECT_ECAT;
escapes_category[0]['x'] = DIRECT_ECAT;
escapes_category[0]['%'] = DIRECT_ECAT;
escapes_category[0]['$'] = DIRECT_ECAT;
escapes_category[1]['%'] = DIRECT_ECAT;
escapes_category[1]['$'] = DIRECT_ECAT;
}
#line 88 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
;
if ((esc < 0) || (esc >= 128) ||
((Characters__isalpha((wchar_t) esc) == FALSE) &&
(Characters__isdigit((wchar_t) esc) == FALSE)))
internal_error("nonalphabetic escape");
if (escapes_category[set][esc] != VACANT_ECAT) {
WRITE_TO(STDERR, "Clashing escape is %s%c\n", (set == 0)?"%":"$", esc);
internal_error("clash of escapes");
}
escapes_category[set][esc] = cat;
the_escapes[set][esc] = f;
}
#line 130 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
void Writers__printf(text_stream *stream, char *fmt, ...) {
va_list ap; /* the variable argument list signified by the dots */
char *p;
if (stream == NULL) return;
va_start(ap, fmt); /* macro to begin variable argument processing */
for (p = fmt; *p; p++) {
switch (*p) {
case '%': {
int set = 0;
{
#line 163 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
char format_string[8];
int esc_number = ' ';
int i = 0;
format_string[i++] = *(p++);
while (*p) {
format_string[i++] = *p;
if ((islower(*p)) || (isupper(*p)) || ((set == 1) && (isdigit(*p))) ||
(*p == '%')) esc_number = (int) *p;
p++;
if ((esc_number != ' ') || (i==6)) break;
}
format_string[i] = 0; p--;
if ((esc_number<0) || (esc_number > 255)) esc_number = 0;
switch (escapes_category[set][esc_number]) {
case POINTER_ECAT: {
if (set == 0) {
writer_function f = (writer_function) the_escapes[0][esc_number];
void *q = va_arg(ap, void *);
(*f)(stream, format_string+1, q);
} else {
log_function f = (log_function) the_escapes[1][esc_number];
void *q = va_arg(ap, void *);
(*f)(stream, q);
}
break;
}
case INTSIZED_ECAT: {
if (set == 0) {
writer_function_I f = (writer_function_I) the_escapes[0][esc_number];
int N = va_arg(ap, int);
(*f)(stream, format_string+1, N);
} else {
log_function_I f = (log_function_I) the_escapes[1][esc_number];
int N = va_arg(ap, int);
(*f)(stream, N);
}
break;
}
case WORDING_ECAT: {
#ifdef WORDS_MODULE
if (set == 0) {
writer_function_W f = (writer_function_W) the_escapes[0][esc_number];
wording W = va_arg(ap, wording);
(*f)(stream, format_string+1, W);
} else {
log_function_W f = (log_function_W) the_escapes[1][esc_number];
wording W = va_arg(ap, wording);
(*f)(stream, W);
}
#endif
break;
}
case DIRECT_ECAT:
{
#line 237 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
switch (esc_number) {
case 'c': case 'd': case 'i': case 'x': { /* |char| is promoted to |int| in variable arguments */
int ival = va_arg(ap, int);
char temp[256];
if (snprintf(temp, 255, format_string, ival) >= 255) strcpy(temp, "?");
for (int j = 0; temp[j]; j++) Streams__putc(temp[j], stream);
break;
}
case 'g': {
double dval = va_arg(ap, double);
char temp[256];
if (snprintf(temp, 255, format_string, dval) >= 255) strcpy(temp, "?");
for (int j = 0; temp[j]; j++) Streams__putc(temp[j], stream);
break;
}
case 's':
for (char *sval = va_arg(ap, char *); *sval; sval++) Streams__putc(*sval, stream);
break;
case 'w': {
wchar_t *W = (wchar_t *) va_arg(ap, wchar_t *);
for (int j = 0; W[j]; j++) Streams__putc(W[j], stream);
break;
}
case '%': Streams__putc('%', stream); break;
case '$': Streams__putc('$', stream); break;
}
#pragma clang diagnostic pop
}
#line 215 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
; break;
case VACANT_ECAT:
WRITE_TO(STDERR, "*** Bad WRITE escape: <%s> ***\n", format_string);
internal_error("Unknown string escape");
break;
}
}
#line 138 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
;
break;
}
case '$': {
int set = 1;
if ((stream->stream_flags) & USES_LOG_ESCAPES_STRF)
{
#line 163 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
char format_string[8];
int esc_number = ' ';
int i = 0;
format_string[i++] = *(p++);
while (*p) {
format_string[i++] = *p;
if ((islower(*p)) || (isupper(*p)) || ((set == 1) && (isdigit(*p))) ||
(*p == '%')) esc_number = (int) *p;
p++;
if ((esc_number != ' ') || (i==6)) break;
}
format_string[i] = 0; p--;
if ((esc_number<0) || (esc_number > 255)) esc_number = 0;
switch (escapes_category[set][esc_number]) {
case POINTER_ECAT: {
if (set == 0) {
writer_function f = (writer_function) the_escapes[0][esc_number];
void *q = va_arg(ap, void *);
(*f)(stream, format_string+1, q);
} else {
log_function f = (log_function) the_escapes[1][esc_number];
void *q = va_arg(ap, void *);
(*f)(stream, q);
}
break;
}
case INTSIZED_ECAT: {
if (set == 0) {
writer_function_I f = (writer_function_I) the_escapes[0][esc_number];
int N = va_arg(ap, int);
(*f)(stream, format_string+1, N);
} else {
log_function_I f = (log_function_I) the_escapes[1][esc_number];
int N = va_arg(ap, int);
(*f)(stream, N);
}
break;
}
case WORDING_ECAT: {
#ifdef WORDS_MODULE
if (set == 0) {
writer_function_W f = (writer_function_W) the_escapes[0][esc_number];
wording W = va_arg(ap, wording);
(*f)(stream, format_string+1, W);
} else {
log_function_W f = (log_function_W) the_escapes[1][esc_number];
wording W = va_arg(ap, wording);
(*f)(stream, W);
}
#endif
break;
}
case DIRECT_ECAT:
{
#line 237 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
switch (esc_number) {
case 'c': case 'd': case 'i': case 'x': { /* |char| is promoted to |int| in variable arguments */
int ival = va_arg(ap, int);
char temp[256];
if (snprintf(temp, 255, format_string, ival) >= 255) strcpy(temp, "?");
for (int j = 0; temp[j]; j++) Streams__putc(temp[j], stream);
break;
}
case 'g': {
double dval = va_arg(ap, double);
char temp[256];
if (snprintf(temp, 255, format_string, dval) >= 255) strcpy(temp, "?");
for (int j = 0; temp[j]; j++) Streams__putc(temp[j], stream);
break;
}
case 's':
for (char *sval = va_arg(ap, char *); *sval; sval++) Streams__putc(*sval, stream);
break;
case 'w': {
wchar_t *W = (wchar_t *) va_arg(ap, wchar_t *);
for (int j = 0; W[j]; j++) Streams__putc(W[j], stream);
break;
}
case '%': Streams__putc('%', stream); break;
case '$': Streams__putc('$', stream); break;
}
#pragma clang diagnostic pop
}
#line 215 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
; break;
case VACANT_ECAT:
WRITE_TO(STDERR, "*** Bad WRITE escape: <%s> ***\n", format_string);
internal_error("Unknown string escape");
break;
}
}
#line 144 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
else Streams__putc('$', stream);
break;
}
case '"':
if (stream->stream_flags & USES_I6_ESCAPES_STRF)
Streams__putc('~', stream);
else Streams__putc(*p, stream);
break;
case '\n':
Streams__putc(*p, stream);
break;
default: Streams__putc(*p, stream); break;
}
}
va_end(ap); /* macro to end variable argument processing */
}
#line 31 "inweb/foundation-module/Chapter 2/Methods.w"
method_set *Methods__new_set(void) {
method_set *S = CREATE(method_set);
S->first_method = NULL;
return S;
}
#line 44 "inweb/foundation-module/Chapter 2/Methods.w"
#line 58 "inweb/foundation-module/Chapter 2/Methods.w"
INT_METHOD_TYPE(UNUSED_METHOD_ID_MTID, text_stream *example, int wont_be_used)
#line 75 "inweb/foundation-module/Chapter 2/Methods.w"
void Methods__add(method_set *S, int ID, void *function) {
method *M = CREATE(method);
M->method_id = ID;
M->method_function = function;
M->next_method = NULL;
if (S->first_method == NULL) S->first_method = M;
else {
method *existing = S->first_method;
while ((existing) && (existing->next_method)) existing = existing->next_method;
existing->next_method = M;
}
}
int Methods__provided(method_set *S, int ID) {
if (S == NULL) return FALSE;
for (method *M = S->first_method; M; M = M->next_method)
if (M->method_id == ID)
return TRUE;
return FALSE;
}
#line 23 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
#line 28 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
#line 30 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
linked_list *LinkedLists__new(void) {
linked_list *ll = CREATE(linked_list);
LinkedLists__empty(ll);
return ll;
}
void LinkedLists__empty(linked_list *ll) {
ll->linked_list_length = 0;
ll->early_items_used = 0;
ll->first_list_item = NULL;
ll->last_list_item = NULL;
}
#line 47 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void LinkedLists__add(linked_list *L, void *P, int to_end) {
if (L == NULL) internal_error("null list");
linked_list_item *item = NULL;
if (L->early_items_used < NO_LL_EARLY_ITEMS)
item = &(L->early_items[L->early_items_used++]);
else
item = CREATE(linked_list_item);
item->item_contents = P;
if (to_end) {
item->next_list_item = NULL;
if (L->last_list_item == NULL) {
L->first_list_item = item;
L->last_list_item = item;
} else {
L->last_list_item->next_list_item = item;
L->last_list_item = item;
}
} else {
item->next_list_item = L->first_list_item;
L->first_list_item = item;
if (L->last_list_item == NULL) L->last_list_item = item;
}
L->linked_list_length++;
}
#line 75 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void *LinkedLists__remove_from_front(linked_list *L) {
if (L == NULL) internal_error("null list");
linked_list_item *front = L->first_list_item;
if (front == NULL) internal_error("empty list can't have item 0 removed");
L->first_list_item = front->next_list_item;
if (L->first_list_item == NULL) L->last_list_item = NULL;
L->linked_list_length--;
return front->item_contents;
}
#line 88 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void *LinkedLists__delete(int N, linked_list *L) {
if (L == NULL) internal_error("null list");
if ((N < 0) || (N >= L->linked_list_length)) internal_error("index not valid");
if (N == 0) return LinkedLists__remove_from_front(L);
for (linked_list_item *item = L->first_list_item; item; item = item->next_list_item) {
N--;
if (N == 0) {
if (L->last_list_item == item->next_list_item) L->last_list_item = item;
void *contents_deleted = item->next_list_item->item_contents;
item->next_list_item = item->next_list_item->next_list_item;
L->linked_list_length--;
return contents_deleted;
}
}
internal_error("index not found");
return NULL;
}
#line 112 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
void LinkedLists__insert(linked_list *L, int N, void *P) {
if (N <= 0) LinkedLists__add(L, P, FALSE);
else {
linked_list_item *prev = NULL;
for (linked_list_item *I = L->first_list_item; I; I = I->next_list_item) {
if (N-- == 0) break;
prev = I;
}
if (prev == NULL) LinkedLists__add(L, P, FALSE);
else {
linked_list_item *item = NULL;
if (L->early_items_used < NO_LL_EARLY_ITEMS)
item = &(L->early_items[L->early_items_used++]);
else
item = CREATE(linked_list_item);
item->item_contents = P;
linked_list_item *subs = prev->next_list_item;
prev->next_list_item = item;
item->next_list_item = subs;
L->linked_list_length++;
}
}
}
#line 140 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
int LinkedLists__len(linked_list *L) {
return L?(L->linked_list_length):0;
}
linked_list_item *LinkedLists__first(linked_list *L) {
return L?(L->first_list_item):NULL;
}
void *LinkedLists__entry(int N, linked_list *L) {
if ((N < 0) || (L == NULL) || (N >= L->linked_list_length)) return NULL;
for (linked_list_item *I = L->first_list_item; I; I = I->next_list_item)
if (N-- == 0)
return I->item_contents;
return NULL;
}
void LinkedLists__set_entry(int N, linked_list *L, void *P) {
if ((N < 0) || (L == NULL) || (N >= L->linked_list_length)) return;
for (linked_list_item *I = L->first_list_item; I; I = I->next_list_item)
if (N-- == 0) {
I->item_contents = P; return;
}
}
linked_list_item *LinkedLists__last(linked_list *L) {
return L?(L->last_list_item):NULL;
}
linked_list_item *LinkedLists__next(linked_list_item *I) {
return I?(I->next_list_item):NULL;
}
void *LinkedLists__content(linked_list_item *I) {
return I?(I->item_contents):NULL;
}
#line 20 "inweb/foundation-module/Chapter 2/Dictionaries.w"
#line 27 "inweb/foundation-module/Chapter 2/Dictionaries.w"
#line 33 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dictionary *Dictionaries__new(int S, int textual) {
if (S < 2) internal_error("dictionary too small");
dictionary *D = CREATE(dictionary);
D->textual = textual;
D->hash_table_size = S;
D->no_entries = 0;
D->hash_table = Memory__calloc(S, sizeof(dict_entry), DICTIONARY_MREASON);
for (int i=0; i<S; i++) {
D->hash_table[i].vacant = TRUE;
D->hash_table[i].value = NULL;
D->hash_table[i].next_in_entry = NULL;
}
return D;
}
#line 51 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__log(OUTPUT_STREAM, dictionary *D) {
WRITE("Dictionary:\n"); INDENT;
for (int i=0; i<D->hash_table_size; i++) {
WRITE("Slot %02d:", i);
for (dict_entry *E = &(D->hash_table[i]); E; E = E->next_in_entry)
if (E->vacant) WRITE(" vacant");
else if (D->textual) WRITE(" %S='%S'", E->key, E->value);
else WRITE(" %S=<binary>", E->key);
WRITE("\n");
}
OUTDENT;
}
#line 71 "inweb/foundation-module/Chapter 2/Dictionaries.w"
int Dictionaries__hash(text_stream *K, int N) {
unsigned int hash = 0;
LOOP_THROUGH_TEXT(P, K)
hash = 16339*hash + ((unsigned int) Str__get(P));
return (int) (hash % ((unsigned int) N));
}
#line 85 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry *Dictionaries__find(dictionary *D, text_stream *K) {
return Dictionaries__find_p(D, K, 0);
}
dict_entry *Dictionaries__create(dictionary *D, text_stream *K) {
return Dictionaries__find_p(D, K, 1);
}
void Dictionaries__destroy(dictionary *D, text_stream *K) {
Dictionaries__find_p(D, K, -1);
}
#line 100 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry *Dictionaries__find_literal(dictionary *D, wchar_t *lit) {
TEMPORARY_TEXT(K)
WRITE_TO(K, "%w", lit);
dict_entry *E = Dictionaries__find(D, K);
DISCARD_TEXT(K)
return E;
}
dict_entry *Dictionaries__create_literal(dictionary *D, wchar_t *lit) {
TEMPORARY_TEXT(K)
WRITE_TO(K, "%w", lit);
dict_entry *E = Dictionaries__create(D, K);
DISCARD_TEXT(K)
return E;
}
void Dictionaries__destroy_literal(dictionary *D, wchar_t *lit) {
TEMPORARY_TEXT(K)
WRITE_TO(K, "%w", lit);
Dictionaries__destroy(D, K);
DISCARD_TEXT(K)
}
#line 125 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry *Dictionaries__find_p(dictionary *D, text_stream *K, int change) {
if (D == NULL)
{
#line 134 "inweb/foundation-module/Chapter 2/Dictionaries.w"
if (change == 0) return NULL;
internal_error("tried to create or destroy in a null dictionary");
}
#line 126 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
if (change == 1)
{
#line 143 "inweb/foundation-module/Chapter 2/Dictionaries.w"
if (D->no_entries > D->hash_table_size) {
dictionary *D2 = Dictionaries__new(2*D->hash_table_size, D->textual);
for (int i=0; i<D->hash_table_size; i++)
for (dict_entry *E = &(D->hash_table[i]); E; E = E->next_in_entry)
if (E->vacant == FALSE) {
dict_entry *E2 = Dictionaries__find_p(D2, E->key, 1);
E2->value = E->value;
}
Memory__I7_free(D->hash_table, DICTIONARY_MREASON,
D->hash_table_size*((int) sizeof(dict_entry)));
D->hash_table_size = D2->hash_table_size;
D->hash_table = D2->hash_table;
}
}
#line 127 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
{
#line 158 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry *last_E = NULL;
for (dict_entry *E = &(D->hash_table[Dictionaries__hash(K, D->hash_table_size)]);
E; E = E->next_in_entry) {
last_E = E;
if (E->vacant) {
if (change == 1) {
{
#line 183 "inweb/foundation-module/Chapter 2/Dictionaries.w"
E->vacant = FALSE;
if (D->textual) E->value = Str__new(); else E->value = NULL;
E->key = Str__duplicate(K);
D->no_entries++;
}
#line 163 "inweb/foundation-module/Chapter 2/Dictionaries.w"
; return E; }
} else {
if (Str__eq(K, E->key)) {
if (change == -1)
{
#line 193 "inweb/foundation-module/Chapter 2/Dictionaries.w"
E->vacant = TRUE; D->no_entries--;
if ((D->textual) && (E->value)) Str__dispose_of(E->value);
E->value = NULL;
}
#line 166 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
return E;
}
}
}
if (change == 1) {
dict_entry *E = CREATE(dict_entry);
{
#line 183 "inweb/foundation-module/Chapter 2/Dictionaries.w"
E->vacant = FALSE;
if (D->textual) E->value = Str__new(); else E->value = NULL;
E->key = Str__duplicate(K);
D->no_entries++;
}
#line 173 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
last_E->next_in_entry = E;
return E;
}
return NULL;
}
#line 128 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
}
#line 202 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void *Dictionaries__value_for_entry(dict_entry *de) {
if (de) return de->value;
return NULL;
}
void *Dictionaries__read_value(dictionary *D, text_stream *key) {
if (D == NULL) return NULL;
if (D->textual) internal_error("textual dictionary accessed as pointy");
dict_entry *E = Dictionaries__find(D, key);
if (E == NULL) internal_error("read null dictionary entry");
if (E->vacant) internal_error("read vacant dictionary entry");
return E->value;
}
void *Dictionaries__read_value_literal(dictionary *D, wchar_t *key) {
if (D == NULL) return NULL;
if (D->textual) internal_error("textual dictionary accessed as pointy");
dict_entry *E = Dictionaries__find_literal(D, key);
if (E == NULL) internal_error("read null dictionary entry");
if (E->vacant) internal_error("read vacant dictionary entry");
return E->value;
}
void Dictionaries__write_value(dictionary *D, text_stream *key, void *val) {
if (D == NULL) internal_error("wrote to null dictionary");
if (D->textual) internal_error("textual dictionary accessed as pointy");
dict_entry *E = Dictionaries__find(D, key);
if (E == NULL) internal_error("wrote null dictionary entry");
if (E->vacant) internal_error("wrote vacant dictionary entry");
E->value = val;
}
void Dictionaries__write_value_literal(dictionary *D, wchar_t *key, void *val) {
if (D == NULL) internal_error("wrote to null dictionary");
if (D->textual) internal_error("textual dictionary accessed as pointy");
dict_entry *E = Dictionaries__find_literal(D, key);
if (E == NULL) internal_error("wrote null dictionary entry");
if (E->vacant) internal_error("wrote vacant dictionary entry");
E->value = val;
}
#line 245 "inweb/foundation-module/Chapter 2/Dictionaries.w"
text_stream *Dictionaries__create_text(dictionary *D, text_stream *key) {
if (D == NULL) internal_error("wrote to null dictionary");
if (D->textual == FALSE) internal_error("pointy dictionary accessed as textual");
dict_entry *E = Dictionaries__create(D, key);
return (text_stream *) E->value;
}
text_stream *Dictionaries__create_text_literal(dictionary *D, wchar_t *lit) {
if (D == NULL) internal_error("wrote to null dictionary");
if (D->textual == FALSE) internal_error("pointy dictionary accessed as textual");
dict_entry *E = Dictionaries__create_literal(D, lit);
return (text_stream *) E->value;
}
#line 262 "inweb/foundation-module/Chapter 2/Dictionaries.w"
text_stream *Dictionaries__get_text(dictionary *D, text_stream *key) {
if (D == NULL) return NULL;
if (D->textual == FALSE) internal_error("pointy dictionary accessed as textual");
dict_entry *E = Dictionaries__find(D, key);
if (E == NULL) return NULL;
return (text_stream *) E->value;
}
text_stream *Dictionaries__get_text_literal(dictionary *D, wchar_t *lit) {
if (D == NULL) return NULL;
if (D->textual == FALSE) internal_error("pointy dictionary accessed as textual");
dict_entry *E = Dictionaries__find_literal(D, lit);
if (E == NULL) return NULL;
return (text_stream *) E->value;
}
#line 283 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__dispose_of(dictionary *D) {
if (D->textual)
for (int i=0; i<D->hash_table_size; i++)
for (dict_entry *E = &(D->hash_table[i]); E; E = E->next_in_entry)
if (E->vacant == FALSE)
Str__dispose_of(E->value);
Memory__I7_free(D->hash_table, DICTIONARY_MREASON, D->hash_table_size*((int) sizeof(dict_entry)));
D->hash_table = NULL;
}
#line 16 "inweb/foundation-module/Chapter 2/Trees.w"
#line 18 "inweb/foundation-module/Chapter 2/Trees.w"
heterogeneous_tree *Trees__new(tree_type *type) {
heterogeneous_tree *T = CREATE(heterogeneous_tree);
T->type = type;
T->root = NULL;
return T;
}
#line 35 "inweb/foundation-module/Chapter 2/Trees.w"
#line 40 "inweb/foundation-module/Chapter 2/Trees.w"
tree_node *Trees__new_node(heterogeneous_tree *T, tree_node_type *type, general_pointer wrapping) {
if (T == NULL) internal_error("no tree");
if (wrapping.run_time_type_code == -1)
internal_error("no reference given");
if (type->required_CLASS >= 0)
if (wrapping.run_time_type_code != type->required_CLASS)
internal_error("wrong reference type");
tree_node *N = CREATE(tree_node);
N->content = wrapping;
N->owner = T;
N->type = type;
N->parent = NULL;
N->child = NULL;
N->next = NULL;
return N;
}
#line 61 "inweb/foundation-module/Chapter 2/Trees.w"
tree_node *Trees__new_child(tree_node *of, tree_node_type *type, general_pointer wrapping) {
tree_node *N = Trees__new_node(of->owner, type, wrapping);
Trees__make_child(N, of);
return N;
}
#line 79 "inweb/foundation-module/Chapter 2/Trees.w"
#line 81 "inweb/foundation-module/Chapter 2/Trees.w"
tree_type *Trees__new_type(text_stream *name, int (*verifier)(tree_node *)) {
tree_type *T = CREATE(tree_type);
T->name = Str__duplicate(name);
T->verify_root = verifier;
return T;
}
#line 98 "inweb/foundation-module/Chapter 2/Trees.w"
#line 100 "inweb/foundation-module/Chapter 2/Trees.w"
tree_node_type *Trees__new_node_type(text_stream *name, int req,
int (*verifier)(tree_node *)) {
tree_node_type *NT = CREATE(tree_node_type);
NT->node_type_name = Str__duplicate(name);
NT->required_CLASS = req;
NT->verify_children = verifier;
return NT;
}
#line 114 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__make_root(heterogeneous_tree *T, tree_node *N) {
if (T == NULL) internal_error("no tree");
if (N == NULL) internal_error("no node");
N->owner = T;
T->root = N;
N->parent = NULL;
N->next = NULL;
if (T->type->verify_root)
if ((*(T->type->verify_root))(N) == FALSE)
internal_error("disallowed node as root");
}
void Trees__remove_root(heterogeneous_tree *T) {
if (T == NULL) internal_error("no tree");
T->root = NULL;
}
#line 134 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__make_child(tree_node *N, tree_node *of) {
if (N == NULL) internal_error("no node");
if (of == NULL) internal_error("no node");
if (N == N->owner->root) Trees__remove_root(N->owner);
N->owner = of->owner;
N->parent = of;
N->next = NULL;
if (of->child == NULL)
of->child = N;
else
for (tree_node *S = of->child; S; S = S->next)
if (S->next == NULL) {
S->next = N; break;
}
Trees__verify_children(of);
}
void Trees__make_eldest_child(tree_node *N, tree_node *of) {
if (N == NULL) internal_error("no node");
if (of == NULL) internal_error("no node");
if (N == N->owner->root) Trees__remove_root(N->owner);
N->owner = of->owner;
N->parent = of;
N->next = of->child;
of->child = N;
Trees__verify_children(of);
}
void Trees__make_sibling(tree_node *N, tree_node *of) {
if (N == NULL) internal_error("no node");
if (of == NULL) internal_error("no node");
if (N == N->owner->root) Trees__remove_root(N->owner);
if (of == of->owner->root)
internal_error("nodes cannot be siblings of the root");
N->owner = of->owner;
N->parent = of->parent;
N->next = of->next;
of->next = N;
if (of->parent) Trees__verify_children(of->parent);
}
#line 179 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__remove(tree_node *N) {
if (N == NULL) internal_error("no node");
if (N == N->owner->root) { Trees__remove_root(N->owner); return; }
tree_node *p = N->parent;
if (N->parent->child == N)
N->parent->child = N->next;
else
for (tree_node *S = N->parent->child; S; S = S->next)
if (S->next == N)
S->next = N->next;
N->parent = NULL;
N->next = NULL;
if (p) Trees__verify_children(p);
}
int Trees__verify_children(tree_node *N) {
if (N == NULL) internal_error("no node");
if (N->type->verify_children)
return (*(N->type->verify_children))(N);
return TRUE;
}
#line 210 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__traverse_tree(heterogeneous_tree *T,
int (*visitor)(tree_node *, void *, int L), void *state) {
if (T == NULL) internal_error("no tree");
Trees__traverse_from(T->root, visitor, state, 0);
}
void Trees__traverse_from(tree_node *N,
int (*visitor)(tree_node *, void *, int L), void *state, int L) {
if (N)
if ((*visitor)(N, state, L))
Trees__traverse(N->child, visitor, state, L+1);
}
void Trees__traverse(tree_node *N,
int (*visitor)(tree_node *, void *, int L), void *state, int L) {
for (tree_node *M = N; M; M = M->next)
if ((*visitor)(M, state, L))
Trees__traverse(M->child, visitor, state, L+1);
}
#line 233 "inweb/foundation-module/Chapter 2/Trees.w"
void Trees__prune_tree(heterogeneous_tree *T,
int (*visitor)(tree_node *, void *), void *state) {
if (T == NULL) internal_error("no tree");
Trees__prune_from(T->root, visitor, state);
}
void Trees__prune_from(tree_node *N,
int (*visitor)(tree_node *, void *), void *state) {
if (N) {
if ((*visitor)(N, state))
Trees__remove(N);
else
Trees__prune(N->child, visitor, state);
}
}
void Trees__prune(tree_node *N,
int (*visitor)(tree_node *, void *), void *state) {
for (tree_node *M = N, *next_M = N?(N->next):NULL; M; M = next_M, next_M = M?(M->next):NULL)
if ((*visitor)(M, state))
Trees__remove(M);
else
Trees__prune(M->child, visitor, state);
}
#line 10 "inweb/foundation-module/Chapter 3/Error Messages.w"
int (*errors_handler)(text_stream *, int) = NULL;
void (*internal_errors_handler)(void *, char *, char *, int) = NULL;
void Errors__set_handler(int (*f)(text_stream *, int)) {
errors_handler = f;
}
void Errors__set_internal_handler(void (*f)(void *, char *, char *, int)) {
internal_errors_handler = f;
}
int problem_count = 0;
int Errors__have_occurred(void) {
if (problem_count > 0) return TRUE;
return FALSE;
}
void Errors__issue(text_stream *message, int fatality) {
STREAM_FLUSH(STDOUT);
int rv = TRUE;
if (errors_handler) rv = (*errors_handler)(message, fatality);
if (rv) WRITE_TO(STDERR, "%S", message);
STREAM_FLUSH(STDERR);
if (fatality) Errors__die(); else problem_count++;
}
#line 43 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__fatal(char *message) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: fatal error: %s\n", PROGRAM_NAME, message);
Errors__issue(ERM, TRUE);
DISCARD_TEXT(ERM)
}
void Errors__fatal_with_C_string(char *message, char *parameter) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: fatal error: ", PROGRAM_NAME);
WRITE_TO(ERM, message, parameter);
WRITE_TO(ERM, "\n");
Errors__issue(ERM, TRUE);
DISCARD_TEXT(ERM)
}
void Errors__fatal_with_text(char *message, text_stream *parameter) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: fatal error: ", PROGRAM_NAME);
WRITE_TO(ERM, message, parameter);
WRITE_TO(ERM, "\n");
Errors__issue(ERM, TRUE);
DISCARD_TEXT(ERM)
}
void Errors__fatal_with_file(char *message, filename *F) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: fatal error: %s: %f\n", PROGRAM_NAME, message, F);
Errors__issue(ERM, TRUE);
DISCARD_TEXT(ERM)
}
void Errors__fatal_with_path(char *message, pathname *P) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: fatal error: %s: %p\n", PROGRAM_NAME, message, P);
Errors__issue(ERM, TRUE);
DISCARD_TEXT(ERM)
}
#line 90 "inweb/foundation-module/Chapter 3/Error Messages.w"
_Noreturn
void Errors__internal_error_handler(void *p, char *message, char *f, int lc) {
if (internal_errors_handler)
(*internal_errors_handler)(p, message, f, lc);
else
Errors__fatal_with_C_string("internal error (%s)", message);
exit(1); /* redundant but needed to remove compiler warning in clang */
}
#line 105 "inweb/foundation-module/Chapter 3/Error Messages.w"
int debugger_mode = FALSE;
void Errors__enter_debugger_mode(void) {
debugger_mode = TRUE;
printf("(Debugger mode enabled: will crash on fatal errors)\n");
}
void Errors__die(void) { /* as void as it gets */
if (DL) STREAM_FLUSH(DL);
if (debugger_mode) {
WRITE_TO(STDERR, "(crashing intentionally to allow backtrace)\n");
int to_deliberately_crash = 0;
printf("%d", 1/to_deliberately_crash);
}
/* on a fatal exit, memory isn't freed, because that causes threading problems */
exit(2);
}
#line 127 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__nowhere(char *message) {
Errors__in_text_file(message, NULL);
}
void Errors__in_text_file(char *message, text_file_position *here) {
if (here)
Errors__at_position(message, here->text_file_filename, here->line_count);
else
Errors__at_position(message, NULL, 0);
}
void Errors__in_text_file_S(text_stream *message, text_file_position *here) {
if (here)
Errors__at_position_S(message, here->text_file_filename, here->line_count);
else
Errors__at_position_S(message, NULL, 0);
}
#line 148 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__at_position(char *message, filename *file, int line) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: ", PROGRAM_NAME);
if (file) WRITE_TO(ERM, "%f, line %d: ", file, line);
WRITE_TO(ERM, "%s\n", message);
Errors__issue(ERM, FALSE);
DISCARD_TEXT(ERM)
}
void Errors__at_position_S(text_stream *message, filename *file, int line) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: ", PROGRAM_NAME);
if (file) WRITE_TO(ERM, "%f, line %d: ", file, line);
WRITE_TO(ERM, "%S\n", message);
Errors__issue(ERM, FALSE);
DISCARD_TEXT(ERM)
}
#line 169 "inweb/foundation-module/Chapter 3/Error Messages.w"
void Errors__with_file(char *message, filename *F) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: %f: %s\n", PROGRAM_NAME, F, message);
Errors__issue(ERM, FALSE);
DISCARD_TEXT(ERM)
}
void Errors__with_text(char *message, text_stream *T) {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "%s: ", PROGRAM_NAME);
WRITE_TO(ERM, message, T);
WRITE_TO(ERM, "\n");
Errors__issue(ERM, FALSE);
DISCARD_TEXT(ERM)
}
#line 50 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
#line 55 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
dictionary *cls_dictionary = NULL;
#line 63 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int current_switch_group = -1;
text_stream *switch_group_names[NO_DEFINED_CLSG_VALUES+1];
void CommandLine__begin_group(int id, text_stream *name) {
if (current_switch_group == -1)
for (int i=0; i<=NO_DEFINED_CLSG_VALUES; i++) switch_group_names[i] = NULL;
current_switch_group = id;
switch_group_names[id] = name;
}
void CommandLine__end_group(void) {
current_switch_group = NO_CLSG;
}
command_line_switch *CommandLine__declare_switch(int id,
wchar_t *name_literal, int val, wchar_t *help_literal) {
return CommandLine__declare_switch_p(id,
Str__new_from_wide_string(name_literal), val,
Str__new_from_wide_string(help_literal));
}
command_line_switch *CommandLine__declare_switch_p(int id,
text_stream *name, int val, text_stream *help_literal) {
if (current_switch_group == -1) {
current_switch_group = NO_CLSG;
for (int i=0; i<=NO_DEFINED_CLSG_VALUES; i++) switch_group_names[i] = NULL;
}
if (cls_dictionary == NULL) cls_dictionary = Dictionaries__new(16, FALSE);
command_line_switch *cls = CREATE(command_line_switch);
cls->switch_name = name;
{
#line 107 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
cls->switch_sort_name = Str__duplicate(name);
if (Str__begins_with_wide_string(name, L"no-")) {
Str__delete_n_characters(cls->switch_sort_name, 3);
WRITE_TO(cls->switch_sort_name, "_");
}
}
#line 89 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
;
cls->switch_id = id;
cls->valency = val;
cls->help_text = help_literal;
cls->form = ACTION_CLSF;
cls->active_by_default = FALSE;
cls->negates = NULL;
cls->switch_group = current_switch_group;
Dictionaries__create(cls_dictionary, cls->switch_name);
Dictionaries__write_value(cls_dictionary, cls->switch_name, cls);
return cls;
}
#line 117 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
command_line_switch *CommandLine__declare_boolean_switch(int id,
wchar_t *name_literal, int val, wchar_t *help_literal, int active) {
command_line_switch *cls =
CommandLine__declare_switch(id, name_literal, val, help_literal);
text_stream *neg = Str__new();
WRITE_TO(neg, "no-%w", name_literal);
text_stream *neg_help = Str__new();
WRITE_TO(neg_help, "don't %w", help_literal);
command_line_switch *negated =
CommandLine__declare_switch_p(id, neg, val, neg_help);
cls->form = BOOLEAN_ON_CLSF;
negated->form = BOOLEAN_OFF_CLSF;
negated->negates = cls;
if (active) cls->active_by_default = TRUE; else negated->active_by_default = TRUE;
return cls;
}
void CommandLine__declare_numerical_switch(int id,
wchar_t *name_literal, int val, wchar_t *help_literal) {
command_line_switch *cls =
CommandLine__declare_switch(id, name_literal, val, help_literal);
cls->form = NUMERICAL_CLSF;
}
void CommandLine__declare_textual_switch(int id,
wchar_t *name_literal, int val, wchar_t *help_literal) {
command_line_switch *cls =
CommandLine__declare_switch(id, name_literal, val, help_literal);
cls->form = TEXTUAL_CLSF;
}
#line 178 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__read(int argc, char **argv, void *state,
void (*f)(int, int, text_stream *, void *), void (*g)(int, text_stream *, void *)) {
clf_reader_state crs;
crs.state = state; crs.f = f; crs.g = g;
crs.subs = FALSE; crs.nrt = 0;
CommandLine__read_array(&crs, argc, argv);
CommandLine__read_file(&crs);
return crs.subs;
}
void CommandLine__set_locale(int argc, char **argv) {
for (int i=1; i<argc; i++) {
char *p = argv[i];
if ((strcmp(p, "-locale") == 0) && (i<argc-1))
if (Locales__set_locales(argv[i+1]) == FALSE)
Errors__fatal("unrecognised locale");
}
}
void CommandLine__read_array(clf_reader_state *crs, int argc, char **argv) {
for (int i=1; i<argc; i++) {
int switched = FALSE;
char *p = argv[i];
while (p[0] == '-') { p++; switched = TRUE; } /* allow a doubled-dash as a single */
TEMPORARY_TEXT(opt)
Streams__write_locale_string(opt, p);
TEMPORARY_TEXT(arg)
if (i+1 < argc) Streams__write_locale_string(arg, argv[i+1]);
if (switched) {
int N = CommandLine__read_pair(crs, opt, arg);
if (N == 0)
Errors__fatal_with_text("unknown command line switch: -%S", opt);
i += N - 1;
} else {
CommandLine__read_one(crs, opt);
}
DISCARD_TEXT(opt)
DISCARD_TEXT(arg)
}
}
#line 224 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
filename *command_line_file = NULL;
void CommandLine__also_read_file(filename *F) {
command_line_file = F;
}
#line 235 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
linked_list *command_line_logs = NULL;
void CommandLine__record_log(text_stream *line) {
if (command_line_logs == NULL)
command_line_logs = NEW_LINKED_LIST(text_stream);
ADD_TO_LINKED_LIST(line, text_stream, command_line_logs);
}
void CommandLine__play_back_log(void) {
if (command_line_logs) {
text_stream *line;
LOOP_OVER_LINKED_LIST(line, text_stream, command_line_logs)
LOG("%S\n", line);
}
}
#line 259 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__read_file(clf_reader_state *crs) {
text_stream *logline = Str__new();
WRITE_TO(logline, "Reading further switches from file: %f", command_line_file);
CommandLine__record_log(logline);
if (command_line_file)
TextFiles__read(command_line_file, FALSE,
NULL, FALSE, CommandLine__read_file_helper, NULL, (void *) crs);
command_line_file = NULL;
text_stream *lastline = Str__new();
WRITE_TO(lastline, "Completed expert settings file");
CommandLine__record_log(lastline);
}
void CommandLine__read_file_helper(text_stream *text, text_file_position *tfp, void *state) {
clf_reader_state *crs = (clf_reader_state *) state;
match_results mr = Regexp__create_mr();
if ((Str__is_whitespace(text)) || (Regexp__match(&mr, text, L" *#%c*"))) {
;
} else {
text_stream *logline = Str__new();
WRITE_TO(logline, "line %d: %S", tfp->line_count, text);
CommandLine__record_log(logline);
if (Regexp__match(&mr, text, L" *-*(%C+) (%c+?) *")) {
int N = CommandLine__read_pair(crs, mr.exp[0], mr.exp[1]);
if (N == 0)
Errors__fatal_with_text("unknown command line switch: -%S", mr.exp[0]);
if (N == 1)
Errors__fatal_with_text("command line switch does not take value: -%S", mr.exp[0]);
} else if (Regexp__match(&mr, text, L" *-*(%C+) *")) {
int N = CommandLine__read_pair(crs, mr.exp[0], NULL);
if (N == 0)
Errors__fatal_with_text("unknown command line switch: -%S", mr.exp[0]);
if (N == 2)
Errors__fatal_with_text("command line switch requires value: -%S", mr.exp[0]);
} else {
Errors__in_text_file("illegible line in expert settings file", tfp);
WRITE_TO(STDERR, "'%S'\n", text);
}
}
Regexp__dispose_of(&mr);
}
void CommandLine__read_one(clf_reader_state *crs, text_stream *opt) {
(*(crs->g))(crs->nrt++, opt, crs->state);
crs->subs = TRUE;
}
#line 308 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__read_pair(clf_reader_state *crs, text_stream *opt, text_stream *arg) {
TEMPORARY_TEXT(opt_p)
TEMPORARY_TEXT(opt_val)
Str__copy(opt_p, opt);
int N = BOGUS_CLSN;
match_results mr = Regexp__create_mr();
if ((Regexp__match(&mr, opt, L"(%c+)=(%d+)")) ||
(Regexp__match(&mr, opt, L"(%c+)=(-%d+)"))) {
N = Str__atoi(mr.exp[1], 0);
Str__copy(opt_p, mr.exp[0]);
Str__copy(opt_val, mr.exp[1]);
} else if (Regexp__match(&mr, opt, L"(%c+)=(%c*)")) {
Str__copy(opt_p, mr.exp[0]);
Str__copy(opt_val, mr.exp[1]);
}
int rv = CommandLine__read_pair_p(opt_p, opt_val, N, arg, crs->state, crs->f, &(crs->subs));
DISCARD_TEXT(opt_p)
DISCARD_TEXT(opt_val)
return rv;
}
#line 332 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__read_pair_p(text_stream *opt, text_stream *opt_val, int N,
text_stream *arg, void *state,
void (*f)(int, int, text_stream *, void *), int *substantive) {
if (Dictionaries__find(cls_dictionary, opt) == NULL) return 0;
command_line_switch *cls = Dictionaries__read_value(cls_dictionary, opt);
if (cls == NULL) return 0;
if ((N == BOGUS_CLSN) && (cls->form == NUMERICAL_CLSF)) {
Errors__fatal_with_text("no value N given for -%S=N", opt);
return cls->valency;
}
if ((N != BOGUS_CLSN) && (cls->form != NUMERICAL_CLSF)) {
Errors__fatal_with_text("this is not a numerical setting: -%S", opt);
return cls->valency;
}
if (cls->valency > 1) {
if (Str__len(arg) == 0) {
Errors__fatal_with_text("no argument X for -%S X", opt);
return cls->valency;
}
}
int innocuous = FALSE;
{
#line 362 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
switch (cls->switch_id) {
case CRASH_CLSW:
if (cls->form == BOOLEAN_ON_CLSF) {
Errors__enter_debugger_mode(); innocuous = TRUE;
}
break;
case LOG_CLSW:
{
#line 402 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
if (Log__get_debug_log_filename() == NULL) {
TEMPORARY_TEXT(itn)
WRITE_TO(itn, "%s", PROGRAM_NAME);
filename *F = Filenames__in(Pathnames__from_text(itn), TL_IS_1);
DISCARD_TEXT(itn)
Log__set_debug_log_filename(F);
}
Log__open();
Log__set_aspect_from_command_line(arg, TRUE);
}
#line 368 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
; innocuous = TRUE; break;
case VERSION_CLSW: {
PRINT("inweb");
char *svn = "7.2.0";
if (svn[0]) PRINT(" version %s", svn);
char *vname = "Escape to Danger";
if (vname[0]) PRINT(" '%s'", vname);
char *d = "20 August 2022";
if (d[0]) PRINT(" (%s)", d);
PRINT("\n");
innocuous = TRUE; break;
}
case HELP_CLSW: CommandLine__write_help(STDOUT); innocuous = TRUE; break;
case FIXTIME_CLSW:
if (cls->form == BOOLEAN_ON_CLSF) Time__fix();
break;
case AT_CLSW: Pathnames__set_installation_path(Pathnames__from_text(arg)); break;
case LOCALE_CLSW: break; /* because it was done earlier */
default:
if (f) {
int par = -1;
switch (cls->form) {
case BOOLEAN_ON_CLSF: par = TRUE; break;
case BOOLEAN_OFF_CLSF: par = FALSE; break;
case NUMERICAL_CLSF: par = N; break;
case TEXTUAL_CLSF: arg = opt_val; break;
}
if (cls->valency == 1) (*f)(cls->switch_id, par, arg, state);
else (*f)(cls->switch_id, par, arg, state);
}
break;
}
}
#line 353 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
;
if ((innocuous == FALSE) && (substantive)) *substantive = TRUE;
return cls->valency;
}
#line 422 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
text_stream *cls_heading = NULL;
void CommandLine__declare_heading(wchar_t *heading_text_literal) {
cls_heading = Str__new_from_wide_string(heading_text_literal);
}
void CommandLine__write_help(OUTPUT_STREAM) {
command_line_switch *cls;
int max = 0, N = 0;
LOOP_OVER(cls, command_line_switch) {
int L = Str__len(cls->switch_name);
if (L > max) max = L;
N++;
}
command_line_switch **sorted_table =
Memory__calloc(N, (int) sizeof(command_line_switch *), ARRAY_SORTING_MREASON);
int i=0; LOOP_OVER(cls, command_line_switch) sorted_table[i++] = cls;
qsort(sorted_table, (size_t) N, sizeof(command_line_switch *), CommandLine__compare_names);
if (Str__len(cls_heading) > 0) WRITE("%S\n", cls_heading);
int filter = NO_CLSG, new_para_needed = FALSE;
{
#line 454 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
if (new_para_needed) {
WRITE("\n");
new_para_needed = FALSE;
}
for (int i=0; i<N; i++) {
command_line_switch *cls = sorted_table[i];
if (cls->switch_group != filter) continue;
if ((cls->form == BOOLEAN_OFF_CLSF) || (cls->form == BOOLEAN_ON_CLSF)) {
if (cls->active_by_default) continue;
}
text_stream *label = switch_group_names[filter];
if (new_para_needed == FALSE) {
if (Str__len(label) > 0) WRITE("%S:\n", label);
new_para_needed = TRUE;
}
TEMPORARY_TEXT(line)
if (Str__len(label) > 0) WRITE_TO(line, " ");
WRITE_TO(line, "-%S", cls->switch_name);
if (cls->form == NUMERICAL_CLSF) WRITE_TO(line, "=N");
if (cls->form == TEXTUAL_CLSF) WRITE_TO(line, "=X");
if (cls->valency > 1) WRITE_TO(line, " X");
while (Str__len(line) < max+7) WRITE_TO(line, " ");
WRITE_TO(line, "%S", cls->help_text);
if (cls->form == BOOLEAN_ON_CLSF)
WRITE_TO(line, " (default is -no-%S)", cls->switch_name);
if (cls->form == BOOLEAN_OFF_CLSF)
WRITE_TO(line, " (default is -%S)", cls->negates->switch_name);
WRITE("%S\n", line);
DISCARD_TEXT(line)
}
}
#line 443 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
;
for (filter = NO_CLSG; filter<NO_DEFINED_CLSG_VALUES; filter++)
if ((filter != NO_CLSG) && (filter != FOUNDATION_CLSG))
{
#line 454 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
if (new_para_needed) {
WRITE("\n");
new_para_needed = FALSE;
}
for (int i=0; i<N; i++) {
command_line_switch *cls = sorted_table[i];
if (cls->switch_group != filter) continue;
if ((cls->form == BOOLEAN_OFF_CLSF) || (cls->form == BOOLEAN_ON_CLSF)) {
if (cls->active_by_default) continue;
}
text_stream *label = switch_group_names[filter];
if (new_para_needed == FALSE) {
if (Str__len(label) > 0) WRITE("%S:\n", label);
new_para_needed = TRUE;
}
TEMPORARY_TEXT(line)
if (Str__len(label) > 0) WRITE_TO(line, " ");
WRITE_TO(line, "-%S", cls->switch_name);
if (cls->form == NUMERICAL_CLSF) WRITE_TO(line, "=N");
if (cls->form == TEXTUAL_CLSF) WRITE_TO(line, "=X");
if (cls->valency > 1) WRITE_TO(line, " X");
while (Str__len(line) < max+7) WRITE_TO(line, " ");
WRITE_TO(line, "%S", cls->help_text);
if (cls->form == BOOLEAN_ON_CLSF)
WRITE_TO(line, " (default is -no-%S)", cls->switch_name);
if (cls->form == BOOLEAN_OFF_CLSF)
WRITE_TO(line, " (default is -%S)", cls->negates->switch_name);
WRITE("%S\n", line);
DISCARD_TEXT(line)
}
}
#line 446 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
;
filter = FOUNDATION_CLSG;
{
#line 454 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
if (new_para_needed) {
WRITE("\n");
new_para_needed = FALSE;
}
for (int i=0; i<N; i++) {
command_line_switch *cls = sorted_table[i];
if (cls->switch_group != filter) continue;
if ((cls->form == BOOLEAN_OFF_CLSF) || (cls->form == BOOLEAN_ON_CLSF)) {
if (cls->active_by_default) continue;
}
text_stream *label = switch_group_names[filter];
if (new_para_needed == FALSE) {
if (Str__len(label) > 0) WRITE("%S:\n", label);
new_para_needed = TRUE;
}
TEMPORARY_TEXT(line)
if (Str__len(label) > 0) WRITE_TO(line, " ");
WRITE_TO(line, "-%S", cls->switch_name);
if (cls->form == NUMERICAL_CLSF) WRITE_TO(line, "=N");
if (cls->form == TEXTUAL_CLSF) WRITE_TO(line, "=X");
if (cls->valency > 1) WRITE_TO(line, " X");
while (Str__len(line) < max+7) WRITE_TO(line, " ");
WRITE_TO(line, "%S", cls->help_text);
if (cls->form == BOOLEAN_ON_CLSF)
WRITE_TO(line, " (default is -no-%S)", cls->switch_name);
if (cls->form == BOOLEAN_OFF_CLSF)
WRITE_TO(line, " (default is -%S)", cls->negates->switch_name);
WRITE("%S\n", line);
DISCARD_TEXT(line)
}
}
#line 448 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
;
Memory__I7_free(sorted_table, ARRAY_SORTING_MREASON, N*((int) sizeof(command_line_switch *)));
}
#line 486 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
int CommandLine__compare_names(const void *ent1, const void *ent2) {
text_stream *tx1 = (*((const command_line_switch **) ent1))->switch_sort_name;
text_stream *tx2 = (*((const command_line_switch **) ent2))->switch_sort_name;
return Str__cmp_insensitive(tx1, tx2);
}
#line 44 "inweb/foundation-module/Chapter 3/Pathnames.w"
#line 50 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname *home_path = NULL;
void Pathnames__start(void) {
char *home = (char *) (Platform__getenv("HOME"));
if (home) {
text_stream *H = Str__new_from_locale_string(home);
home_path = Pathnames__from_text(H);
home_path->known_to_exist = TRUE;
}
}
#line 63 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname *installation_path = NULL;
void Pathnames__set_installation_path(pathname *P) {
installation_path = P;
}
pathname *Pathnames__installation_path(const char *V, text_stream *def) {
if (installation_path) return installation_path;
wchar_t where[4*MAX_FILENAME_LENGTH];
where[0] = 0;
Platform__where_am_i(where, 4*MAX_FILENAME_LENGTH);
if (where[0]) {
text_stream *v = Str__new_from_wide_string(where);
filename *F = Filenames__from_text(v);
pathname *P = Filenames__up(F);
if ((P) && (Str__eq(P->intermediate, TL_IS_2)))
P = P->pathname_of_parent;
return P;
}
if (V) {
char *val = Platform__getenv(V);
if ((val) && (val[0])) {
text_stream *v = Str__new_from_locale_string(val);
return Pathnames__from_text(v);
}
}
if (def) return Pathnames__from_text(def);
return NULL;
}
#line 96 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname *Pathnames__down(pathname *P, text_stream *dir_name) {
return Pathnames__primitive(dir_name, 0, Str__len(dir_name), P);
}
pathname *Pathnames__primitive(text_stream *str, int from, int to, pathname *par) {
pathname *P = CREATE(pathname);
P->pathname_of_parent = par;
P->known_to_exist = FALSE;
if (to-from <= 0) internal_error("empty intermediate pathname");
P->intermediate = Str__new_with_capacity(to-from+1);
if (str)
for (int i = from; i < to; i++)
PUT_TO(P->intermediate, Str__get(Str__at(str, i)));
return P;
}
#line 120 "inweb/foundation-module/Chapter 3/Pathnames.w"
pathname *Pathnames__from_text(text_stream *path) {
return Pathnames__from_text_relative(NULL, path);
}
pathname *Pathnames__from_text_relative(pathname *P, text_stream *path) {
pathname *at = P;
int i = 0, pos = 0;
if ((Str__get(Str__start(path))) && (P == NULL)) i++;
for (; i < Str__len(path); i++)
if (Platform__is_folder_separator(Str__get(Str__at(path, i)))) {
if (i > pos) at = Pathnames__primitive(path, pos, i, at);
pos = i+1;
}
if (i > pos) at = Pathnames__primitive(path, pos, i, at);
return at;
}
#line 141 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__writer(OUTPUT_STREAM, char *format_string, void *vP) {
pathname *P = (pathname *) vP;
int divider = FOLDER_SEPARATOR;
if (format_string[0] == '/') divider = '/';
if (P) Pathnames__writer_r(OUT, P, divider); else WRITE(".");
}
void Pathnames__writer_r(OUTPUT_STREAM, pathname *P, int divider) {
if (P->pathname_of_parent) {
Pathnames__writer_r(OUT, P->pathname_of_parent, divider);
PUT(divider);
}
WRITE("%S", P->intermediate);
}
#line 178 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__to_text_relative(OUTPUT_STREAM, pathname *P, pathname *R) {
TEMPORARY_TEXT(rt)
TEMPORARY_TEXT(pt)
WRITE_TO(rt, "%p", R);
WRITE_TO(pt, "%p", P);
int n = Str__len(pt);
if ((Str__prefix_eq(rt, pt, n)) && (Platform__is_folder_separator(Str__get_at(rt, n)))) {
Str__delete_n_characters(rt, n+1);
WRITE("%S", rt);
} else if (Str__eq(rt, pt) == FALSE)
internal_error("pathname not relative to pathname");
DISCARD_TEXT(rt)
DISCARD_TEXT(pt)
}
pathname *Pathnames__up(pathname *P) {
if (P == NULL) internal_error("can't go up from root directory");
return P->pathname_of_parent;
}
text_stream *Pathnames__directory_name(pathname *P) {
if (P == NULL) return NULL;
return P->intermediate;
}
#line 209 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__relative_URL(OUTPUT_STREAM, pathname *from, pathname *to) {
TEMPORARY_TEXT(url)
int found = FALSE;
for (pathname *P = to; P && (found == FALSE); P = Pathnames__up(P)) {
TEMPORARY_TEXT(PT)
WRITE_TO(PT, "%p", P);
int q_up_count = 0;
for (pathname *Q = from; Q && (found == FALSE); Q = Pathnames__up(Q)) {
TEMPORARY_TEXT(QT)
WRITE_TO(QT, "%p", Q);
if (Str__eq(PT, QT)) {
for (int i=0; i<q_up_count; i++) WRITE_TO(url, "../");
TEMPORARY_TEXT(FPT)
WRITE_TO(FPT, "%p", to);
Str__substr(url, Str__at(FPT, Str__len(PT) + 1), Str__end(FPT));
found = TRUE;
}
DISCARD_TEXT(QT)
q_up_count++;
}
DISCARD_TEXT(PT)
}
if (found == FALSE) {
for (pathname *Q = from; Q; Q = Pathnames__up(Q)) WRITE_TO(url, "../");
WRITE_TO(url, "%p", to);
}
WRITE("%S", url);
if ((Str__len(url) > 0) && (Str__get_last_char(url) != '/')) WRITE("/");
DISCARD_TEXT(url)
}
#line 245 "inweb/foundation-module/Chapter 3/Pathnames.w"
int Pathnames__create_in_file_system(pathname *P) {
if (P == NULL) return TRUE; /* the root of the file system always exists */
if (P->known_to_exist) return TRUE;
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
TEMPORARY_TEXT(pn)
WRITE_TO(pn, "%p", P);
Str__copy_to_locale_string(transcoded_pathname, pn, 4*MAX_FILENAME_LENGTH);
DISCARD_TEXT(pn)
P->known_to_exist = Platform__mkdir(transcoded_pathname);
return P->known_to_exist;
}
#line 263 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__rsync(pathname *source, pathname *dest) {
char transcoded_source[4*MAX_FILENAME_LENGTH];
TEMPORARY_TEXT(pn)
WRITE_TO(pn, "%p", source);
Str__copy_to_locale_string(transcoded_source, pn, 4*MAX_FILENAME_LENGTH);
DISCARD_TEXT(pn)
char transcoded_dest[4*MAX_FILENAME_LENGTH];
TEMPORARY_TEXT(pn2)
WRITE_TO(pn2, "%p", dest);
Str__copy_to_locale_string(transcoded_dest, pn2, 4*MAX_FILENAME_LENGTH);
DISCARD_TEXT(pn2)
Platform__rsync(transcoded_source, transcoded_dest);
}
#line 17 "inweb/foundation-module/Chapter 3/Filenames.w"
#line 22 "inweb/foundation-module/Chapter 3/Filenames.w"
filename *Filenames__in(pathname *P, text_stream *file_name) {
return Filenames__primitive(file_name, 0, Str__len(file_name), P);
}
filename *Filenames__primitive(text_stream *S, int from, int to, pathname *P) {
filename *F = CREATE(filename);
F->pathname_of_location = P;
if (to-from <= 0)
internal_error("empty intermediate pathname");
F->leafname = Str__new_with_capacity(to-from+1);
string_position pos = Str__at(S, from);
for (int i = from; i < to; i++, pos = Str__forward(pos))
PUT_TO(F->leafname, Str__get(pos));
return F;
}
#line 42 "inweb/foundation-module/Chapter 3/Filenames.w"
filename *Filenames__from_text(text_stream *path) {
int i = 0, pos = -1;
LOOP_THROUGH_TEXT(at, path) {
if (Platform__is_folder_separator(Str__get(at))) pos = i;
i++;
}
pathname *P = NULL;
if (pos >= 0) {
TEMPORARY_TEXT(PT)
Str__substr(PT, Str__at(path, 0), Str__at(path, pos));
P = Pathnames__from_text(PT);
DISCARD_TEXT(PT)
}
return Filenames__primitive(path, pos+1, Str__len(path), P);
}
filename *Filenames__from_text_relative(pathname *from, text_stream *path) {
filename *F = Filenames__from_text(path);
if (from) {
if (F->pathname_of_location == NULL) F->pathname_of_location = from;
else {
pathname *P = F->pathname_of_location;
while ((P) && (P->pathname_of_parent)) P = P->pathname_of_parent;
P->pathname_of_parent = from;
}
}
return F;
}
#line 75 "inweb/foundation-module/Chapter 3/Filenames.w"
void Filenames__writer(OUTPUT_STREAM, char *format_string, void *vF) {
filename *F = (filename *) vF;
if (F == NULL) WRITE("<no file>");
else {
if (F->pathname_of_location) {
Pathnames__writer(OUT, format_string, (void *) F->pathname_of_location);
if (format_string[0] == '/') PUT('/');
else PUT(FOLDER_SEPARATOR);
}
WRITE("%S", F->leafname);
}
}
#line 91 "inweb/foundation-module/Chapter 3/Filenames.w"
void Filenames__to_text_relative(OUTPUT_STREAM, filename *F, pathname *P) {
TEMPORARY_TEXT(ft)
TEMPORARY_TEXT(pt)
WRITE_TO(ft, "%f", F);
WRITE_TO(pt, "%p", P);
int n = Str__len(pt);
if ((Str__prefix_eq(ft, pt, n)) && (Platform__is_folder_separator(Str__get_at(ft, n)))) {
Str__delete_n_characters(ft, n+1);
WRITE("%S", ft);
} else {
if (P == NULL) {
WRITE("%S", ft);
} else {
WRITE("..%c", FOLDER_SEPARATOR);
Filenames__to_text_relative(OUT, F, Pathnames__up(P));
}
}
DISCARD_TEXT(ft)
DISCARD_TEXT(pt)
}
#line 115 "inweb/foundation-module/Chapter 3/Filenames.w"
pathname *Filenames__up(filename *F) {
if (F == NULL) return NULL;
return F->pathname_of_location;
}
#line 123 "inweb/foundation-module/Chapter 3/Filenames.w"
filename *Filenames__without_path(filename *F) {
return Filenames__in(NULL, F->leafname);
}
text_stream *Filenames__get_leafname(filename *F) {
if (F == NULL) return NULL;
return F->leafname;
}
void Filenames__write_unextended_leafname(OUTPUT_STREAM, filename *F) {
LOOP_THROUGH_TEXT(pos, F->leafname) {
wchar_t c = Str__get(pos);
if (c == '.') return;
PUT(c);
}
}
#line 148 "inweb/foundation-module/Chapter 3/Filenames.w"
void Filenames__write_extension(OUTPUT_STREAM, filename *F) {
int on = FALSE;
LOOP_THROUGH_TEXT(pos, F->leafname) {
wchar_t c = Str__get(pos);
if (c == '.') on = TRUE;
if (on) PUT(c);
}
}
filename *Filenames__set_extension(filename *F, text_stream *extension) {
TEMPORARY_TEXT(NEWLEAF)
LOOP_THROUGH_TEXT(pos, F->leafname) {
wchar_t c = Str__get(pos);
if (c == '.') break;
PUT_TO(NEWLEAF, c);
}
if (Str__len(extension) > 0) {
if (Str__get_first_char(extension) != '.') WRITE_TO(NEWLEAF, ".");
WRITE_TO(NEWLEAF, "%S", extension);
}
filename *N = Filenames__in(F->pathname_of_location, NEWLEAF);
DISCARD_TEXT(NEWLEAF)
return N;
}
#line 190 "inweb/foundation-module/Chapter 3/Filenames.w"
int Filenames__guess_format(filename *F) {
TEMPORARY_TEXT(EXT)
Filenames__write_extension(EXT, F);
TEMPORARY_TEXT(NORMALISED)
LOOP_THROUGH_TEXT(pos, EXT) {
wchar_t c = Str__get(pos);
if (c != ' ') PUT_TO(NORMALISED, Characters__tolower(c));
}
DISCARD_TEXT(EXT)
int verdict = FORMAT_UNRECOGNISED;
if (Str__eq_wide_string(NORMALISED, L".html")) verdict = FORMAT_PERHAPS_HTML;
else if (Str__eq_wide_string(NORMALISED, L".htm")) verdict = FORMAT_PERHAPS_HTML;
else if (Str__eq_wide_string(NORMALISED, L".jpg")) verdict = FORMAT_PERHAPS_JPEG;
else if (Str__eq_wide_string(NORMALISED, L".jpeg")) verdict = FORMAT_PERHAPS_JPEG;
else if (Str__eq_wide_string(NORMALISED, L".png")) verdict = FORMAT_PERHAPS_PNG;
else if (Str__eq_wide_string(NORMALISED, L".ogg")) verdict = FORMAT_PERHAPS_OGG;
else if (Str__eq_wide_string(NORMALISED, L".aiff")) verdict = FORMAT_PERHAPS_AIFF;
else if (Str__eq_wide_string(NORMALISED, L".aif")) verdict = FORMAT_PERHAPS_AIFF;
else if (Str__eq_wide_string(NORMALISED, L".midi")) verdict = FORMAT_PERHAPS_MIDI;
else if (Str__eq_wide_string(NORMALISED, L".mid")) verdict = FORMAT_PERHAPS_MIDI;
else if (Str__eq_wide_string(NORMALISED, L".mod")) verdict = FORMAT_PERHAPS_MOD;
else if (Str__eq_wide_string(NORMALISED, L".svg")) verdict = FORMAT_PERHAPS_SVG;
else if (Str__eq_wide_string(NORMALISED, L".gif")) verdict = FORMAT_PERHAPS_GIF;
else if (Str__len(NORMALISED) > 0) {
if ((Str__get(Str__at(NORMALISED, 0)) == '.') &&
(Str__get(Str__at(NORMALISED, 1)) == 'z') &&
(Characters__isdigit(Str__get(Str__at(NORMALISED, 2)))) &&
(Str__len(NORMALISED) == 3))
verdict = FORMAT_PERHAPS_ZCODE;
else if (Str__get(Str__back(Str__end(NORMALISED))) == 'x')
verdict = FORMAT_PERHAPS_GLULX;
}
DISCARD_TEXT(NORMALISED)
return verdict;
}
#line 234 "inweb/foundation-module/Chapter 3/Filenames.w"
FILE *Filenames__fopen(filename *F, char *usage) {
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
TEMPORARY_TEXT(FN)
WRITE_TO(FN, "%f", F);
Str__copy_to_locale_string(transcoded_pathname, FN, 4*MAX_FILENAME_LENGTH);
DISCARD_TEXT(FN)
return fopen(transcoded_pathname, usage);
}
FILE *Filenames__fopen_caseless(filename *F, char *usage) {
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
TEMPORARY_TEXT(FN)
WRITE_TO(FN, "%f", F);
Str__copy_to_locale_string(transcoded_pathname, FN, 4*MAX_FILENAME_LENGTH);
DISCARD_TEXT(FN)
return CIFilingSystem__fopen(transcoded_pathname, usage);
}
#line 258 "inweb/foundation-module/Chapter 3/Filenames.w"
int Filenames__eq(filename *F1, filename *F2) {
if (F1 == F2) return TRUE;
TEMPORARY_TEXT(T1)
TEMPORARY_TEXT(T2)
WRITE_TO(T1, "%f", F1);
WRITE_TO(T2, "%f", F2);
int rv = Str__eq(T1, T2);
DISCARD_TEXT(T1)
DISCARD_TEXT(T2)
return rv;
}
#line 273 "inweb/foundation-module/Chapter 3/Filenames.w"
time_t Filenames__timestamp(filename *F) {
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
TEMPORARY_TEXT(FN)
WRITE_TO(FN, "%f", F);
Str__copy_to_locale_string(transcoded_pathname, FN, 4*MAX_FILENAME_LENGTH);
time_t t = Platform__timestamp(transcoded_pathname);
DISCARD_TEXT(FN)
return t;
}
int Filenames__size(filename *F) {
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
TEMPORARY_TEXT(FN)
WRITE_TO(FN, "%f", F);
Str__copy_to_locale_string(transcoded_pathname, FN, 4*MAX_FILENAME_LENGTH);
int t = (int) Platform__size(transcoded_pathname);
DISCARD_TEXT(FN)
return t;
}
#ifdef PLATFORM_POSIX
#line 50 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
FILE *CIFilingSystem__fopen(const char *path, const char *mode) {
char *topdirpath = NULL, *ciextdirpath = NULL, *cistring = NULL, *ciextname = NULL;
char *workstring = NULL, *workstring2 = NULL;
DIR *topdir = NULL, *extdir = NULL; FILE *handle;
size_t length;
/* for efficiency's sake, though it's logically equivalent, we try... */
handle = fopen(path, mode); if (handle)
{
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return handle;
}
#line 57 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 159 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
length = 0;
if (path) length = (size_t) strlen(path);
if (length < 1) { errno = ENOENT; return NULL; }
}
#line 59 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 121 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
workstring = calloc(length+1, sizeof(char));
if (workstring == NULL) { errno = ENOMEM;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 122 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
; }
workstring2 = calloc(length+1, sizeof(char));
if (workstring2 == NULL) { errno = ENOMEM;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 124 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
; }
topdirpath = calloc(length+1, sizeof(char));
if (topdirpath == NULL) { errno = ENOMEM;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 126 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
; }
ciextdirpath = calloc(length+1, sizeof(char));
if (ciextdirpath == NULL) { errno = ENOMEM;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 128 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
; }
cistring = calloc(length+1, sizeof(char));
if (cistring == NULL) { errno = ENOMEM;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 130 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
; }
ciextname = calloc(length+1, sizeof(char));
if (ciextname == NULL) { errno = ENOMEM;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 132 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
; }
}
#line 60 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 175 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
char *p;
size_t extdirindex = 0, extindex = 0, namelen = 0, dirlen = 0;
p = CIFilingSystem__strrchr(path);
if (p) {
extindex = (size_t) (p - path);
namelen = length - extindex - 1;
strncpy(ciextname, path + extindex + 1, namelen);
}
ciextname[namelen] = 0;
if (extindex > 0) strncpy(workstring, path, extindex);
workstring[extindex] = 0;
p = CIFilingSystem__strrchr(workstring);
if (p) {
extdirindex = (size_t) (p - workstring);
strncpy(topdirpath, path, extdirindex);
}
topdirpath[extdirindex] = 0;
dirlen = extindex - extdirindex;
if (dirlen > 0) dirlen -= 1;
strncpy(ciextdirpath, path + extdirindex + 1, dirlen);
ciextdirpath[dirlen] = 0;
}
#line 61 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
topdir = opendir(topdirpath); /* whose pathname is assumed case-correct... */
if (topdir == NULL)
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 64 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
; /* ...so that failure is fatal; |errno| is set by |opendir| */
sprintf(workstring, "%s%c%s", topdirpath, FOLDER_SEPARATOR, ciextdirpath);
extdir = opendir(workstring); /* try with supplied extension directory name */
if (extdir == NULL)
{
#line 83 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
int rc = CIFilingSystem__match_in_directory(topdir, ciextdirpath, workstring);
switch (rc) {
case 0:
errno = ENOENT;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 86 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
case 1:
sprintf(cistring, "%s%c%s", topdirpath, FOLDER_SEPARATOR, workstring);
extdir = opendir(cistring);
if (extdir == NULL) {
errno = ENOENT;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 91 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
}
break;
default:
errno = EBADF;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 95 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
}
}
#line 68 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
else strcpy(cistring, workstring);
sprintf(workstring, "%s%c%s", cistring, FOLDER_SEPARATOR, ciextname);
handle = fopen(workstring, mode); /* try with supplied name */
if (handle)
{
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return handle;
}
#line 73 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 102 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
int rc = CIFilingSystem__match_in_directory(extdir, ciextname, workstring);
switch (rc) {
case 0:
errno = ENOENT;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 106 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
case 1:
sprintf(workstring2, "%s%c%s", cistring, FOLDER_SEPARATOR, workstring);
workstring2[length] = 0;
handle = fopen(workstring2, mode);
if (handle)
{
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return handle;
}
#line 111 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
errno = ENOENT;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 112 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
default:
errno = EBADF;
{
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
{
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 114 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
}
}
#line 75 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
;
}
#endif /* PLATFORM_POSIX */
#line 205 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
char *CIFilingSystem__strrchr(const char *p) {
const char *q = NULL;
while (*p) {
if (Platform__is_folder_separator((wchar_t) (*p))) q = p;
p++;
}
return (char *) q;
}
#line 225 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
int CIFilingSystem__match_in_directory(void *vd,
char *name, char *last_match) {
DIR *d = (DIR *) vd;
struct dirent *dirp;
int rc = 0;
last_match[0] = 0;
while ((dirp = readdir(d)) != NULL) {
if (strcasecmp(name, dirp->d_name) == 0) {
rc++;
strcpy(last_match, dirp->d_name);
}
}
return rc;
}
#ifndef PLATFORM_POSIX
#line 245 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
FILE *CIFilingSystem__fopen(const char *path, const char *mode) {
return fopen(path, mode);
}
#endif /* PLATFORM_POSIX */
#line 14 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__quote_path(OUTPUT_STREAM, pathname *P) {
TEMPORARY_TEXT(FN)
WRITE_TO(FN, "%p", P);
Shell__quote_text(OUT, FN);
DISCARD_TEXT(FN)
}
void Shell__quote_file(OUTPUT_STREAM, filename *F) {
TEMPORARY_TEXT(FN)
WRITE_TO(FN, "%f", F);
Shell__quote_text(OUT, FN);
DISCARD_TEXT(FN)
}
void Shell__plain(OUTPUT_STREAM, char *raw) {
WRITE("%s", raw);
}
void Shell__plain_text(OUTPUT_STREAM, text_stream *raw) {
WRITE("%S", raw);
}
void Shell__quote_text(OUTPUT_STREAM, text_stream *raw) {
PUT(SHELL_QUOTE_CHARACTER);
LOOP_THROUGH_TEXT(pos, raw) {
wchar_t c = Str__get(pos);
if (c == SHELL_QUOTE_CHARACTER) PUT('\\');
PUT(c);
}
PUT(SHELL_QUOTE_CHARACTER);
PUT(' ');
}
#line 50 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__apply(char *command, filename *F) {
TEMPORARY_TEXT(COMMAND)
Shell__plain(COMMAND, command);
Shell__plain(COMMAND, " ");
Shell__quote_file(COMMAND, F);
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
void Shell__apply_S(text_stream *command, filename *F) {
TEMPORARY_TEXT(COMMAND)
Shell__plain_text(COMMAND, command);
Shell__plain(COMMAND, " ");
Shell__quote_file(COMMAND, F);
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
#line 70 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__rm(filename *F) {
Shell__apply("rm", F);
}
void Shell__copy(filename *F, pathname *T, char *options) {
TEMPORARY_TEXT(COMMAND)
Shell__plain(COMMAND, "cp ");
Shell__plain(COMMAND, options);
Shell__plain(COMMAND, " ");
Shell__quote_file(COMMAND, F);
Shell__quote_path(COMMAND, T);
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
#line 89 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__redirect(OUTPUT_STREAM, filename *F) {
Shell__plain(OUT, ">");
Shell__quote_file(OUT, F);
Shell__plain(OUT, "2>&1");
}
#line 105 "inweb/foundation-module/Chapter 3/Shell.w"
int shell_verbosity = FALSE;
void Shell__verbose(void) {
shell_verbosity = TRUE;
}
int Shell__run(OUTPUT_STREAM) {
if (shell_verbosity) PRINT("shell: %S\n", OUT);
LOGIF(SHELL_USAGE, "shell: %S\n", OUT);
char spool[SPOOL_LENGTH];
Streams__write_as_locale_string(spool, OUT, SPOOL_LENGTH);
if (debugger_mode) {
WRITE_TO(STDOUT, "debugger mode suppressing shell command: %S\n", OUT);
return 0;
}
int rv = Platform__system(spool);
if (rv == -1) {
WRITE_TO(STDERR, "shell: %S\n", OUT);
internal_error("OS shell error");
}
if (rv == 127) {
WRITE_TO(STDERR, "shell: %S\n", OUT);
internal_error("Execution of the shell failed");
}
return rv;
}
#line 13 "inweb/foundation-module/Chapter 3/Directories.w"
#line 19 "inweb/foundation-module/Chapter 3/Directories.w"
scan_directory *Directories__open_from(text_stream *name) {
scan_directory *D = CREATE(scan_directory);
Str__copy_to_locale_string(D->directory_name_written_out, name, 4*MAX_FILENAME_LENGTH);
D->directory_handle = Platform__opendir(D->directory_name_written_out);
if (D->directory_handle == NULL) return NULL;
return D;
}
scan_directory *Directories__open(pathname *P) {
TEMPORARY_TEXT(pn)
WRITE_TO(pn, "%p", P);
scan_directory *D = Directories__open_from(pn);
DISCARD_TEXT(pn)
return D;
}
int Directories__next(scan_directory *D, text_stream *leafname) {
char leafname_Cs[MAX_FILENAME_LENGTH];
int rv = TRUE;
while (rv) {
rv = Platform__readdir(D->directory_handle, D->directory_name_written_out, leafname_Cs);
if (leafname_Cs[0] != '.') break;
}
Str__clear(leafname);
if (rv) Streams__write_locale_string(leafname, leafname_Cs);
return rv;
}
void Directories__close(scan_directory *D) {
Platform__closedir(D->directory_handle);
}
#line 55 "inweb/foundation-module/Chapter 3/Directories.w"
int Directories__exists(pathname *P) {
scan_directory *TRY = Directories__open(P);
if (TRY == NULL) return FALSE;
Directories__close(TRY);
return TRUE;
}
#line 74 "inweb/foundation-module/Chapter 3/Directories.w"
linked_list *Directories__listing(pathname *P) {
int capacity = 4, used = 0;
text_stream **listing_array = (text_stream **)
(Memory__calloc(capacity, sizeof(text_stream *), ARRAY_SORTING_MREASON));
scan_directory *D = Directories__open(P);
if (D) {
text_stream *entry = Str__new();
while (Directories__next(D, entry)) {
if (used == capacity) {
int new_capacity = 4*capacity;
text_stream **new_listing_array = (text_stream **)
(Memory__calloc(new_capacity, sizeof(text_stream *), ARRAY_SORTING_MREASON));
for (int i=0; i<used; i++) new_listing_array[i] = listing_array[i];
listing_array = new_listing_array;
capacity = new_capacity;
}
listing_array[used++] = entry;
entry = Str__new();
}
Directories__close(D);
}
qsort(listing_array, (size_t) used, sizeof(text_stream *), Directories__compare_names);
linked_list *L = NEW_LINKED_LIST(text_stream);
for (int i=0; i<used; i++) ADD_TO_LINKED_LIST(listing_array[i], text_stream, L);
Memory__I7_free(listing_array, ARRAY_SORTING_MREASON, capacity*((int) sizeof(text_stream *)));
return L;
}
int Directories__compare_names(const void *ent1, const void *ent2) {
text_stream *tx1 = *((text_stream **) ent1);
text_stream *tx2 = *((text_stream **) ent2);
return Str__cmp_insensitive(tx1, tx2);
}
#line 9 "inweb/foundation-module/Chapter 3/Time.w"
time_t right_now;
struct tm *the_present = NULL;
int fix_time_mode = FALSE;
void Time__begin(void) {
time_t right_now = time(NULL);
the_present = localtime(&right_now);
fix_time_mode = FALSE;
}
#line 26 "inweb/foundation-module/Chapter 3/Time.w"
void Time__fix(void) {
struct tm start;
start.tm_sec = 0; start.tm_min = 0; start.tm_hour = 11;
start.tm_mday = 28; start.tm_mon = 3; start.tm_year = 116; start.tm_isdst = -1;
time_t pretend_time = mktime(&start);
the_present = localtime(&pretend_time);
fix_time_mode = TRUE;
}
int Time__fixed(void) {
return fix_time_mode;
}
#line 79 "inweb/foundation-module/Chapter 3/Time.w"
void Time__easter(int year, int *d, int *m) {
int c, y, k, i, n, j, l;
y = year;
c = y/100;
n = y-19*(y/19);
k = (c-17)/25;
i = c-c/4-(c-k)/3+19*n+15;
i = i-30*(i/30);
i = i-(i/28)*(1-(i/28)*(29/(i+1))*((21-n)/11));
j = y+y/4+i+2-c+c/4;
j = j-7*(j/7);
l = i-j;
*m = 3+(l+40)/44;
*d = l+28-31*(*m/4);
}
#line 102 "inweb/foundation-module/Chapter 3/Time.w"
int Time__feast(void) {
int this_month = the_present->tm_mon + 1;
int this_day = the_present->tm_mday;
int this_year = the_present->tm_year + 1900;
int m, d;
Time__easter(this_year, &m, &d);
if ((this_month == m) && (this_day >= d-2) && (this_day <= d+1))
return EASTER_FEAST; /* that is, Good Friday to Easter Monday */
if ((this_year == 2018) && (this_month == 3) && (this_day >= 30))
return EASTER_FEAST; /* Easter Sunday falls on 1 April in 2018 */
if ((this_month == 12) && (this_day >= 25))
return CHRISTMAS_FEAST; /* that is, Christmas Day to New Year's Eve */
return NON_FEAST;
}
#line 139 "inweb/foundation-module/Chapter 3/Time.w"
#line 145 "inweb/foundation-module/Chapter 3/Time.w"
stopwatch_timer *Time__start_stopwatch(stopwatch_timer *within, text_stream *name) {
stopwatch_timer *st = CREATE(stopwatch_timer);
st->event = Str__duplicate(name);
st->start_time = clock();
st->end_time = st->start_time;
st->time_taken = 0;
st->stages_chronological = NEW_LINKED_LIST(stopwatch_timer);
st->stages_sorted = NULL;
st->running = TRUE;
if (within) {
if (within->running == FALSE)
internal_error("stopwatch started in event not under way");
ADD_TO_LINKED_LIST(st, stopwatch_timer, within->stages_chronological);
}
return st;
}
#line 166 "inweb/foundation-module/Chapter 3/Time.w"
int Time__stop_stopwatch(stopwatch_timer *st) {
if (st->running == FALSE) internal_error("already stopped");
st->running = FALSE;
st->end_time = clock();
st->time_taken +=
(((int) (st->end_time)) - ((int) (st->start_time))) / ((int) (CLOCKS_PER_SEC/100));
int N = LinkedLists__len(st->stages_chronological);
if (N > 0)
{
#line 178 "inweb/foundation-module/Chapter 3/Time.w"
st->stages_sorted = NEW_LINKED_LIST(stopwatch_timer);
stopwatch_timer **as_array = (stopwatch_timer **)
(Memory__calloc(N, sizeof(stopwatch_timer *), ARRAY_SORTING_MREASON));
stopwatch_timer *sst; int i = 0;
LOOP_OVER_LINKED_LIST(sst, stopwatch_timer, st->stages_chronological)
as_array[i++] = sst;
qsort(as_array, (size_t) N, sizeof(stopwatch_timer *), Time__compare_watches);
for (i=0; i<N; i++)
ADD_TO_LINKED_LIST(as_array[i], stopwatch_timer, st->stages_sorted);
Memory__I7_array_free(as_array,
ARRAY_SORTING_MREASON, N, sizeof(stopwatch_timer *));
}
#line 173 "inweb/foundation-module/Chapter 3/Time.w"
;
return st->time_taken;
}
#line 193 "inweb/foundation-module/Chapter 3/Time.w"
int Time__compare_watches(const void *w1, const void *w2) {
const stopwatch_timer **st1 = (const stopwatch_timer **) w1;
const stopwatch_timer **st2 = (const stopwatch_timer **) w2;
if ((*st1 == NULL) || (*st2 == NULL))
internal_error("Disaster while sorting stopwatch timings");
int t1 = (*st1)->time_taken, t2 = (*st2)->time_taken;
if (t1 > t2) return -1;
if (t1 < t2) return 1;
return Str__cmp((*st1)->event, (*st2)->event);
}
#line 208 "inweb/foundation-module/Chapter 3/Time.w"
void Time__resume_stopwatch(stopwatch_timer *st) {
if (st->running) internal_error("already running");
st->running = TRUE;
st->start_time = clock();
st->end_time = st->start_time;
}
#line 220 "inweb/foundation-module/Chapter 3/Time.w"
void Time__log_timing(stopwatch_timer *st, int total) {
if (st) {
int N = 1000*st->time_taken/total;
if (N > 0) {
LOG("%3d.%d%% in %S\n", N/10, N%10, st->event);
LOG_INDENT;
int T = 0, no_details = 0;
if (st->stages_sorted) {
stopwatch_timer *sst;
LOOP_OVER_LINKED_LIST(sst, stopwatch_timer, st->stages_sorted) {
no_details++;
T += sst->time_taken;
Time__log_timing(sst, total);
}
}
if (no_details > 0) {
int M = N - 1000*T/total;
if (M > 0) LOG("%3d.%d%% not specifically accounted for\n", M/10, M%10);
}
LOG_OUTDENT;
}
}
}
#line 8 "inweb/foundation-module/Chapter 4/Characters.w"
wchar_t Characters__tolower(wchar_t c) {
return (wchar_t) tolower((int) c);
}
wchar_t Characters__toupper(wchar_t c) {
return (wchar_t) toupper((int) c);
}
int Characters__isalpha(wchar_t c) {
return isalpha((int) c);
}
int Characters__isdigit(wchar_t c) {
return isdigit((int) c);
}
int Characters__isupper(wchar_t c) {
return isupper((int) c);
}
int Characters__islower(wchar_t c) {
return islower((int) c);
}
int Characters__isalnum(wchar_t c) {
return isalnum((int) c);
}
int Characters__iscntrl(wchar_t c) {
int i = c;
return ((i >= 0) && (i < 32));
}
int Characters__vowel(wchar_t c) {
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) return TRUE;
return FALSE;
}
#line 41 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__is_space_or_tab(int c) {
if ((c == ' ') || (c == '\t')) return TRUE;
return FALSE;
}
int Characters__is_whitespace(int c) {
if ((c == ' ') || (c == '\t') || (c == '\n')) return TRUE;
return FALSE;
}
#line 55 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__is_babel_whitespace(int c) {
if ((c == ' ') || (c == '\t') || (c == '\x0a')
|| (c == '\x0d') || (c == NEWLINE_IN_STRING)) return TRUE;
return FALSE;
}
#line 66 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__combine_accent(int accent, int letter) {
switch(accent) {
case 0x0300: /* Unicode combining grave */
switch(letter) {
case 'a': return 0xE0; case 'e': return 0xE8; case 'i': return 0xEC;
case 'o': return 0xF2; case 'u': return 0xF9;
case 'A': return 0xC0; case 'E': return 0xC8; case 'I': return 0xCC;
case 'O': return 0xD2; case 'U': return 0xD9;
}
break;
case 0x0301: /* Unicode combining acute */
switch(letter) {
case 'a': return 0xE1; case 'e': return 0xE9; case 'i': return 0xED;
case 'o': return 0xF3; case 'u': return 0xFA; case 'y': return 0xFF;
case 'A': return 0xC1; case 'E': return 0xC9; case 'I': return 0xCD;
case 'O': return 0xD3; case 'U': return 0xDA;
}
break;
case 0x0302: /* Unicode combining circumflex */
switch(letter) {
case 'a': return 0xE2; case 'e': return 0xEA; case 'i': return 0xEE;
case 'o': return 0xF4; case 'u': return 0xFB;
case 'A': return 0xC2; case 'E': return 0xCA; case 'I': return 0xCE;
case 'O': return 0xD4; case 'U': return 0xDB;
}
break;
case 0x0303: /* Unicode combining tilde */
switch(letter) {
case 'a': return 0xE3; case 'n': return 0xF1; case 'o': return 0xF5;
case 'A': return 0xC3; case 'N': return 0xD1; case 'O': return 0xD5;
}
break;
case 0x0308: /* Unicode combining diaeresis */
switch(letter) {
case 'a': return 0xE4; case 'e': return 0xEB; case 'u': return 0xFC;
case 'o': return 0xF6; case 'i': return 0xEF;
case 'A': return 0xC4; case 'E': return 0xCB; case 'U': return 0xDC;
case 'O': return 0xD6; case 'I': return 0xCF;
}
break;
case 0x0327: /* Unicode combining cedilla */
switch(letter) {
case 'c': return 0xE7; case 'C': return 0xC7;
}
break;
}
return '?';
}
#line 120 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__make_filename_safe(int charcode) {
charcode = Characters__remove_accent(charcode);
if (charcode >= 128) charcode = '-';
return charcode;
}
wchar_t Characters__make_wchar_t_filename_safe(wchar_t charcode) {
charcode = Characters__remove_wchar_t_accent(charcode);
if (charcode >= 128) charcode = '-';
return charcode;
}
#line 135 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__remove_accent(int charcode) {
switch (charcode) {
case 0xC0: case 0xC1: case 0xC2: case 0xC3:
case 0xC4: case 0xC5: charcode = 'A'; break;
case 0xE0: case 0xE1: case 0xE2: case 0xE3:
case 0xE4: case 0xE5: charcode = 'a'; break;
case 0xC8: case 0xC9: case 0xCA: case 0xCB: charcode = 'E'; break;
case 0xE8: case 0xE9: case 0xEA: case 0xEB: charcode = 'e'; break;
case 0xCC: case 0xCD: case 0xCE: case 0xCF: charcode = 'I'; break;
case 0xEC: case 0xED: case 0xEE: case 0xEF: charcode = 'i'; break;
case 0xD2: case 0xD3: case 0xD4: case 0xD5:
case 0xD6: case 0xD8: charcode = 'O'; break;
case 0xF2: case 0xF3: case 0xF4: case 0xF5:
case 0xF6: case 0xF8: charcode = 'o'; break;
case 0xD9: case 0xDA: case 0xDB: case 0xDC: charcode = 'U'; break;
case 0xF9: case 0xFA: case 0xFB: case 0xFC: charcode = 'u'; break;
case 0xDD: charcode = 'Y'; break;
case 0xFD: charcode = 'y'; break;
case 0xD1: charcode = 'N'; break;
case 0xF1: charcode = 'n'; break;
case 0xC7: charcode = 'C'; break;
case 0xE7: charcode = 'c'; break;
case 0xDF: charcode = 's'; break;
}
return charcode;
}
wchar_t Characters__remove_wchar_t_accent(wchar_t charcode) {
return (wchar_t) Characters__remove_accent((int) charcode);
}
#line 169 "inweb/foundation-module/Chapter 4/Characters.w"
int Characters__isalphabetic(int letter) {
return Characters__isalpha((wchar_t) Characters__remove_accent(letter));
}
#line 21 "inweb/foundation-module/Chapter 4/C Strings.w"
#line 25 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__strlen_unbounded(const char *p) {
return (int) strlen(p);
}
#line 35 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__check_len(int n) {
if ((n > MAX_STRING_LENGTH) || (n < 0)) Errors__fatal("String overflow\n");
return n;
}
#line 44 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__len(char *str) {
for (int i=0; i<=MAX_STRING_LENGTH; i++)
if (str[i] == 0) return i;
str[MAX_STRING_LENGTH] = 0;
return MAX_STRING_LENGTH;
}
#line 55 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__copy(char *to, char *from) {
CStrings__check_len(CStrings__len(from));
int i;
for (i=0; ((from[i]) && (i < MAX_STRING_LENGTH)); i++) to[i] = from[i];
to[i] = 0;
}
#line 65 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__eq(char *A, char *B) {
return (CStrings__cmp(A, B) == 0)?TRUE:FALSE;
}
int CStrings__ne(char *A, char *B) {
return (CStrings__cmp(A, B) == 0)?FALSE:TRUE;
}
#line 76 "inweb/foundation-module/Chapter 4/C Strings.w"
int CStrings__cmp(char *A, char *B) {
if ((A == NULL) || (A[0] == 0)) {
if ((B == NULL) || (B[0] == 0)) return 0;
return -1;
}
if ((B == NULL) || (B[0] == 0)) return 1;
return strcmp(A, B);
}
#line 89 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__transcode_ISO_string_to_UTF8(char *p, char *dest) {
int i, j;
for (i=0, j=0; p[i]; i++) {
int charcode = (int) (((unsigned char *)p)[i]);
if (charcode >= 128) {
dest[j++] = (char) (0xC0 + (charcode >> 6));
dest[j++] = (char) (0x80 + (charcode & 0x3f));
} else {
dest[j++] = p[i];
}
}
dest[j] = 0;
}
#line 110 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__truncated_strcpy(char *to, char *from, int max) {
int i;
for (i=0; ((from[i]) && (i<max-1)); i++) to[i] = from[i];
to[i] = 0;
}
#line 128 "inweb/foundation-module/Chapter 4/C Strings.w"
#line 130 "inweb/foundation-module/Chapter 4/C Strings.w"
char *CStrings__park_string(char *from) {
string_storage_area *ssa = CREATE(string_storage_area);
ssa->capacity = (int) CStrings__strlen_unbounded(from) + 1;
ssa->storage_at = Memory__malloc(ssa->capacity, STRING_STORAGE_MREASON);
strcpy(ssa->storage_at, from);
return ssa->storage_at;
}
#line 141 "inweb/foundation-module/Chapter 4/C Strings.w"
void CStrings__free_ssas(void) {
string_storage_area *ssa;
LOOP_OVER(ssa, string_storage_area)
Memory__I7_free(ssa->storage_at, STRING_STORAGE_MREASON, ssa->capacity);
}
#line 14 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__len(wchar_t *p) {
return (int) wcslen(p);
}
#line 21 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__cmp(wchar_t *A, wchar_t *B) {
return wcscmp(A, B);
}
#line 26 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__atoi(wchar_t *p) {
return (int) wcstol(p, NULL, 10);
}
#line 38 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__new(void) {
return Str__new_with_capacity(32);
}
text_stream *Str__new_with_capacity(int c) {
text_stream *S = CREATE(text_stream);
if (Streams__open_to_memory(S, c)) return S;
return NULL;
}
void Str__dispose_of(text_stream *text) {
if (text) STREAM_CLOSE(text);
}
#line 57 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__duplicate(text_stream *E) {
if (E == NULL) return Str__new();
text_stream *S = CREATE(text_stream);
if (Streams__open_to_memory(S, Str__len(E)+4)) {
Streams__copy(S, E);
return S;
}
return NULL;
}
#line 73 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__new_from_wide_string(const wchar_t *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_wide_string(S, C_string)) return S;
return NULL;
}
text_stream *Str__new_from_ISO_string(const char *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_ISO_string(S, C_string)) return S;
return NULL;
}
text_stream *Str__new_from_UTF8_string(const char *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_UTF8_string(S, C_string)) return S;
return NULL;
}
text_stream *Str__new_from_locale_string(const char *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_locale_string(S, C_string)) return S;
return NULL;
}
#line 100 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__from_wide_string(text_stream *S, wchar_t *c_string) {
if (Streams__open_from_wide_string(S, c_string) == FALSE) return NULL;
return S;
}
text_stream *Str__from_locale_string(text_stream *S, char *c_string) {
if (Streams__open_from_locale_string(S, c_string) == FALSE) return NULL;
return S;
}
#line 113 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_to_ISO_string(char *C_string, text_stream *S, int buffer_size) {
Streams__write_as_ISO_string(C_string, S, buffer_size);
}
void Str__copy_to_UTF8_string(char *C_string, text_stream *S, int buffer_size) {
Streams__write_as_UTF8_string(C_string, S, buffer_size);
}
void Str__copy_to_wide_string(wchar_t *C_string, text_stream *S, int buffer_size) {
Streams__write_as_wide_string(C_string, S, buffer_size);
}
void Str__copy_to_locale_string(char *C_string, text_stream *S, int buffer_size) {
Streams__write_as_locale_string(C_string, S, buffer_size);
}
#line 132 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__atoi(text_stream *S, int index) {
char buffer[32];
int i = 0;
for (string_position P = Str__at(S, index);
((i < 31) && (P.index < Str__len(S))); P = Str__forward(P))
buffer[i++] = (char) Str__get(P);
buffer[i] = 0;
return atoi(buffer);
}
#line 146 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__len(text_stream *S) {
return Streams__get_position(S);
}
#line 163 "inweb/foundation-module/Chapter 4/String Manipulation.w"
#line 167 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__start(text_stream *S) {
string_position P; P.S = S; P.index = 0; return P;
}
string_position Str__at(text_stream *S, int i) {
if (i < 0) i = 0;
if (i > Str__len(S)) i = Str__len(S);
string_position P; P.S = S; P.index = i; return P;
}
string_position Str__end(text_stream *S) {
string_position P; P.S = S; P.index = Str__len(S); return P;
}
#line 184 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__back(string_position P) {
if (P.index > 0) P.index--; return P;
}
string_position Str__forward(string_position P) {
P.index++; return P;
}
string_position Str__plus(string_position P, int increment) {
P.index += increment; return P;
}
int Str__width_between(string_position P1, string_position P2) {
if (P1.S != P2.S) internal_error("positions are in different strings");
return P2.index - P1.index;
}
int Str__in_range(string_position P) {
if (P.index < Str__len(P.S)) return TRUE;
return FALSE;
}
int Str__index(string_position P) {
return P.index;
}
#line 222 "inweb/foundation-module/Chapter 4/String Manipulation.w"
wchar_t Str__get(string_position P) {
if ((P.S == NULL) || (P.index < 0)) return 0;
return Streams__get_char_at_index(P.S, P.index);
}
wchar_t Str__get_at(text_stream *S, int index) {
if ((S == NULL) || (index < 0)) return 0;
return Streams__get_char_at_index(S, index);
}
wchar_t Str__get_first_char(text_stream *S) {
return Str__get(Str__at(S, 0));
}
wchar_t Str__get_last_char(text_stream *S) {
int L = Str__len(S);
if (L == 0) return 0;
return Str__get(Str__at(S, L-1));
}
#line 243 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__put(string_position P, wchar_t C) {
if (P.index < 0) internal_error("wrote before start of string");
if (P.S == NULL) internal_error("wrote to null stream");
int ext = Str__len(P.S);
if (P.index > ext) internal_error("wrote beyond end of string");
if (P.index == ext) {
if (C) PUT_TO(P.S, (int) C);
return;
}
Streams__put_char_at_index(P.S, P.index, C);
}
void Str__put_at(text_stream *S, int index, wchar_t C) {
Str__put(Str__at(S, index), C);
}
#line 262 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__clear(text_stream *S) {
Str__truncate(S, 0);
}
void Str__truncate(text_stream *S, int len) {
if (len < 0) len = 0;
if (len < Str__len(S)) Str__put(Str__at(S, len), 0);
}
#line 274 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__remove_indentation(text_stream *S, int spaces_per_tab) {
int spaces_in = 0, tab_stops_of_indentation = 0;
while (Characters__is_space_or_tab(Str__get_first_char(S))) {
if (Str__get_first_char(S) == '\t') {
spaces_in = 0;
tab_stops_of_indentation++;
} else {
spaces_in++;
if (spaces_in == spaces_per_tab) {
tab_stops_of_indentation++;
spaces_in = 0;
}
}
Str__delete_first_character(S);
}
if (spaces_in > 0) {
TEMPORARY_TEXT(respaced)
while (spaces_in > 0) { PUT_TO(respaced, ' '); spaces_in--; }
WRITE_TO(respaced, "%S", S);
Str__clear(S);
Str__copy(S, respaced);
DISCARD_TEXT(respaced)
}
return tab_stops_of_indentation;
}
void Str__rectify_indentation(text_stream *S, int spaces_per_tab) {
TEMPORARY_TEXT(tail)
WRITE_TO(tail, "%S", S);
int N = Str__remove_indentation(tail, spaces_per_tab);
Str__clear(S);
for (int i=0; i<N; i++) for (int j=0; j<spaces_per_tab; j++) PUT_TO(S, ' ');
WRITE_TO(S, "%S", tail);
DISCARD_TEXT(tail)
}
#line 313 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__concatenate(text_stream *S1, text_stream *S2) {
Streams__copy(S1, S2);
}
void Str__copy(text_stream *S1, text_stream *S2) {
if (S1 == S2) return;
Str__clear(S1);
Streams__copy(S1, S2);
}
void Str__copy_tail(text_stream *S1, text_stream *S2, int from) {
Str__clear(S1);
int L = Str__len(S2);
if (from < L)
for (string_position P = Str__at(S2, from); P.index < L; P = Str__forward(P))
PUT_TO(S1, Str__get(P));
}
#line 334 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_ISO_string(text_stream *S, char *C_string) {
Str__clear(S);
Streams__write_ISO_string(S, C_string);
}
void Str__copy_UTF8_string(text_stream *S, char *C_string) {
Str__clear(S);
Streams__write_UTF8_string(S, C_string);
}
void Str__copy_wide_string(text_stream *S, wchar_t *C_string) {
Str__clear(S);
Streams__write_wide_string(S, C_string);
}
#line 353 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__eq(text_stream *S1, text_stream *S2) {
if (Str__cmp(S1, S2) == 0) return TRUE;
return FALSE;
}
int Str__eq_insensitive(text_stream *S1, text_stream *S2) {
if ((Str__len(S1) == Str__len(S2)) && (Str__cmp_insensitive(S1, S2) == 0)) return TRUE;
return FALSE;
}
int Str__ne(text_stream *S1, text_stream *S2) {
if (Str__cmp(S1, S2) != 0) return TRUE;
return FALSE;
}
int Str__ne_insensitive(text_stream *S1, text_stream *S2) {
if ((Str__len(S1) != Str__len(S2)) || (Str__cmp_insensitive(S1, S2) != 0)) return TRUE;
return FALSE;
}
#line 390 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__cmp(text_stream *S1, text_stream *S2) {
int L1 = Str__len(S1), L2 = Str__len(S2), M = L1;
if (L2 < M) M = L2;
for (int i=0; i<M; i++) {
int d = (int) Str__get_at(S1, i) - (int) Str__get_at(S2, i);
if (d != 0) return d;
}
return L1 - L2;
}
int Str__cmp_insensitive(text_stream *S1, text_stream *S2) {
for (string_position P = Str__start(S1), Q = Str__start(S2);
(P.index < Str__len(S1)) && (Q.index < Str__len(S2));
P = Str__forward(P), Q = Str__forward(Q)) {
int d = tolower((int) Str__get(P)) - tolower((int) Str__get(Q));
if (d != 0) return d;
}
return Str__len(S1) - Str__len(S2);
}
#line 421 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__prefix_eq(text_stream *S1, text_stream *S2, int N) {
int L1 = Str__len(S1), L2 = Str__len(S2);
if ((N > L1) || (N > L2)) return FALSE;
for (int i=0; i<N; i++)
if (Str__get_at(S1, i) != Str__get_at(S2, i))
return FALSE;
return TRUE;
}
int Str__suffix_eq(text_stream *S1, text_stream *S2, int N) {
int L1 = Str__len(S1), L2 = Str__len(S2);
if ((N > L1) || (N > L2)) return FALSE;
for (int i=1; i<=N; i++)
if (Str__get_at(S1, L1-i) != Str__get_at(S2, L2-i))
return FALSE;
return TRUE;
}
int Str__begins_with_wide_string(text_stream *S, wchar_t *prefix) {
if ((prefix == NULL) || (*prefix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0; prefix[i]; i++)
if (Str__get_at(S, i) != prefix[i])
return FALSE;
return TRUE;
}
int Str__ends_with_wide_string(text_stream *S, wchar_t *suffix) {
if ((suffix == NULL) || (*suffix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0, at = Str__len(S) - (int) wcslen(suffix); suffix[i]; i++)
if (Str__get_at(S, at+i) != suffix[i])
return FALSE;
return TRUE;
}
#line 458 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__eq_wide_string(text_stream *S1, wchar_t *S2) {
if (S2 == NULL) return (Str__len(S1) == 0)?TRUE:FALSE;
if (Str__len(S1) == (int) wcslen(S2)) {
int i=0;
LOOP_THROUGH_TEXT(P, S1)
if (Str__get(P) != S2[i++])
return FALSE;
return TRUE;
}
return FALSE;
}
int Str__eq_narrow_string(text_stream *S1, char *S2) {
if (S2 == NULL) return (Str__len(S1) == 0)?TRUE:FALSE;
if (Str__len(S1) == (int) strlen(S2)) {
int i=0;
LOOP_THROUGH_TEXT(P, S1)
if (Str__get(P) != (wchar_t) S2[i++])
return FALSE;
return TRUE;
}
return FALSE;
}
int Str__ne_wide_string(text_stream *S1, wchar_t *S2) {
return (Str__eq_wide_string(S1, S2)?FALSE:TRUE);
}
#line 487 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__is_whitespace(text_stream *S) {
LOOP_THROUGH_TEXT(pos, S)
if (Characters__is_space_or_tab(Str__get(pos)) == FALSE)
return FALSE;
return TRUE;
}
#line 497 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__trim_white_space(text_stream *S) {
int len = Str__len(S), i = 0, j = 0;
string_position F = Str__start(S);
LOOP_THROUGH_TEXT(P, S) {
if (!(Characters__is_space_or_tab(Str__get(P)))) { F = P; break; }
i++;
}
LOOP_BACKWARDS_THROUGH_TEXT(Q, S) {
if (!(Characters__is_space_or_tab(Str__get(Q)))) break;
j++;
}
if (i+j > Str__len(S)) Str__truncate(S, 0);
else {
len = len - j;
Str__truncate(S, len);
if (i > 0) {
string_position P = Str__start(S);
wchar_t c = 0;
do {
c = Str__get(F);
Str__put(P, c);
P = Str__forward(P); F = Str__forward(F);
} while (c != 0);
len = len - i;
Str__truncate(S, len);
}
}
}
int Str__trim_white_space_at_end(text_stream *S) {
int shortened = FALSE;
for (int j = Str__len(S)-1; j >= 0; j--) {
if (Characters__is_space_or_tab(Str__get_at(S, j))) {
Str__truncate(S, j);
shortened = TRUE;
} else break;
}
return shortened;
}
int Str__trim_all_white_space_at_end(text_stream *S) {
int shortened = FALSE;
for (int j = Str__len(S)-1; j >= 0; j--) {
if (Characters__is_babel_whitespace(Str__get_at(S, j))) {
Str__truncate(S, j);
shortened = TRUE;
} else break;
}
return shortened;
}
#line 551 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__delete_first_character(text_stream *S) {
Str__delete_nth_character(S, 0);
}
void Str__delete_last_character(text_stream *S) {
if (Str__len(S) > 0)
Str__truncate(S, Str__len(S) - 1);
}
void Str__delete_nth_character(text_stream *S, int n) {
for (string_position P = Str__at(S, n); P.index < Str__len(P.S); P = Str__forward(P))
Str__put(P, Str__get(Str__forward(P)));
}
void Str__delete_n_characters(text_stream *S, int n) {
int L = Str__len(S) - n;
if (L <= 0) Str__clear(S);
else {
for (int i=0; i<L; i++)
Str__put(Str__at(S, i), Str__get(Str__at(S, i+n)));
Str__truncate(S, L);
}
}
#line 578 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__substr(OUTPUT_STREAM, string_position from, string_position to) {
if (from.S != to.S) internal_error("substr on two different strings");
for (int i = from.index; i < to.index; i++)
PUT(Str__get_at(from.S, i));
}
int Str__includes_character(text_stream *S, wchar_t c) {
if (S)
LOOP_THROUGH_TEXT(pos, S)
if (Str__get(pos) == c)
return TRUE;
return FALSE;
}
int Str__includes_wide_string_at(text_stream *S, wchar_t *prefix, int j) {
if ((prefix == NULL) || (*prefix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0; prefix[i]; i++)
if (Str__get_at(S, i+j) != prefix[i])
return FALSE;
return TRUE;
}
int Str__includes_wide_string_at_insensitive(text_stream *S, wchar_t *prefix, int j) {
if ((prefix == NULL) || (*prefix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0; prefix[i]; i++)
if (Characters__tolower(Str__get_at(S, i+j)) != Characters__tolower(prefix[i]))
return FALSE;
return TRUE;
}
int Str__includes(text_stream *S, text_stream *T) {
int LS = Str__len(S);
int LT = Str__len(T);
for (int i=0; i<LS-LT; i++) {
int failed = FALSE;
for (int j=0; j<LT; j++)
if (Str__get_at(S, i+j) != Str__get_at(T, j)) {
failed = TRUE;
break;
}
if (failed == FALSE) return TRUE;
}
return FALSE;
}
int Str__includes_at(text_stream *line, int i, text_stream *pattern) {
if (Str__len(pattern) == 0) return FALSE;
if (i < 0) return FALSE;
if (i + Str__len(pattern) > Str__len(line)) return FALSE;
LOOP_THROUGH_TEXT(pos, pattern)
if (Str__get(pos) != Str__get_at(line, i++))
return FALSE;
return TRUE;
}
#line 646 "inweb/foundation-module/Chapter 4/String Manipulation.w"
dictionary *string_literals_dictionary = NULL;
text_stream *Str__literal(wchar_t *wide_C_string) {
text_stream *answer = NULL;
CREATE_MUTEX(mutex);
LOCK_MUTEX(mutex);
{
#line 658 "inweb/foundation-module/Chapter 4/String Manipulation.w"
if (string_literals_dictionary == NULL)
string_literals_dictionary = Dictionaries__new(100, TRUE);
answer = Dictionaries__get_text_literal(string_literals_dictionary, wide_C_string);
if (answer == NULL) {
Dictionaries__create_literal(string_literals_dictionary, wide_C_string);
answer = Dictionaries__get_text_literal(string_literals_dictionary, wide_C_string);
WRITE_TO(answer, "%w", wide_C_string);
Streams__mark_as_read_only(answer);
}
}
#line 652 "inweb/foundation-module/Chapter 4/String Manipulation.w"
;
UNLOCK_MUTEX(mutex);
return answer;
}
#line 20 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__exists(filename *F) {
TEMPORARY_TEXT(pn)
WRITE_TO(pn, "%f", F);
scan_directory *D = Directories__open_from(pn);
DISCARD_TEXT(pn)
if (D) {
Directories__close(D);
return FALSE;
}
FILE *HANDLE = Filenames__fopen(F, "rb");
if (HANDLE == NULL) return FALSE;
fclose(HANDLE);
return TRUE;
}
#line 48 "inweb/foundation-module/Chapter 4/Text Files.w"
#line 52 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__get_line_count(text_file_position *tfp) {
if (tfp == NULL) return 0;
return tfp->line_count;
}
#line 60 "inweb/foundation-module/Chapter 4/Text Files.w"
text_file_position TextFiles__nowhere(void) {
text_file_position tfp;
tfp.text_file_filename = NULL;
tfp.line_count = 0;
tfp.line_position = 0;
tfp.skip_terminator = FALSE;
tfp.actively_scanning = FALSE;
return tfp;
}
text_file_position TextFiles__at(filename *F, int line) {
text_file_position tfp = TextFiles__nowhere();
tfp.text_file_filename = F;
tfp.line_count = line;
return tfp;
}
#line 84 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__read(filename *F, int escape_oddities, char *message, int serious,
void (iterator)(text_stream *, text_file_position *, void *),
text_file_position *start_at, void *state) {
text_file_position tfp;
tfp.ufb = TextFiles__create_ufb();
{
#line 97 "inweb/foundation-module/Chapter 4/Text Files.w"
tfp.handle_when_open = Filenames__fopen(F, "rb");
if (tfp.handle_when_open == NULL) {
if (message == NULL) return 0;
if (serious) Errors__fatal_with_file(message, F);
else { Errors__with_file(message, F); return 0; }
}
}
#line 89 "inweb/foundation-module/Chapter 4/Text Files.w"
;
{
#line 110 "inweb/foundation-module/Chapter 4/Text Files.w"
if (start_at == NULL) {
tfp.line_count = 1;
tfp.line_position = 0;
tfp.skip_terminator = 'X';
} else {
tfp = *start_at;
if (fseek(tfp.handle_when_open, (long int) (tfp.line_position), SEEK_SET)) {
if (serious) Errors__fatal_with_file("unable to seek position in file", F);
Errors__with_file("unable to seek position in file", F);
return 0;
}
}
tfp.actively_scanning = TRUE;
tfp.text_file_filename = F;
}
#line 90 "inweb/foundation-module/Chapter 4/Text Files.w"
;
{
#line 129 "inweb/foundation-module/Chapter 4/Text Files.w"
TEMPORARY_TEXT(line)
int i = 0, c = ' ';
while ((c != EOF) && (tfp.actively_scanning)) {
c = TextFiles__utf8_fgetc(tfp.handle_when_open, NULL, escape_oddities, &tfp.ufb);
if ((c == EOF) || (c == '\x0a') || (c == '\x0d')) {
Str__put_at(line, i, 0);
if ((i > 0) || (c != tfp.skip_terminator)) {
{
#line 153 "inweb/foundation-module/Chapter 4/Text Files.w"
iterator(line, &tfp, state);
tfp.line_count++;
}
#line 136 "inweb/foundation-module/Chapter 4/Text Files.w"
;
if (c == '\x0a') tfp.skip_terminator = '\x0d';
if (c == '\x0d') tfp.skip_terminator = '\x0a';
} else tfp.skip_terminator = 'X';
{
#line 167 "inweb/foundation-module/Chapter 4/Text Files.w"
tfp.line_position = (int) (ftell(tfp.handle_when_open));
if (tfp.line_position == -1) {
if (serious)
Errors__fatal_with_file("unable to determine position in file", F);
else
Errors__with_file("unable to determine position in file", F);
}
}
#line 140 "inweb/foundation-module/Chapter 4/Text Files.w"
;
i = 0;
} else {
Str__put_at(line, i++, (wchar_t) c);
}
}
if ((i > 0) && (tfp.actively_scanning))
{
#line 153 "inweb/foundation-module/Chapter 4/Text Files.w"
iterator(line, &tfp, state);
tfp.line_count++;
}
#line 147 "inweb/foundation-module/Chapter 4/Text Files.w"
;
DISCARD_TEXT(line)
}
#line 91 "inweb/foundation-module/Chapter 4/Text Files.w"
;
fclose(tfp.handle_when_open);
return tfp.line_count;
}
#line 176 "inweb/foundation-module/Chapter 4/Text Files.w"
void TextFiles__read_line(OUTPUT_STREAM, int escape_oddities, text_file_position *tfp) {
Str__clear(OUT);
int i = 0, c = ' ';
while ((c != EOF) && (tfp->actively_scanning)) {
c = TextFiles__utf8_fgetc(tfp->handle_when_open, NULL, escape_oddities, &tfp->ufb);
if ((c == EOF) || (c == '\x0a') || (c == '\x0d')) {
Str__put_at(OUT, i, 0);
if ((i > 0) || (c != tfp->skip_terminator)) {
if (c == '\x0a') tfp->skip_terminator = '\x0d';
if (c == '\x0d') tfp->skip_terminator = '\x0a';
} else tfp->skip_terminator = 'X';
tfp->line_position = (int) (ftell(tfp->handle_when_open));
i = 0;
tfp->line_count++; return;
}
Str__put_at(OUT, i++, (wchar_t) c);
}
if ((i > 0) && (tfp->actively_scanning)) tfp->line_count++;
}
#line 200 "inweb/foundation-module/Chapter 4/Text Files.w"
void TextFiles__lose_interest(text_file_position *tfp) {
tfp->actively_scanning = FALSE;
}
#line 232 "inweb/foundation-module/Chapter 4/Text Files.w"
unicode_file_buffer TextFiles__create_ufb(void) {
unicode_file_buffer ufb;
ufb.ufb_counter = -1;
return ufb;
}
int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities,
unicode_file_buffer *ufb) {
int c = EOF, conts;
if ((ufb) && (ufb->ufb_counter >= 0)) {
if (ufb->unicode_feed_buffer[ufb->ufb_counter] == 0) ufb->ufb_counter = -1;
else return ufb->unicode_feed_buffer[ufb->ufb_counter++];
}
if (from) c = fgetc(from); else if (or_from) c = ((unsigned char) *((*or_from)++));
if (c == EOF) return c; /* ruling out EOF leaves a genuine byte from the file */
if (c<0x80) return c; /* in all other cases, a UTF-8 continuation sequence begins */
{
#line 272 "inweb/foundation-module/Chapter 4/Text Files.w"
if (c<0xC0) return '?'; /* malformed UTF-8 */
if (c<0xE0) { c = c & 0x1f; conts = 1; }
else if (c<0xF0) { c = c & 0xf; conts = 2; }
else if (c<0xF8) { c = c & 0x7; conts = 3; }
else if (c<0xFC) { c = c & 0x3; conts = 4; }
else { c = c & 0x1; conts = 5; }
while (conts > 0) {
int d = EOF;
if (from) d = fgetc(from); else if (or_from) d = ((unsigned char) *((*or_from)++));
if (d == EOF) return '?'; /* malformed UTF-8 */
c = c << 6;
c = c + (d & 0x3F);
conts--;
}
}
#line 250 "inweb/foundation-module/Chapter 4/Text Files.w"
;
{
#line 301 "inweb/foundation-module/Chapter 4/Text Files.w"
if ((c == 0xa1) || (c == 0xa3) || (c == 0xbf)) return c; /* pound sign, inverted ! and ? */
if (c == 0xd7) return 'x'; /* convert multiplication sign to lower case "x" */
if ((c >= 0xc0) && (c <= 0xff)) { /* accented West European letters, but... */
if ((c != 0xd0) && (c != 0xf0) && /* not Icelandic eths */
(c != 0xde) && (c != 0xfe) && /* nor Icelandic thorns */
(c != 0xf7)) /* nor division signs */
return c;
}
}
#line 251 "inweb/foundation-module/Chapter 4/Text Files.w"
;
if (escape_oddities)
{
#line 316 "inweb/foundation-module/Chapter 4/Text Files.w"
if (c == 0x85) return '\x0d'; /* NEL, or "next line" */
if (c == 0xa0) return ' '; /* non-breaking space */
if ((c >= 0x2000) && (c <= 0x200a)) return ' '; /* space variants */
if ((c >= 0x2010) && (c <= 0x2014)) return '-'; /* rules and dashes */
if ((c >= 0x2018) && (c <= 0x2019)) return '\''; /* smart single quotes */
if ((c >= 0x201c) && (c <= 0x201d)) return '"'; /* smart double quotes */
if ((c >= 0x2028) && (c <= 0x2029)) return '\x0d'; /* fancy newlines */
}
#line 252 "inweb/foundation-module/Chapter 4/Text Files.w"
;
if (c == 0xFEFF) return c; /* the Unicode BOM non-character */
if (escape_oddities == FALSE) return c;
if (ufb) {
sprintf(ufb->unicode_feed_buffer, "[unicode %d]", c);
ufb->ufb_counter = 1;
return '[';
}
return '?';
}
#line 28 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *header,
linked_list *special_macros, general_pointer specifics, wchar_t comment_char,
int encoding) {
struct text_stream processed_file;
if (STREAM_OPEN_TO_FILE(&processed_file, F, encoding) == FALSE)
Errors__fatal_with_file("unable to write tangled file", F);
text_stream *OUT = &processed_file;
WRITE("%S", header);
preprocessor_state PPS;
{
#line 79 "inweb/foundation-module/Chapter 4/Preprocessor.w"
PPS.dest = Str__new();
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;
PPS.comment_character = comment_char;
}
#line 38 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
TextFiles__read(prototype, FALSE, "can't open prototype file",
TRUE, Preprocessor__scan_line, NULL, &PPS);
for (int i=0; i<Str__len(PPS.dest); i++) {
wchar_t c = Str__get_at(PPS.dest, i);
if (c == PROTECTED_OPEN_BRACE_PPCHAR) PUT('{');
else if (c == PROTECTED_CLOSE_BRACE_PPCHAR) PUT('}');
else if (c != PROTECTED_BLANK_PPCHAR) PUT(c);
}
STREAM_CLOSE(OUT);
}
#line 70 "inweb/foundation-module/Chapter 4/Preprocessor.w"
#line 77 "inweb/foundation-module/Chapter 4/Preprocessor.w"
#line 95 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__set_loop_var_name(preprocessor_loop *loop, text_stream *name) {
loop->loop_var_name = Str__duplicate(name);
}
void Preprocessor__add_loop_iteration(preprocessor_loop *loop, text_stream *value) {
ADD_TO_LINKED_LIST(Str__duplicate(value), text_stream, loop->iterations);
}
#line 110 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__scan_line(text_stream *line, text_file_position *tfp, void *X) {
preprocessor_state *PPS = (preprocessor_state *) X;
{
#line 123 "inweb/foundation-module/Chapter 4/Preprocessor.w"
LOOP_THROUGH_TEXT(pos, line) {
wchar_t c = Str__get(pos);
if (c == PPS->comment_character) return;
if (Characters__is_whitespace(c) == FALSE) break;
}
}
#line 112 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
{
#line 130 "inweb/foundation-module/Chapter 4/Preprocessor.w"
for (int i = 0; i < Str__len(line); i++) {
wchar_t c = Str__get_at(line, i);
if (c == '\\') {
wchar_t d = Str__get_at(line, i+1);
switch (d) {
case '{':
Str__put_at(line, i, PROTECTED_OPEN_BRACE_PPCHAR);
Str__put_at(line, i+1, PROTECTED_BLANK_PPCHAR);
break;
case '}':
Str__put_at(line, i, PROTECTED_CLOSE_BRACE_PPCHAR);
Str__put_at(line, i+1, PROTECTED_BLANK_PPCHAR);
break;
case '\\':
Str__put_at(line, i+1, PROTECTED_BLANK_PPCHAR);
break;
case ' ': case '\t': case '\n': case '\r': case 0: break;
default:
Errors__in_text_file("backslash '\\' must be followed by '{', '}' or '\\'", tfp);
break;
}
}
}
}
#line 113 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
{
#line 155 "inweb/foundation-module/Chapter 4/Preprocessor.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L" *{define: *(%C+) *} *"))
{
#line 163 "inweb/foundation-module/Chapter 4/Preprocessor.w"
if (PPS->defining)
Errors__in_text_file("nested definitions are not allowed", tfp);
text_stream *name = mr.exp[0];
text_stream *parameter_specification = Str__new();
PPS->defining = Preprocessor__new_macro(PPS->known_macros, name,
parameter_specification, Preprocessor__default_expander, tfp);
Regexp__dispose_of(&mr);
return;
}
#line 156 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
if (Regexp__match(&mr, line, L" *{define: *(%C+) (%c*)} *"))
{
#line 173 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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, Preprocessor__default_expander, tfp);
Regexp__dispose_of(&mr);
return;
}
#line 157 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
if (Regexp__match(&mr, line, L" *{end-define} *"))
{
#line 188 "inweb/foundation-module/Chapter 4/Preprocessor.w"
if (PPS->defining == NULL)
Errors__in_text_file("{end-define} without {define: ...}", tfp);
PPS->defining = NULL;
Regexp__dispose_of(&mr);
return;
}
#line 158 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
if (PPS->defining)
{
#line 183 "inweb/foundation-module/Chapter 4/Preprocessor.w"
Preprocessor__add_line_to_macro(PPS->defining, line, tfp);
Regexp__dispose_of(&mr);
return;
}
#line 159 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
Regexp__dispose_of(&mr);
}
#line 114 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
Preprocessor__expand(line, tfp, PPS);
{
#line 195 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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;
}
#line 116 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
}
#line 218 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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) {
{
#line 255 "inweb/foundation-module/Chapter 4/Preprocessor.w"
if (Preprocessor__acceptable_variable_name(braced_matter)) {
{
#line 316 "inweb/foundation-module/Chapter 4/Preprocessor.w"
Preprocessor__expand(before_matter, tfp, PPS);
if (PPS->repeat_sp > 0) {
WRITE_TO(PPS->dest, "{%S}", braced_matter);
} else {
{
#line 361 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_variable *var =
Preprocessor__find_variable(braced_matter, PPS->stack_frame);
if (var) {
WRITE_TO(PPS->dest, "%S", Preprocessor__read_variable(var));
} else {
TEMPORARY_TEXT(erm)
WRITE_TO(erm, "unknown variable '%S'", braced_matter);
Errors__in_text_file_S(erm, tfp);
DISCARD_TEXT(erm)
}
}
#line 320 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
}
Preprocessor__expand(after_matter, tfp, PPS);
}
#line 256 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
} else {
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];
}
{
#line 283 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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_loop))
identifier = loop_mm->identifier;
} else {
if ((loop_mm->span) && (loop_mm->begins_loop))
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_loop))
identifier = loop_mm->identifier;
} else {
if ((loop_mm->span) && (loop_mm->ends_loop))
identifier = loop_mm->identifier;
}
}
DISCARD_TEXT(end_name)
}
}
#line 265 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
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 {
{
#line 332 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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_loop)) {
PPS->shadow_sp++;
}
if ((mm) && (mm->ends_loop)) {
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 {
{
#line 376 "inweb/foundation-module/Chapter 4/Preprocessor.w"
text_stream *parameter_values[MAX_PP_MACRO_PARAMETERS];
for (int i=0; i<MAX_PP_MACRO_PARAMETERS; i++) parameter_values[i] = NULL;
{
#line 391 "inweb/foundation-module/Chapter 4/Preprocessor.w"
match_results mr = Regexp__create_mr();
while (Regexp__match(&mr, parameter_settings, L" *(%C+): *(%c*)")) {
text_stream *setting = mr.exp[0];
text_stream *value = mr.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(&mr);
if (Str__is_whitespace(parameter_settings) == FALSE)
Errors__in_text_file("parameter list is malformed", tfp);
}
#line 378 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
{
#line 426 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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)
}
}
#line 379 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
preprocessor_loop *loop = NULL;
if (mm->begins_loop)
{
#line 440 "inweb/foundation-module/Chapter 4/Preprocessor.w"
if (PPS->repeat_sp >= MAX_PREPROCESSOR_LOOP_DEPTH) {
Errors__in_text_file("repetition too deep", tfp);
} else {
loop = &(PPS->repeat_data[PPS->repeat_sp++]);
PPS->shadow_sp = 1;
Preprocessor__set_loop_var_name(loop, TL_IS_3);
loop->iterations = NEW_LINKED_LIST(text_stream);
loop->repeat_is_block = TRUE;
if (mm->span) loop->repeat_is_block = FALSE;
loop->repeat_saved_dest = PPS->dest;
PPS->dest = Str__new();
}
}
#line 382 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
(*(mm->expander))(mm, PPS, parameter_values, loop, tfp);
}
#line 351 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
if (mm->suppress_newline_after_expanding) PPS->suppress_newline = TRUE;
}
Preprocessor__expand(after_matter, tfp, PPS);
}
#line 274 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
}
Regexp__dispose_of(&mr);
}
}
#line 241 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
} else {
WRITE_TO(PPS->dest, "%S", text);
}
DISCARD_TEXT(before_matter)
DISCARD_TEXT(braced_matter)
DISCARD_TEXT(after_matter)
}
#line 457 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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;
}
#line 476 "inweb/foundation-module/Chapter 4/Preprocessor.w"
text_stream *Preprocessor__read_variable(preprocessor_variable *var) {
if (var == NULL) internal_error("no such pp variable");
return var->value;
}
void Preprocessor__write_variable(preprocessor_variable *var, text_stream *val) {
if (var == NULL) internal_error("no such pp variable");
var->value = Str__duplicate(val);
}
#line 496 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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(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;
}
#line 528 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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);
Preprocessor__write_variable(var, TL_IS_4);
ADD_TO_LINKED_LIST(var, preprocessor_variable, in_set->variables);
}
return var;
}
#line 587 "inweb/foundation-module/Chapter 4/Preprocessor.w"
#line 594 "inweb/foundation-module/Chapter 4/Preprocessor.w"
#line 605 "inweb/foundation-module/Chapter 4/Preprocessor.w"
preprocessor_macro *Preprocessor__new_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification,
void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *),
text_file_position *tfp) {
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);
{
#line 619 "inweb/foundation-module/Chapter 4/Preprocessor.w"
new_macro->identifier = Str__duplicate(name);
new_macro->no_parameters = 0;
new_macro->no_lines = 0;
new_macro->expander = expander;
new_macro->begins_loop = FALSE;
new_macro->ends_loop = FALSE;
new_macro->loop_name = NULL;
new_macro->span = FALSE;
new_macro->suppress_newline_after_expanding = TRUE;
new_macro->suppress_whitespace_when_expanding = TRUE;
}
#line 612 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
{
#line 633 "inweb/foundation-module/Chapter 4/Preprocessor.w"
text_stream *spec = Str__duplicate(parameter_specification);
match_results mr = Regexp__create_mr();
while (Regexp__match(&mr, spec, L" *(%C+): *(%C+) *(%c*)")) {
text_stream *par_name = mr.exp[0];
text_stream *token_name = mr.exp[1];
Str__clear(spec);
Str__copy(spec, mr.exp[2]);
if (new_macro->no_parameters >= MAX_PP_MACRO_PARAMETERS) {
Errors__in_text_file("too many parameters in this definition", tfp);
} else {
{
#line 651 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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;
}
#line 643 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
}
}
Regexp__dispose_of(&mr);
if (Str__is_whitespace(spec) == FALSE)
Errors__in_text_file("parameter list for this definition is malformed", tfp);
}
#line 613 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
ADD_TO_LINKED_LIST(new_macro, preprocessor_macro, L);
return new_macro;
}
#line 665 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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);
}
}
#line 683 "inweb/foundation-module/Chapter 4/Preprocessor.w"
linked_list *Preprocessor__list_of_reserved_macros(linked_list *special_macros) {
linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
Preprocessor__new_loop_macro(L, TL_IS_5, TL_IS_6,
Preprocessor__repeat_expander, NULL);
Preprocessor__new_macro(L, TL_IS_7, TL_IS_8,
Preprocessor__set_expander, NULL);
preprocessor_macro *mm;
LOOP_OVER_LINKED_LIST(mm, preprocessor_macro, special_macros)
ADD_TO_LINKED_LIST(mm, preprocessor_macro, L);
return L;
}
void Preprocessor__do_not_suppress_whitespace(preprocessor_macro *mm) {
mm->suppress_newline_after_expanding = FALSE;
mm->suppress_whitespace_when_expanding = FALSE;
}
void Preprocessor__new_loop_macro(linked_list *L, text_stream *name,
text_stream *parameter_specification,
void (*expander)(preprocessor_macro *, preprocessor_state *, text_stream **, preprocessor_loop *, text_file_position *),
text_file_position *tfp) {
TEMPORARY_TEXT(subname)
WRITE_TO(subname, "%S-block", name);
preprocessor_macro *mm = Preprocessor__new_macro(L, subname, parameter_specification, expander, tfp);
mm->begins_loop = TRUE;
mm->loop_name = Str__duplicate(name);
Str__clear(subname);
WRITE_TO(subname, "end-%S-block", name);
mm = Preprocessor__new_macro(L, subname, NULL, Preprocessor__end_loop_expander, tfp);
mm->ends_loop = TRUE;
mm->loop_name = Str__duplicate(name);
Str__clear(subname);
WRITE_TO(subname, "%S-span", name);
mm = Preprocessor__new_macro(L, subname, parameter_specification, expander, tfp);
mm->begins_loop = TRUE;
mm->loop_name = Str__duplicate(name);
mm->span = TRUE;
Preprocessor__do_not_suppress_whitespace(mm);
Str__clear(subname);
WRITE_TO(subname, "end-%S-span", name);
mm = Preprocessor__new_macro(L, subname, NULL, Preprocessor__end_loop_expander, tfp);
mm->ends_loop = TRUE;
mm->loop_name = Str__duplicate(name);
mm->span = TRUE;
Preprocessor__do_not_suppress_whitespace(mm);
DISCARD_TEXT(subname)
}
#line 740 "inweb/foundation-module/Chapter 4/Preprocessor.w"
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;
}
#line 755 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__default_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, 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);
Preprocessor__write_variable(var, 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;
}
#line 772 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__set_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, 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);
Preprocessor__write_variable(var, value);
}
#line 787 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__repeat_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
text_stream *with = parameter_values[0];
text_stream *in = parameter_values[1];
Preprocessor__set_loop_var_name(loop, 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);
Preprocessor__add_loop_iteration(loop, value);
Str__clear(in);
Str__copy(in, mr.exp[1]);
}
Regexp__dispose_of(&mr);
text_stream *value = in;
Str__trim_white_space(value);
Preprocessor__add_loop_iteration(loop, value);
}
#line 816 "inweb/foundation-module/Chapter 4/Preprocessor.w"
void Preprocessor__end_loop_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
PPS->shadow_sp = 0;
if (PPS->repeat_sp == 0) Errors__in_text_file("end without repeat", tfp);
else {
preprocessor_loop *loop = &(PPS->repeat_data[--(PPS->repeat_sp)]);
text_stream *matter = PPS->dest;
PPS->dest = loop->repeat_saved_dest;
PPS->stack_frame = Preprocessor__new_variable_set(PPS->stack_frame);
preprocessor_variable *loop_var =
Preprocessor__ensure_variable(loop->loop_var_name, PPS->stack_frame);
text_stream *value;
LOOP_OVER_LINKED_LIST(value, text_stream, loop->iterations)
{
#line 835 "inweb/foundation-module/Chapter 4/Preprocessor.w"
Preprocessor__write_variable(loop_var, value);
if (mm->span) {
Preprocessor__expand(matter, tfp, PPS);
} else {
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)
}
}
#line 829 "inweb/foundation-module/Chapter 4/Preprocessor.w"
;
PPS->stack_frame = PPS->stack_frame->outer;
}
}
#line 49 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
#line 77 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
wchar_t *Tries__search(match_trie *T, text_stream *p, wchar_t *add_outcome) {
if (T == NULL) internal_error("no trie to search");
int start, endpoint, delta;
{
#line 140 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
start = 0; endpoint = Str__len(p); delta = 1;
if (T->match_character == TRIE_END) { start = Str__len(p)-1; endpoint = -1; delta = -1; }
}
#line 81 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
;
match_trie *prev = NULL, *pos = T;
{
#line 217 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 84 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
;
int rewind_sp = 0;
int rewind_points[MAX_TRIE_REWIND];
match_trie *rewind_positions[MAX_TRIE_REWIND];
match_trie *rewind_prev_positions[MAX_TRIE_REWIND];
for (int i = start; i != endpoint+delta; i += delta) {
wchar_t group[MAX_TRIE_GROUP_SIZE+1];
int g = 0; /* size of group */
wchar_t c = (i<0)?0:(Str__get_at(p, i)); /* i.e., zero at the two ends of the text */
if ((c >= 0x20) && (c <= 0x7f)) c = Characters__tolower(c); /* normalise it within ASCII */
if (c == 0x20) { c = 0; i = endpoint - delta; } /* force any space to be equivalent to the final 0 */
if (add_outcome) {
wchar_t pairc = 0;
if (c == '<') pairc = '>';
if (c == '>') pairc = '<';
if (pairc) {
int j;
for (j = i+delta; j != endpoint; j += delta) {
wchar_t ch = (j<0)?0:(Str__get_at(p, j));
if (ch == pairc) break;
if (g > MAX_TRIE_GROUP_SIZE) { g = 0; break; }
group[g++] = ch;
}
group[g] = 0;
if (g > 0) i = j;
}
}
if (c == '*') endpoint -= delta;
RewindHere:
{
#line 153 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
int ambig = 0, unambig = 0;
match_trie *point;
for (point = pos; point; point = point->next)
if (Tries__is_ambiguous(point)) ambig++;
else unambig++;
FauxWhileLoop:
if (pos) {
if ((add_outcome == NULL) || (Tries__is_ambiguous(pos) == FALSE))
if (Tries__matches(pos, c)) {
if (pos->match_character == TRIE_ANYTHING) break;
if ((add_outcome == NULL) && (ambig > 0) && (ambig+unambig > 1)
&& (rewind_sp < MAX_TRIE_REWIND)) {
rewind_points[rewind_sp] = i;
rewind_positions[rewind_sp] = pos->next;
rewind_prev_positions[rewind_sp] = prev;
rewind_sp++;
}
{
#line 217 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 171 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
;
continue;
}
pos = pos->next;
goto FauxWhileLoop;
}
}
#line 116 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
;
if (add_outcome == NULL) {
if (rewind_sp > 0) {
i = rewind_points[rewind_sp-1];
pos = rewind_positions[rewind_sp-1];
prev = rewind_prev_positions[rewind_sp-1];
rewind_sp--;
goto RewindHere;
}
return NULL; /* failure! */
}
{
#line 179 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
match_trie *new_pos = NULL;
if (g > 0) {
int nt = TRIE_ANY_GROUP;
wchar_t *from = group;
if (group[0] == '!') { from++; nt = TRIE_NOT_GROUP; }
if (group[(int) Wide__len(group)-1] == '!') {
group[(int) Wide__len(group)-1] = 0; nt = TRIE_NOT_GROUP;
}
new_pos = Tries__new(nt);
wcscpy(new_pos->group_characters, from);
} else if (c == '*') new_pos = Tries__new(TRIE_ANYTHING);
else new_pos = Tries__new(c);
if (prev->on_success == NULL) prev->on_success = new_pos;
else {
match_trie *ppoint = NULL, *point;
for (point = prev->on_success; point; ppoint = point, point = point->next) {
if (new_pos->match_character < point->match_character) {
if (ppoint == NULL) {
new_pos->next = prev->on_success;
prev->on_success = new_pos;
} else {
ppoint->next = new_pos;
new_pos->next = point;
}
break;
}
if (point->next == NULL) {
point->next = new_pos;
break;
}
}
}
pos = new_pos;
{
#line 217 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 214 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
; continue;
}
#line 127 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
;
}
if ((pos) && (pos->match_character == TRIE_ANYTHING))
{
#line 217 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 129 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
;
if ((pos) && (pos->match_outcome)) return pos->match_outcome; /* success! */
if (add_outcome == NULL) return NULL; /* failure! */
if (pos == NULL)
{
#line 225 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
prev->on_success = Tries__new(TRIE_STOP);
prev->on_success->match_outcome = add_outcome;
return add_outcome;
}
#line 134 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
else
{
#line 230 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
prev->on_success = Tries__new(TRIE_STOP);
prev->on_success->match_outcome = add_outcome;
return add_outcome;
}
#line 136 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
;
}
#line 237 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
int Tries__matches(match_trie *pos, int c) {
if (pos->match_character == TRIE_ANYTHING) return TRUE;
if (pos->match_character == TRIE_ANY_GROUP) {
int k;
for (k = 0; pos->group_characters[k]; k++)
if (c == pos->group_characters[k])
return TRUE;
return FALSE;
}
if (pos->match_character == TRIE_NOT_GROUP) {
int k;
for (k = 0; pos->group_characters[k]; k++)
if (c == pos->group_characters[k])
return FALSE;
return TRUE;
}
if (pos->match_character == c) return TRUE;
return FALSE;
}
int Tries__is_ambiguous(match_trie *pos) {
if (pos->match_character == TRIE_ANYTHING) return TRUE;
if (pos->match_character == TRIE_ANY_GROUP) return TRUE;
if (pos->match_character == TRIE_NOT_GROUP) return TRUE;
return FALSE;
}
#line 267 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
match_trie *Tries__new(int mc) {
match_trie *T = CREATE(match_trie);
T->match_character = mc;
T->match_outcome = NULL;
T->on_success = NULL;
T->next = NULL;
return T;
}
#line 288 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
#line 293 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
match_avinue *Tries__new_avinue(int from_start) {
match_avinue *A = CREATE(match_avinue);
A->next = NULL;
A->the_trie = Tries__new(from_start);
return A;
}
void Tries__add_to_avinue(match_avinue *mt, text_stream *from, wchar_t *to) {
if ((mt == NULL) || (mt->the_trie == NULL)) internal_error("null trie");
Tries__search(mt->the_trie, from, to);
}
#line 309 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
match_avinue *Tries__duplicate_avinue(match_avinue *A) {
match_avinue *F = NULL, *FL = NULL;
while (A) {
match_avinue *FN = CREATE(match_avinue);
FN->next = NULL;
FN->the_trie = A->the_trie;
A = A->next;
if (FL) FL->next = FN;
if (F == NULL) F = FN;
FL = FN;
}
return F;
}
#line 327 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
wchar_t *Tries__search_avinue(match_avinue *T, text_stream *p) {
wchar_t *result = NULL;
while ((T) && (result == NULL)) {
result = Tries__search(T->the_trie, p, NULL);
T = T->next;
}
return result;
}
#line 339 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
void Tries__log_avinue(OUTPUT_STREAM, void *vA) {
match_avinue *A = (match_avinue *) vA;
WRITE("Avinue:\n"); INDENT;
int n = 1;
while (A) {
WRITE("Trie %d:\n", n++); INDENT;
Tries__log(OUT, A->the_trie);
OUTDENT;
A = A->next;
}
OUTDENT;
}
void Tries__log(OUTPUT_STREAM, match_trie *T) {
for (; T; T = T->next) {
switch (T->match_character) {
case TRIE_START: WRITE("Start"); break;
case TRIE_END: WRITE("End"); break;
case TRIE_ANYTHING: WRITE("Anything"); break;
case TRIE_ANY_GROUP: WRITE("Group <%w>", T->group_characters); break;
case TRIE_NOT_GROUP: WRITE("Negated group <%w>", T->group_characters); break;
case TRIE_STOP: WRITE("Stop"); break;
case 0: WRITE("00"); break;
default: WRITE("%c", T->match_character); break;
}
if (T->match_outcome) WRITE(" --> %s", T->match_outcome);
WRITE("\n");
if (T->on_success) {
INDENT; Tries__log(OUT, T->on_success); OUTDENT;
}
}
}
#line 10 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__white_space(int c) {
if ((c == ' ') || (c == '\t')) return TRUE;
return FALSE;
}
#line 20 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__identifier_char(int c) {
if ((c == '_') || (c == ':') ||
((c >= 'A') && (c <= 'Z')) ||
((c >= 'a') && (c <= 'z')) ||
((c >= '0') && (c <= '9'))) return TRUE;
return FALSE;
}
#line 35 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__find_expansion(text_stream *text, wchar_t on1, wchar_t on2,
wchar_t off1, wchar_t off2, int *len) {
for (int i = 0; i < Str__len(text); i++)
if ((Str__get_at(text, i) == on1) && (Str__get_at(text, i+1) == on2)) {
for (int j=i+2; j < Str__len(text); j++)
if ((Str__get_at(text, j) == off1) && (Str__get_at(text, j+1) == off2)) {
*len = j+2-i;
return i;
}
}
return -1;
}
#line 51 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__find_open_brace(text_stream *text) {
for (int i=0; i < Str__len(text); i++)
if (Str__get_at(text, i) == '{')
return i;
return -1;
}
#line 62 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__string_is_white_space(text_stream *text) {
LOOP_THROUGH_TEXT(P, text)
if (Regexp__white_space(Str__get(P)) == FALSE)
return FALSE;
return TRUE;
}
#line 119 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
#line 136 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
#line 144 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
match_results Regexp__create_mr(void) {
match_results mr;
mr.no_matched_texts = 0;
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++) {
mr.exp[i] = NULL;
mr.exp_at[i] = -1;
}
return mr;
}
void Regexp__dispose_of(match_results *mr) {
if (mr) {
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
if (mr->exp[i]) {
STREAM_CLOSE(mr->exp[i]);
mr->exp[i] = NULL;
}
mr->no_matched_texts = 0;
}
}
#line 168 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match(match_results *mr, text_stream *text, wchar_t *pattern) {
if (mr) Regexp__prepare(mr);
int rv = (Regexp__match_r(mr, text, pattern, NULL, FALSE) >= 0)?TRUE:FALSE;
if ((mr) && (rv == FALSE)) Regexp__dispose_of(mr);
return rv;
}
int Regexp__match_from(match_results *mr, text_stream *text, wchar_t *pattern,
int x, int allow_partial) {
int match_to = x;
if (x < Str__len(text)) {
if (mr) Regexp__prepare(mr);
match_position at;
at.tpos = x; at.ppos = 0; at.bc = 0; at.bl = 0;
match_to = Regexp__match_r(mr, text, pattern, &at, allow_partial);
if (match_to == -1) {
match_to = x;
if (mr) Regexp__dispose_of(mr);
}
}
return match_to - x;
}
void Regexp__prepare(match_results *mr) {
if (mr) {
mr->no_matched_texts = 0;
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++) {
mr->exp_at[i] = -1;
if (mr->exp[i]) STREAM_CLOSE(mr->exp[i]);
mr->exp_storage[i].match_text_struct =
Streams__new_buffer(
MATCH_TEXT_INITIAL_ALLOCATION, mr->exp_storage[i].match_text_storage);
mr->exp_storage[i].match_text_struct.stream_flags |= FOR_RE_STRF;
mr->exp[i] = &(mr->exp_storage[i].match_text_struct);
}
}
}
#line 207 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match_r(match_results *mr, text_stream *text, wchar_t *pattern,
match_position *scan_from, int allow_partial) {
match_position at;
if (scan_from) at = *scan_from;
else { at.tpos = 0; at.ppos = 0; at.bc = 0; at.bl = 0; }
while ((Str__get_at(text, at.tpos)) || (pattern[at.ppos])) {
if ((allow_partial) && (pattern[at.ppos] == 0)) break;
{
#line 241 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
if (pattern[at.ppos] == '(') {
if (at.bl < MAX_BRACKETED_SUBEXPRESSIONS) at.bracket_nesting[at.bl] = -1;
if (at.bc < MAX_BRACKETED_SUBEXPRESSIONS) {
at.bracket_nesting[at.bl] = at.bc;
at.brackets_start[at.bc] = at.tpos; at.brackets_end[at.bc] = -1;
}
at.bl++; at.bc++; at.ppos++;
continue;
}
if (pattern[at.ppos] == ')') {
at.bl--;
if ((at.bl >= 0) && (at.bl < MAX_BRACKETED_SUBEXPRESSIONS) && (at.bracket_nesting[at.bl] >= 0))
at.brackets_end[at.bracket_nesting[at.bl]] = at.tpos-1;
at.ppos++;
continue;
}
}
#line 214 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
int chcl, /* what class of characters to match: a |*_CHARCLASS| value */
range_from, range_to, /* for |LITERAL_CHARCLASS| only */
reverse = FALSE; /* require a non-match rather than a match */
{
#line 259 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
if (pattern[at.ppos] == 0) return -1;
int len = 0;
chcl = Regexp__get_cclass(pattern, at.ppos, &len, &range_from, &range_to, &reverse);
if (at.ppos+len > Wide__len(pattern)) internal_error("Yikes");
else at.ppos += len;
}
#line 219 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
int rep_from = 1, rep_to = 1; /* minimum and maximum number of repetitions */
int greedy = TRUE; /* go for a maximal-length match if possible */
{
#line 269 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
if (chcl == WHITESPACE_CHARCLASS) {
rep_from = 1; rep_to = Str__len(text)-at.tpos;
}
if (pattern[at.ppos] == '+') {
rep_from = 1; rep_to = Str__len(text)-at.tpos; at.ppos++;
} else if (pattern[at.ppos] == '*') {
rep_from = 0; rep_to = Str__len(text)-at.tpos; at.ppos++;
}
if (pattern[at.ppos] == '?') { greedy = FALSE; at.ppos++; }
}
#line 223 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
int reps = 0;
{
#line 280 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
for (reps = 0; ((Str__get_at(text, at.tpos+reps)) && (reps < rep_to)); reps++)
if (Regexp__test_cclass(Str__get_at(text, at.tpos+reps), chcl,
range_from, range_to, pattern, reverse) == FALSE)
break;
}
#line 226 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
if (reps < rep_from) return -1;
/* we can now accept anything from |rep_from| to |reps| repetitions */
if (rep_from == reps) { at.tpos += reps; continue; }
{
#line 286 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int from = rep_from, to = reps, dj = 1, from_tpos = at.tpos;
if (greedy) { from = reps; to = rep_from; dj = -1; }
for (int j = from; j != to+dj; j += dj) {
at.tpos = from_tpos + j;
int try = Regexp__match_r(mr, text, pattern, &at, allow_partial);
if (try >= 0) return try;
}
}
#line 231 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
/* no match length worked, so no match */
return -1;
}
{
#line 295 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
if (mr) {
for (int i=0; i<at.bc; i++) {
Str__clear(mr->exp[i]);
for (int j = at.brackets_start[i]; j <= at.brackets_end[i]; j++)
PUT_TO(mr->exp[i], Str__get_at(text, j));
mr->exp_at[i] = at.brackets_start[i];
}
mr->no_matched_texts = at.bc;
}
}
#line 236 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
return at.tpos;
}
#line 338 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__get_cclass(wchar_t *pattern, int ppos, int *len, int *from, int *to, int *reverse) {
if (pattern[ppos] == '^') { ppos++; *reverse = TRUE; } else { *reverse = FALSE; }
switch (pattern[ppos]) {
case '%':
ppos++;
*len = 2;
switch (pattern[ppos]) {
case 'd': return DIGIT_CHARCLASS;
case 'c': return ANY_CHARCLASS;
case 'C': return NONWHITESPACE_CHARCLASS;
case 'i': return IDENTIFIER_CHARCLASS;
case 'p': return PREFORM_CHARCLASS;
case 'P': return PREFORMC_CHARCLASS;
case 'q': return QUOTE_CHARCLASS;
case 't': return TAB_CHARCLASS;
}
*from = ppos; *to = ppos; return LITERAL_CHARCLASS;
case '[':
*from = ppos+1;
ppos += 2;
while ((pattern[ppos]) && (pattern[ppos] != ']')) ppos++;
*to = ppos - 1; *len = ppos - *from + 2;
return LITERAL_CHARCLASS;
case ' ':
*len = 1; return WHITESPACE_CHARCLASS;
}
*len = 1; *from = ppos; *to = ppos; return LITERAL_CHARCLASS;
}
#line 368 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__test_cclass(int c, int chcl, int range_from, int range_to, wchar_t *drawn_from, int reverse) {
int match = FALSE;
switch (chcl) {
case ANY_CHARCLASS: if (c) match = TRUE; break;
case DIGIT_CHARCLASS: if (isdigit(c)) match = TRUE; break;
case WHITESPACE_CHARCLASS: if (Characters__is_whitespace(c)) match = TRUE; break;
case TAB_CHARCLASS: if (c == '\t') match = TRUE; break;
case NONWHITESPACE_CHARCLASS: if (!(Characters__is_whitespace(c))) match = TRUE; break;
case QUOTE_CHARCLASS: if (c != '\"') match = TRUE; break;
case IDENTIFIER_CHARCLASS: if (Regexp__identifier_char(c)) match = TRUE; break;
case PREFORM_CHARCLASS: if ((c == '-') || (c == '_') ||
((c >= 'a') && (c <= 'z')) ||
((c >= '0') && (c <= '9'))) match = TRUE; break;
case PREFORMC_CHARCLASS: if ((c == '-') || (c == '_') || (c == ':') ||
((c >= 'a') && (c <= 'z')) ||
((c >= '0') && (c <= '9'))) match = TRUE; break;
case LITERAL_CHARCLASS:
if ((range_to > range_from) && (drawn_from[range_from] == '^')) {
range_from++; reverse = reverse?FALSE:TRUE;
}
for (int j = range_from; j <= range_to; j++) {
int c1 = drawn_from[j], c2 = c1;
if ((j+1 < range_to) && (drawn_from[j+1] == '-')) { c2 = drawn_from[j+2]; j += 2; }
if ((c >= c1) && (c <= c2)) {
match = TRUE; break;
}
}
break;
}
if (reverse) match = (match)?FALSE:TRUE;
return match;
}
#line 415 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__replace(text_stream *text, wchar_t *pattern, wchar_t *replacement, int options) {
TEMPORARY_TEXT(altered)
match_results mr = Regexp__create_mr();
int changes = 0;
for (int i=0, L=Str__len(text); i<L; i++) {
match_position mp; mp.tpos = i; mp.ppos = 0; mp.bc = 0; mp.bl = 0;
Regexp__prepare(&mr);
int try = Regexp__match_r(&mr, text, pattern, &mp, TRUE);
if (try >= 0) {
if (replacement)
for (int j=0; replacement[j]; j++) {
int c = replacement[j];
if (c == '%') {
j++;
int ind = replacement[j] - '0';
if ((ind >= 0) && (ind < MAX_BRACKETED_SUBEXPRESSIONS))
WRITE_TO(altered, "%S", mr.exp[ind]);
else
PUT_TO(altered, replacement[j]);
} else {
PUT_TO(altered, replacement[j]);
}
}
int left = L - try;
changes++;
Regexp__dispose_of(&mr);
L = Str__len(text); i = L-left-1;
if ((options & REP_REPEATING) == 0) {
{
#line 454 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
for (i++; i<L; i++)
PUT_TO(altered, Str__get_at(text, i));
}
#line 442 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
; break; }
continue;
} else PUT_TO(altered, Str__get_at(text, i));
if (options & REP_ATSTART) {
{
#line 454 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
for (i++; i<L; i++)
PUT_TO(altered, Str__get_at(text, i));
}
#line 445 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
; break; }
}
Regexp__dispose_of(&mr);
if (changes > 0) Str__copy(text, altered);
DISCARD_TEXT(altered)
return changes;
}
#line 47 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__write_type(OUTPUT_STREAM, int t) {
switch (t) {
case NUMBER_JSONTYPE: WRITE("number"); break;
case DOUBLE_JSONTYPE: WRITE("double"); break;
case STRING_JSONTYPE: WRITE("string"); break;
case BOOLEAN_JSONTYPE: WRITE("boolean"); break;
case ARRAY_JSONTYPE: WRITE("array"); break;
case OBJECT_JSONTYPE: WRITE("object"); break;
case NULL_JSONTYPE: WRITE("null"); break;
case ERROR_JSONTYPE: WRITE("<error>"); break;
default: WRITE("<invalid %d>", t); break;
}
}
#line 76 "inweb/foundation-module/Chapter 4/JSON.w"
#line 80 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__new_null(void) {
JSON_value *value = CREATE(JSON_value);
value->JSON_type = NULL_JSONTYPE;
value->if_integer = 0;
value->if_double = 0;
value->if_string = NULL;
value->if_boolean = NOT_APPLICABLE;
value->if_list = NULL;
value->dictionary_if_object = NULL;
value->list_if_object = NULL;
value->if_error = NULL;
return value;
}
JSON_value *JSON__new_boolean(int b) {
JSON_value *value = JSON__new_null();
value->JSON_type = BOOLEAN_JSONTYPE;
value->if_boolean = b;
if ((b != TRUE) && (b != FALSE)) internal_error("improper JSON boolean");
return value;
}
JSON_value *JSON__new_number(int b) {
JSON_value *value = JSON__new_null();
value->JSON_type = NUMBER_JSONTYPE;
value->if_integer = b;
return value;
}
JSON_value *JSON__new_double(double d) {
JSON_value *value = JSON__new_null();
value->JSON_type = DOUBLE_JSONTYPE;
value->if_double = d;
return value;
}
JSON_value *JSON__new_string(text_stream *S) {
JSON_value *value = JSON__new_null();
value->JSON_type = STRING_JSONTYPE;
value->if_string = Str__duplicate(S);
return value;
}
#line 127 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__new_array(void) {
JSON_value *value = JSON__new_null();
value->JSON_type = ARRAY_JSONTYPE;
value->if_list = NEW_LINKED_LIST(JSON_value);
return value;
}
JSON_value *JSON__add_to_array(JSON_value *array, JSON_value *new_entry) {
if (array == NULL) internal_error("no array");
if (array->JSON_type == ERROR_JSONTYPE) return array;
if (array->JSON_type != ARRAY_JSONTYPE) internal_error("not an array");
if (new_entry == NULL) internal_error("no new entry");
if (new_entry->JSON_type == ERROR_JSONTYPE) return new_entry;
ADD_TO_LINKED_LIST(new_entry, JSON_value, array->if_list);
return array;
}
#line 148 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__new_object(void) {
JSON_value *value = JSON__new_null();
value->JSON_type = OBJECT_JSONTYPE;
value->dictionary_if_object = Dictionaries__new(16, FALSE);
value->list_if_object = NEW_LINKED_LIST(text_stream);
return value;
}
JSON_value *JSON__add_to_object(JSON_value *obj, text_stream *key, JSON_value *value) {
if (obj == NULL) internal_error("no object");
if (obj->JSON_type == ERROR_JSONTYPE) return obj;
if (obj->JSON_type != OBJECT_JSONTYPE) internal_error("not an object");
if (value == NULL) internal_error("no new entry");
if (value->JSON_type == ERROR_JSONTYPE) return value;
key = Str__duplicate(key);
ADD_TO_LINKED_LIST(key, text_stream, obj->list_if_object);
dict_entry *de = Dictionaries__create(obj->dictionary_if_object, key);
if (de) de->value = value;
return obj;
}
#line 173 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__look_up_object(JSON_value *obj, text_stream *key) {
if (obj == NULL) internal_error("no object");
if (obj->JSON_type == ERROR_JSONTYPE) return NULL;
if (obj->JSON_type != OBJECT_JSONTYPE) internal_error("not an object");
dict_entry *de = Dictionaries__find(obj->dictionary_if_object, key);
if (de == NULL) return NULL;
return de->value;
}
#line 186 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__error(text_stream *msg) {
JSON_value *value = JSON__new_null();
value->JSON_type = ERROR_JSONTYPE;
value->if_error = Str__duplicate(msg);
return value;
}
#line 197 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__eq(JSON_value *val1, JSON_value *val2) {
if ((val1 == NULL) && (val2)) return FALSE;
if ((val1) && (val2 == NULL)) return FALSE;
if (val1 == NULL) return TRUE;
if (val1->JSON_type != val2->JSON_type) return FALSE;
switch (val1->JSON_type) {
case NUMBER_JSONTYPE: if (val1->if_integer == val2->if_integer) return TRUE; break;
case STRING_JSONTYPE: if (Str__eq(val1->if_string, val2->if_string)) return TRUE; break;
case BOOLEAN_JSONTYPE: if (val1->if_boolean == val2->if_boolean) return TRUE; break;
case NULL_JSONTYPE: return TRUE;
}
return FALSE;
}
#line 221 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__decode(text_stream *T, text_file_position *tfp) {
return JSON__decode_range(T, 0, Str__len(T), tfp);
}
JSON_value *JSON__decode_error(text_stream *err, text_file_position *tfp) {
TEMPORARY_TEXT(msg)
if (tfp) WRITE_TO(msg, "%f: ", tfp->text_file_filename);
WRITE_TO(msg, "%S", err);
JSON_value *value = JSON__error(msg);
DISCARD_TEXT(msg)
return value;
}
JSON_value *JSON__decode_error_q(text_stream *err, text_file_position *tfp,
text_stream *T, int from, int to) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "%S", err);
if ((T) && (from < to)) {
WRITE_TO(msg, ": '");
for (int i=from; ((i<to) && (i-from < 40)); i++) {
if (Str__get_at(T, i) == '\n') WRITE_TO(msg, " ");
else WRITE_TO(msg, "%c", Str__get_at(T, i));
}
WRITE_TO(msg, "'");
}
JSON_value *value = JSON__decode_error(msg, tfp);
DISCARD_TEXT(msg)
return value;
}
#line 260 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__decode_range(text_stream *T, int from, int to, text_file_position *tfp) {
int first_nws = -1, last_nws = -1;
wchar_t first_c = 0, last_c = 0;
{
#line 289 "inweb/foundation-module/Chapter 4/JSON.w"
for (int i=from; i<to; i++)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE) {
first_nws = i; break;
}
for (int i=to-1; i>=from; i--)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE) {
last_nws = i; break;
}
if (first_nws < 0) return JSON__decode_error(TL_IS_16, tfp);
first_c = Str__get_at(T, first_nws);
last_c = Str__get_at(T, last_nws);
}
#line 263 "inweb/foundation-module/Chapter 4/JSON.w"
;
switch (first_c) {
case '[':
if (last_c != ']') return JSON__decode_error(TL_IS_9, tfp);
JSON_value *array = JSON__new_array();
return JSON__decode_array(array, T, first_nws+1, last_nws, tfp);
case '{':
if (last_c != '}') return JSON__decode_error(TL_IS_10, tfp);
JSON_value *obj = JSON__new_object();
return JSON__decode_object(obj, T, first_nws+1, last_nws, tfp);
case '"':
if (last_c != '"') return JSON__decode_error(TL_IS_11, tfp);
return JSON__decode_string(T, first_nws+1, last_nws, tfp);
}
if ((Characters__isdigit(first_c)) || (first_c == '-'))
return JSON__decode_number(T, first_nws, last_nws+1, tfp);
if ((Str__includes_at(T, first_nws, TL_IS_12)) && (last_nws - first_nws == 3))
return JSON__new_boolean(TRUE);
if ((Str__includes_at(T, first_nws, TL_IS_13)) && (last_nws - first_nws == 4))
return JSON__new_boolean(FALSE);
if ((Str__includes_at(T, first_nws, TL_IS_14)) && (last_nws - first_nws == 3))
return JSON__new_null();
return JSON__decode_error(TL_IS_15, tfp);
}
#line 307 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__decode_array(JSON_value *array, text_stream *T, int from, int to,
text_file_position *tfp) {
int content = FALSE;
for (int i=from; i<to; i++)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE)
content = TRUE;
if (content == FALSE) return array;
NextEntry: ;
int first_comma = -1, bl = 0;
for (int i=from, quoted = FALSE; i<to; i++) {
wchar_t c = Str__get_at(T, i);
switch (c) {
case '"': quoted = (quoted)?FALSE:TRUE; break;
case '\\': if (quoted) i++; break;
case ',': if ((quoted == FALSE) && ((first_comma < 0) && (bl == 0)))
first_comma = i; break;
case '[': case '{': if (quoted == FALSE) bl++; break;
case ']': case '}': if (quoted == FALSE) bl--; break;
}
}
if (first_comma >= 0) {
array = JSON__decode_array_entry(array, T, from, first_comma, tfp);
from = first_comma + 1;
goto NextEntry;
}
return JSON__decode_array_entry(array, T, from, to, tfp);
}
JSON_value *JSON__decode_array_entry(JSON_value *array, text_stream *T, int from, int to,
text_file_position *tfp) {
JSON_value *value = JSON__decode_range(T, from, to, tfp);
return JSON__add_to_array(array, value);
}
#line 344 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__decode_object(JSON_value *obj, text_stream *T, int from, int to,
text_file_position *tfp) {
int content = FALSE;
for (int i=from; i<to; i++)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE)
content = TRUE;
if (content == FALSE) return obj;
NextEntry: ;
int first_comma = -1, bl = 0;
for (int i=from, quoted = FALSE; i<to; i++) {
wchar_t c = Str__get_at(T, i);
switch (c) {
case '"': quoted = (quoted)?FALSE:TRUE; break;
case '\\': if (quoted) i++; break;
case ',': if ((quoted == FALSE) && ((first_comma < 0) && (bl == 0)))
first_comma = i; break;
case '[': case '{': if (quoted == FALSE) bl++; break;
case ']': case '}': if (quoted == FALSE) bl--; break;
}
}
if (first_comma >= 0) {
obj = JSON__decode_object_entry(obj, T, from, first_comma, tfp);
from = first_comma + 1;
goto NextEntry;
}
return JSON__decode_object_entry(obj, T, from, to, tfp);
}
#line 380 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__decode_object_entry(JSON_value *obj, text_stream *T, int from, int to,
text_file_position *tfp) {
while (Characters__is_whitespace(Str__get_at(T, from))) from++;
int saved_from = from, saved_to = to;
if (from >= to)
return JSON__decode_error(TL_IS_17, tfp);
if (Str__get_at(T, from) != '"')
return JSON__decode_error_q(TL_IS_18, tfp, T, saved_from, saved_to);
from++;
int ended = FALSE;
TEMPORARY_TEXT(key)
while (from < to) {
wchar_t c = Str__get_at(T, from++);
if (c == '\"') { ended = TRUE; break; }
PUT_TO(key, c);
if ((c == '\\') && (from+1 < to)) {
c = Str__get_at(T, from++);
PUT_TO(key, c);
}
}
if (ended == FALSE) return JSON__decode_error_q(TL_IS_19, tfp, T, saved_from, saved_to);
while (Characters__is_whitespace(Str__get_at(T, from))) from++;
if ((from >= to) || (Str__get_at(T, from) != ':'))
return JSON__decode_error_q(TL_IS_20, tfp, T, saved_from, saved_to);
from++;
if (JSON__look_up_object(obj, key)) return JSON__decode_error_q(TL_IS_21, tfp, T, saved_from, saved_to);
JSON_value *value = JSON__decode_range(T, from, to, tfp);
obj = JSON__add_to_object(obj, key, value);
DISCARD_TEXT(key)
return obj;
}
#line 418 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__decode_number(text_stream *T, int from, int to, text_file_position *tfp) {
while (Characters__is_whitespace(Str__get_at(T, from))) from++;
while ((to > from) && (Characters__is_whitespace(Str__get_at(T, to-1)))) to--;
if (to <= from) return JSON__decode_error(TL_IS_22, tfp);
TEMPORARY_TEXT(integer)
int at = from;
if ((Str__get_at(T, at) == '-') && (to > at+1)) { PUT_TO(integer, '-'); at++; }
int double_me = FALSE;
for (int i=at; i<to; i++)
if (Characters__isdigit(Str__get_at(T, i)))
PUT_TO(integer, Str__get_at(T, i));
else if ((Str__get_at(T, i) == 'E') || (Str__get_at(T, i) == 'e') ||
(Str__get_at(T, i) == '.') || (Str__get_at(T, i) == '+'))
double_me = TRUE;
else
return JSON__decode_error(TL_IS_23, tfp);
JSON_value *value = NULL;
if (double_me) {
char double_buffer[32];
for (int i=0; i<32; i++) double_buffer[i] = 0;
for (int i=from; (i<to) && (i-from<31); i++)
double_buffer[i-from] = (char) Str__get_at(T, i);
double d = atof(double_buffer);
if (isnan(d)) return JSON__decode_error(TL_IS_24, tfp);
value = JSON__new_double(d);
} else {
int N = Str__atoi(integer, 0);
value = JSON__new_number(N);
}
DISCARD_TEXT(integer)
return value;
}
#line 455 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *JSON__decode_string(text_stream *T, int from, int to, text_file_position *tfp) {
TEMPORARY_TEXT(string)
for (int i=from; i<to; i++) {
wchar_t c = Str__get_at(T, i);
if (c == '\\') {
i++;
c = Str__get_at(T, i);
if (Characters__iscntrl(c)) return JSON__decode_error(TL_IS_25, tfp);
switch (c) {
case 'b': c = 8; break;
case 't': c = 9; break;
case 'n': c = 10; break;
case 'f': c = 12; break;
case 'r': c = 13; break;
case '\\': break;
case '/': break;
case '"': break;
case 'u':
{
#line 490 "inweb/foundation-module/Chapter 4/JSON.w"
if (i+4 >= to) return JSON__decode_error(TL_IS_27, tfp);
int hex = 0;
for (int j=0; j<4; j++) {
int v = 0;
wchar_t digit = Str__get_at(T, i+1+j);
if ((digit >= '0') && (digit <= '9')) v = (int) (digit-'0');
else if ((digit >= 'a') && (digit <= 'f')) v = 10 + ((int) (digit-'a'));
else if ((digit >= 'A') && (digit <= 'F')) v = 10 + ((int) (digit-'A'));
else return JSON__decode_error(TL_IS_28, tfp);
hex = hex * 16 + v;
}
c = (wchar_t) hex;
i += 4;
}
#line 472 "inweb/foundation-module/Chapter 4/JSON.w"
; break;
default: return JSON__decode_error(TL_IS_26, tfp);
}
PUT_TO(string, c);
} else {
PUT_TO(string, c);
}
}
JSON_value *val = JSON__new_string(string);
DISCARD_TEXT(string)
return val;
}
#line 507 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode(OUTPUT_STREAM, JSON_value *J) {
if (J == NULL) internal_error("no JSON value supplied");
switch (J->JSON_type) {
case ERROR_JSONTYPE:
internal_error("tried to encode erroneous JSON");
case NUMBER_JSONTYPE:
WRITE("%d", J->if_integer);
break;
case DOUBLE_JSONTYPE:
WRITE("%g", J->if_double);
break;
case STRING_JSONTYPE:
WRITE("\""); JSON__encode_string(OUT, J->if_string); WRITE("\"");
break;
case BOOLEAN_JSONTYPE:
if (J->if_boolean == TRUE) WRITE("true");
else if (J->if_boolean == FALSE) WRITE("false");
else internal_error("improper boolean JSON value");
break;
case ARRAY_JSONTYPE: {
WRITE("[");
int count = 0;
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, J->if_list) {
if (count++ > 0) WRITE(",");
WRITE(" ");
JSON__encode(OUT, E);
}
if (count > 0) WRITE(" ");
WRITE("]");
break;
}
case OBJECT_JSONTYPE: {
WRITE("{\n"); INDENT;
int count = 0;
text_stream *key;
LOOP_OVER_LINKED_LIST(key, text_stream, J->list_if_object) {
if (count++ > 0) WRITE(",\n");
JSON_value *E = Dictionaries__read_value(J->dictionary_if_object, key);
if (E == NULL) internal_error("broken JSON object dictionary");
WRITE("\"");
JSON__encode_string(OUT, key);
WRITE("\": ");
JSON__encode(OUT, E);
}
if (count > 0) WRITE("\n");
OUTDENT; WRITE("}");
break;
}
case NULL_JSONTYPE:
WRITE("null");
break;
default: internal_error("unsupported JSON value type");
}
}
#line 567 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode_string(OUTPUT_STREAM, text_stream *T) {
LOOP_THROUGH_TEXT(pos, T) {
wchar_t c = Str__get(pos);
switch (c) {
case '\\': WRITE("\\\\"); break;
case 8: WRITE("\\b"); break;
case 9: WRITE("\\t"); break;
case 10: WRITE("\\n"); break;
case 12: WRITE("\\f"); break;
case 13: WRITE("\\r"); break;
default:
if (Characters__iscntrl(c)) WRITE("\\u%04x", (int)c);
else PUT(c);
break;
}
}
}
#line 599 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement *JSON__single_choice(JSON_single_requirement *sing) {
JSON_requirement *req = CREATE(JSON_requirement);
req->alternatives = NEW_LINKED_LIST(JSON_single_requirement);
ADD_TO_LINKED_LIST(sing, JSON_single_requirement, req->alternatives);
return req;
}
JSON_requirement *JSON__add_alternative(JSON_requirement *so_far,
JSON_single_requirement *sing) {
if (so_far == NULL) return JSON__single_choice(sing);
ADD_TO_LINKED_LIST(sing, JSON_single_requirement, so_far->alternatives);
return so_far;
}
#line 625 "inweb/foundation-module/Chapter 4/JSON.w"
#line 630 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement *JSON__require_requirement(JSON_requirement *req) {
JSON_single_requirement *sing = CREATE(JSON_single_requirement);
sing->this_requirement = req;
sing->this_value = NULL;
sing->this_type = NULL;
return sing;
}
JSON_single_requirement *JSON__require_value(JSON_value *value) {
JSON_single_requirement *sing = CREATE(JSON_single_requirement);
sing->this_requirement = NULL;
sing->this_value = value;
sing->this_type = NULL;
return sing;
}
JSON_single_requirement *JSON__require_type(int t) {
JSON_single_requirement *sing = CREATE(JSON_single_requirement);
sing->this_requirement = NULL;
sing->this_value = NULL;
sing->this_type = JSON__new_type_requirement(t);
return sing;
}
#line 669 "inweb/foundation-module/Chapter 4/JSON.w"
#line 675 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_type *JSON__new_type_requirement(int t) {
JSON_type *type = CREATE(JSON_type);
type->JSON_type = t;
if (t == ARRAY_JSONTYPE) {
type->if_list = NEW_LINKED_LIST(JSON_requirement);
type->all_if_list = NULL;
} else {
type->if_list = NULL;
type->all_if_list = NULL;
}
if (t == OBJECT_JSONTYPE) {
type->dictionary_if_object = Dictionaries__new(16, FALSE);
type->list_if_object = NEW_LINKED_LIST(text_stream);
} else {
type->dictionary_if_object = NULL;
type->list_if_object = NULL;
}
type->if_error = NULL;
return type;
}
#line 704 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement *JSON__require_array_of(JSON_requirement *E_req) {
JSON_single_requirement *req = JSON__require_type(ARRAY_JSONTYPE);
req->this_type->all_if_list = E_req;
return req;
}
#line 715 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__require_entry(JSON_single_requirement *array_sr, JSON_requirement *entry_sr) {
if (array_sr == NULL) internal_error("no array");
if ((array_sr->this_type == NULL) ||
(array_sr->this_type->JSON_type != ARRAY_JSONTYPE)) internal_error("not an array");
if (entry_sr == NULL) internal_error("no new entry");
ADD_TO_LINKED_LIST(entry_sr, JSON_requirement, array_sr->this_type->if_list);
}
#line 727 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__require_pair(JSON_single_requirement *obj_sr, text_stream *key, JSON_requirement *req) {
JSON__require_pair_inner(obj_sr, key, req, FALSE);
}
void JSON__allow_pair(JSON_single_requirement *obj_sr, text_stream *key, JSON_requirement *req) {
JSON__require_pair_inner(obj_sr, key, req, TRUE);
}
void JSON__require_pair_inner(JSON_single_requirement *obj_sr, text_stream *key,
JSON_requirement *req, int opt) {
if (obj_sr == NULL) internal_error("no object");
if ((obj_sr->this_type == NULL) ||
(obj_sr->this_type->JSON_type != OBJECT_JSONTYPE)) internal_error("not an object");
if (req == NULL) internal_error("no val req");
key = Str__duplicate(key);
ADD_TO_LINKED_LIST(key, text_stream, obj_sr->this_type->list_if_object);
JSON_pair_requirement *pr = CREATE(JSON_pair_requirement);
pr->req = req;
pr->optional = opt;
dict_entry *de = Dictionaries__create(obj_sr->this_type->dictionary_if_object, key);
if (de) de->value = pr;
}
#line 754 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_pair_requirement *JSON__look_up_pair(JSON_single_requirement *obj_sr, text_stream *key) {
if (obj_sr == NULL) internal_error("no object");
if ((obj_sr->this_type == NULL) ||
(obj_sr->this_type->JSON_type != OBJECT_JSONTYPE)) internal_error("not an object");
dict_entry *de = Dictionaries__find(obj_sr->this_type->dictionary_if_object, key);
if (de == NULL) return NULL;
return de->value;
}
#line 767 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement *JSON__error_sr(text_stream *msg) {
JSON_single_requirement *req = JSON__require_type(ERROR_JSONTYPE);
req->this_type->if_error = Str__duplicate(msg);
return req;
}
#line 785 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__validate(JSON_value *val, JSON_requirement *req, linked_list *errs) {
lifo_stack *location = NEW_LIFO_STACK(text_stream);
if ((val) && (val->JSON_type == ARRAY_JSONTYPE)) {
PUSH_TO_LIFO_STACK(TL_IS_29, text_stream, location);
}
if ((val) && (val->JSON_type == OBJECT_JSONTYPE)) {
PUSH_TO_LIFO_STACK(TL_IS_30, text_stream, location);
}
return JSON__validate_r(val, req, errs, location);
}
void JSON__validation_error(linked_list *errs, text_stream *err, lifo_stack *location) {
if (errs) {
text_stream *msg = Str__new();
int S = LinkedLists__len(location);
for (int i=S-1; i>=0; i--) {
int c = 0;
text_stream *seg;
LOOP_OVER_LINKED_LIST(seg, text_stream, location)
if (c++ == i)
WRITE_TO(msg, "%S", seg);
}
if (Str__len(msg) > 0) WRITE_TO(msg, ": ");
WRITE_TO(msg, "%S", err);
ADD_TO_LINKED_LIST(msg, text_stream, errs);
}
}
#line 819 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__validate_r(JSON_value *val, JSON_requirement *req, linked_list *errs,
lifo_stack *location) {
if (val == NULL) internal_error("no value");
if (req == NULL) internal_error("no req");
JSON_single_requirement *sing;
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
int rv = JSON__validate_single_r(val, sing, NULL, location);
if (rv) return TRUE;
}
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
JSON__validate_single_r(val, sing, errs, location);
break;
}
return FALSE;
}
#line 838 "inweb/foundation-module/Chapter 4/JSON.w"
int JSON__validate_single_r(JSON_value *val, JSON_single_requirement *req,
linked_list *errs, lifo_stack *location) {
if (val->JSON_type == ERROR_JSONTYPE) {
JSON__validation_error(errs,
TL_IS_31, location);
return FALSE;
}
if (req->this_requirement)
{
#line 852 "inweb/foundation-module/Chapter 4/JSON.w"
return JSON__validate_r(val, req->this_requirement, errs, location);
}
#line 845 "inweb/foundation-module/Chapter 4/JSON.w"
;
if (req->this_value)
{
#line 855 "inweb/foundation-module/Chapter 4/JSON.w"
if (JSON__eq(val, req->this_value) == FALSE) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "value ");
JSON__encode(msg, val);
WRITE_TO(msg, " not one of those allowed");
JSON__validation_error(errs, msg, location);
DISCARD_TEXT(msg)
return FALSE;
}
return TRUE;
}
#line 846 "inweb/foundation-module/Chapter 4/JSON.w"
;
if (req->this_type)
{
#line 867 "inweb/foundation-module/Chapter 4/JSON.w"
{
#line 876 "inweb/foundation-module/Chapter 4/JSON.w"
if (val->JSON_type != req->this_type->JSON_type) {
if (errs) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "expected ");
JSON__write_type(msg, req->this_type->JSON_type);
WRITE_TO(msg, " but found ");
JSON__write_type(msg, val->JSON_type);
JSON__validation_error(errs, msg, location);
DISCARD_TEXT(msg)
}
return FALSE;
}
}
#line 867 "inweb/foundation-module/Chapter 4/JSON.w"
;
int outcome = TRUE;
if (val->JSON_type == ARRAY_JSONTYPE)
{
#line 890 "inweb/foundation-module/Chapter 4/JSON.w"
int count = 0;
JSON_value *E;
LOOP_OVER_LINKED_LIST(E, JSON_value, val->if_list) {
JSON_requirement *E_req = req->this_type->all_if_list;
if (E_req == NULL) {
JSON_requirement *A_req;
int rcount = 0;
LOOP_OVER_LINKED_LIST(A_req, JSON_requirement, req->this_type->if_list)
if (rcount++ == count)
E_req = A_req;
}
TEMPORARY_TEXT(at)
WRITE_TO(at, "[%d]", count);
PUSH_TO_LIFO_STACK(at, text_stream, location);
if (E_req == NULL) {
JSON__validation_error(errs, TL_IS_32, location);
outcome = FALSE;
} else {
if (JSON__validate_r(E, E_req, errs, location) == FALSE) outcome = FALSE;
}
POP_LIFO_STACK(text_stream, location);
DISCARD_TEXT(at)
count++;
}
}
#line 870 "inweb/foundation-module/Chapter 4/JSON.w"
;
if (val->JSON_type == OBJECT_JSONTYPE)
{
#line 916 "inweb/foundation-module/Chapter 4/JSON.w"
text_stream *key;
LOOP_OVER_LINKED_LIST(key, text_stream, val->list_if_object)
{
#line 928 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *E = Dictionaries__read_value(val->dictionary_if_object, key);
if (E == NULL) internal_error("broken JSON object dictionary");
JSON_pair_requirement *pr = JSON__look_up_pair(req, key);
TEMPORARY_TEXT(at)
WRITE_TO(at, ".%S", key);
PUSH_TO_LIFO_STACK(at, text_stream, location);
if (pr == NULL) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "unexpected member '%S'", key);
JSON__validation_error(errs, msg, location);
DISCARD_TEXT(msg)
outcome = FALSE;
} else {
if (JSON__validate_r(E, pr->req, errs, location) == FALSE) outcome = FALSE;
}
POP_LIFO_STACK(text_stream, location);
DISCARD_TEXT(at)
}
#line 918 "inweb/foundation-module/Chapter 4/JSON.w"
;
LOOP_OVER_LINKED_LIST(key, text_stream, req->this_type->list_if_object) {
JSON_pair_requirement *pr =
Dictionaries__read_value(req->this_type->dictionary_if_object, key);
if (pr == NULL) internal_error("broken JSON object requirement");
if (pr->optional == FALSE)
{
#line 947 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_value *E = JSON__look_up_object(val, key);
if (E == NULL) {
TEMPORARY_TEXT(msg)
WRITE_TO(msg, "member '%S' missing", key);
JSON__validation_error(errs, msg, location);
DISCARD_TEXT(msg)
outcome = FALSE;
}
}
#line 924 "inweb/foundation-module/Chapter 4/JSON.w"
;
}
}
#line 872 "inweb/foundation-module/Chapter 4/JSON.w"
;
return outcome;
}
#line 847 "inweb/foundation-module/Chapter 4/JSON.w"
;
internal_error("bad single requirement");
}
#line 988 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement *JSON__decode_req(text_stream *T, dictionary *known_names) {
return JSON__decode_req_range(T, 0, Str__len(T), known_names);
}
#line 996 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_requirement *JSON__decode_req_range(text_stream *T, int from, int to,
dictionary *known_names) {
int first_nws = -1, last_nws = -1;
wchar_t first_c = 0, last_c = 0;
{
#line 1114 "inweb/foundation-module/Chapter 4/JSON.w"
for (int i=from; i<to; i++)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE) {
first_nws = i; break;
}
for (int i=to-1; i>=from; i--)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE) {
last_nws = i; break;
}
first_c = Str__get_at(T, first_nws);
last_c = Str__get_at(T, last_nws);
}
#line 1000 "inweb/foundation-module/Chapter 4/JSON.w"
;
if (first_c == '(') {
if (last_c != ')')
return JSON__single_choice(JSON__error_sr(TL_IS_33));
from = first_nws + 1;
to = last_nws;
JSON_requirement *req = NULL;
NextEntry: ;
int first_pipe = -1, bl = 0;
for (int i=from, quoted = FALSE; i<to; i++) {
wchar_t c = Str__get_at(T, i);
switch (c) {
case '"': quoted = (quoted)?FALSE:TRUE; break;
case '\\': if (quoted) i++; break;
case '|': if ((first_pipe < 0) && (bl == 0)) first_pipe = i; break;
case '[': case '{': case '(': if (quoted == FALSE) bl++; break;
case ']': case '}': case ')': if (quoted == FALSE) bl--; break;
}
}
if (first_pipe >= 0) {
req = JSON__decode_req_alternative(req, T, from, first_pipe, known_names);
from = first_pipe + 1;
goto NextEntry;
}
return JSON__decode_req_alternative(req, T, from, to, known_names);
}
return JSON__single_choice(JSON__decode_sreq_range(T, from, to, known_names));
}
JSON_requirement *JSON__decode_req_alternative(JSON_requirement *req, text_stream *T,
int from, int to, dictionary *known_names) {
JSON_single_requirement *sing = JSON__decode_sreq_range(T, from, to, known_names);
return JSON__add_alternative(req, sing);
}
#line 1041 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement *JSON__decode_sreq_range(text_stream *T, int from, int to,
dictionary *known_names) {
int first_nws = -1, last_nws = -1;
wchar_t first_c = 0, last_c = 0;
{
#line 1114 "inweb/foundation-module/Chapter 4/JSON.w"
for (int i=from; i<to; i++)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE) {
first_nws = i; break;
}
for (int i=to-1; i>=from; i--)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE) {
last_nws = i; break;
}
first_c = Str__get_at(T, first_nws);
last_c = Str__get_at(T, last_nws);
}
#line 1045 "inweb/foundation-module/Chapter 4/JSON.w"
;
if (first_nws < 0) return JSON__error_sr(TL_IS_34);
switch (first_c) {
case '[':
if (last_c != ']') return JSON__error_sr(TL_IS_35);
JSON_single_requirement *array_sr = JSON__require_type(ARRAY_JSONTYPE);
return JSON__decode_req_array(array_sr, T, first_nws+1, last_nws, known_names);
case '{':
if (last_c != '}') return JSON__error_sr(TL_IS_36);
JSON_single_requirement *obj_sr = JSON__require_type(OBJECT_JSONTYPE);
return JSON__decode_req_object(obj_sr, T, first_nws+1, last_nws, known_names);
case '<':
if (last_c != '>') return JSON__error_sr(TL_IS_37);
JSON_requirement *known = NULL;
TEMPORARY_TEXT(name)
for (int i = first_nws+1; i<last_nws; i++)
PUT_TO(name, Str__get_at(T, i));
if (known_names) {
dict_entry *de = Dictionaries__find(known_names, name);
if (de == NULL) return JSON__error_sr(TL_IS_38);
known = de->value;
} else {
return JSON__error_sr(TL_IS_39);
}
DISCARD_TEXT(name)
if (known) return JSON__require_requirement(known);
return NULL;
}
int require_value = FALSE;
if ((first_c == '"') || (first_c == '-') || (Characters__isdigit(first_c)))
require_value = TRUE;
if ((Str__includes_at(T, first_nws, TL_IS_40)) && (last_nws - first_nws == 3))
require_value = TRUE;
if ((Str__includes_at(T, first_nws, TL_IS_41)) && (last_nws - first_nws == 4))
require_value = TRUE;
if ((Str__includes_at(T, first_nws, TL_IS_42)) && (last_nws - first_nws == 3))
require_value = TRUE;
if (require_value) {
JSON_value *value = JSON__decode_range(T, from, to, NULL);
if (value->JSON_type == ERROR_JSONTYPE) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "JSON value error: %S", value->if_error);
JSON_single_requirement *sing = JSON__error_sr(err);
DISCARD_TEXT(err)
return sing;
}
return JSON__require_value(value);
}
if ((Str__includes_at(T, first_nws, TL_IS_43)) && (last_nws - first_nws == 5))
return JSON__require_type(NUMBER_JSONTYPE);
if ((Str__includes_at(T, first_nws, TL_IS_44)) && (last_nws - first_nws == 5))
return JSON__require_type(DOUBLE_JSONTYPE);
if ((Str__includes_at(T, first_nws, TL_IS_45)) && (last_nws - first_nws == 5))
return JSON__require_type(STRING_JSONTYPE);
if ((Str__includes_at(T, first_nws, TL_IS_46)) && (last_nws - first_nws == 6))
return JSON__require_type(BOOLEAN_JSONTYPE);
text_stream *msg = Str__new();
WRITE_TO(msg, "unknown JSON type '");
for (int i=first_nws; i<last_nws; i++) PUT_TO(msg, Str__get_at(T, i));
WRITE_TO(msg, "'");
return JSON__error_sr(msg);
}
#line 1128 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement *JSON__decode_req_array(JSON_single_requirement *array_sr,
text_stream *T, int from, int to, dictionary *known_names) {
int content = FALSE;
for (int i=from; i<to; i++)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE)
content = TRUE;
if (content == FALSE) return array_sr;
while ((to > from) && (Characters__is_whitespace(Str__get_at(T, to-1)))) to--;
if (Str__get_at(T, to-1) == '*') {
to--;
return JSON__require_array_of(JSON__decode_req_range(T, from, to, known_names));
}
NextEntry: ;
int first_comma = -1, bl = 0;
for (int i=from, quoted = FALSE; i<to; i++) {
wchar_t c = Str__get_at(T, i);
switch (c) {
case '"': quoted = (quoted)?FALSE:TRUE; break;
case '\\': if (quoted) i++; break;
case ',': if ((quoted == FALSE) && ((first_comma < 0) && (bl == 0)))
first_comma = i; break;
case '[': case '{': case '(': if (quoted == FALSE) bl++; break;
case ']': case '}': case ')': if (quoted == FALSE) bl--; break;
}
}
if (first_comma >= 0) {
array_sr = JSON__decode_req_array_entry(array_sr, T, from, first_comma, known_names);
from = first_comma + 1;
goto NextEntry;
}
return JSON__decode_req_array_entry(array_sr, T, from, to, known_names);
}
JSON_single_requirement *JSON__decode_req_array_entry(JSON_single_requirement *array_sr,
text_stream *T, int from, int to, dictionary *known_names) {
JSON_requirement *req = JSON__decode_req_range(T, from, to, known_names);
JSON__require_entry(array_sr, req);
return array_sr;
}
#line 1171 "inweb/foundation-module/Chapter 4/JSON.w"
JSON_single_requirement *JSON__decode_req_object(JSON_single_requirement *obj,
text_stream *T, int from, int to, dictionary *known_names) {
int content = FALSE;
for (int i=from; i<to; i++)
if (Characters__is_whitespace(Str__get_at(T, i)) == FALSE)
content = TRUE;
if (content == FALSE) return obj;
NextEntry: ;
int first_comma = -1, bl = 0;
for (int i=from, quoted = FALSE; i<to; i++) {
wchar_t c = Str__get_at(T, i);
switch (c) {
case '"': quoted = (quoted)?FALSE:TRUE; break;
case '\\': if (quoted) i++; break;
case ',': if ((quoted == FALSE) && ((first_comma < 0) && (bl == 0)))
first_comma = i; break;
case '[': case '{': case '(': if (quoted == FALSE) bl++; break;
case ']': case '}': case ')': if (quoted == FALSE) bl--; break;
}
}
if (first_comma >= 0) {
obj = JSON__decode_req_object_entry(obj, T, from, first_comma, known_names);
from = first_comma + 1;
goto NextEntry;
}
return JSON__decode_req_object_entry(obj, T, from, to, known_names);
}
JSON_single_requirement *JSON__decode_req_object_entry(JSON_single_requirement *obj,
text_stream *T, int from, int to, dictionary *known_names) {
int optional = FALSE;
while (Characters__is_whitespace(Str__get_at(T, from))) from++;
if (Str__get_at(T, from) == '?') { optional = TRUE; from++; }
while (Characters__is_whitespace(Str__get_at(T, from))) from++;
if (Str__get_at(T, from) != '"')
return JSON__error_sr(TL_IS_47);
from++;
int ended = FALSE;
TEMPORARY_TEXT(key)
while (from < to) {
wchar_t c = Str__get_at(T, from++);
if (c == '\"') { ended = TRUE; break; }
PUT_TO(key, c);
if ((c == '\\') && (from+1 < to)) {
c = Str__get_at(T, from++);
PUT_TO(key, c);
}
}
if (ended == FALSE) return JSON__error_sr(TL_IS_48);
while (Characters__is_whitespace(Str__get_at(T, from))) from++;
if ((from >= to) || (Str__get_at(T, from) != ':'))
return JSON__error_sr(TL_IS_49);
from++;
if (JSON__look_up_pair(obj, key)) return JSON__error_sr(TL_IS_50);
JSON_requirement *req = JSON__decode_req_range(T, from, to, known_names);
if (optional) JSON__allow_pair(obj, key, req);
else JSON__require_pair(obj, key, req);
DISCARD_TEXT(key)
return obj;
}
#line 1247 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__encode_req(OUTPUT_STREAM, JSON_requirement *req) {
JSON__encode_req_r(OUT, req);
}
void JSON__encode_req_r(OUTPUT_STREAM, JSON_requirement *req) {
if (req == NULL) internal_error("no JSON value supplied");
int L = LinkedLists__len(req->alternatives);
if (L > 1) WRITE("( ");
int c = 0;
JSON_single_requirement *sing;
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
if (c++ > 0) WRITE(" | ");
JSON__encode_sreq_r(OUT, sing);
}
if (L > 1) WRITE(" )");
}
void JSON__encode_sreq_r(OUTPUT_STREAM, JSON_single_requirement *sing) {
if (sing->this_requirement) JSON__encode_req_r(OUT, sing->this_requirement);
if (sing->this_value) JSON__encode(OUT, sing->this_value);
if (sing->this_type) JSON__encode_type(OUT, sing->this_type);
}
void JSON__encode_type(OUTPUT_STREAM, JSON_type *type) {
switch (type->JSON_type) {
case ARRAY_JSONTYPE: {
WRITE("[");
if (type->all_if_list) {
WRITE(" ");
JSON__encode_req_r(OUT, type->all_if_list);
WRITE("* ");
} else {
int count = 0;
JSON_requirement *E_req;
LOOP_OVER_LINKED_LIST(E_req, JSON_requirement, type->if_list) {
if (count++ > 0) WRITE(",");
WRITE(" ");
JSON__encode_req_r(OUT, E_req);
}
if (count > 0) WRITE(" ");
}
WRITE("]");
break;
}
case OBJECT_JSONTYPE: {
WRITE("{\n"); INDENT;
int count = 0;
text_stream *key;
LOOP_OVER_LINKED_LIST(key, text_stream, type->list_if_object) {
if (count++ > 0) WRITE(",\n");
JSON_pair_requirement *pr =
Dictionaries__read_value(type->dictionary_if_object, key);
if (pr == NULL) internal_error("broken JSON req dictionary");
if (pr->optional) WRITE("?");
WRITE("\"");
JSON__encode_string(OUT, key);
WRITE("\": ");
JSON__encode_req_r(OUT, pr->req);
}
if (count > 0) WRITE("\n");
OUTDENT; WRITE("}");
break;
}
default: JSON__write_type(OUT, type->JSON_type);
}
}
#line 1346 "inweb/foundation-module/Chapter 4/JSON.w"
dictionary *JSON__read_requirements_file(dictionary *known, filename *F) {
if (known == NULL) known = Dictionaries__new(32, FALSE);
JSON_rrf_state state;
state.name = Str__new();
state.defn = Str__new();
state.dict = known;
TextFiles__read(F, FALSE, "unable to read file of JSON requirements", TRUE,
&JSON__read_requirements_file_helper, NULL, (void *) &state);
JSON__process_req_defn(&state);
return known;
}
void JSON__read_requirements_file_helper(text_stream *text, text_file_position *tfp,
void *v_state) {
JSON_rrf_state *state = (JSON_rrf_state *) v_state;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, text, L" *<(%C+)> *::= *(%c*)")) {
JSON__process_req_defn(state);
WRITE_TO(state->name, "%S", mr.exp[0]);
WRITE_TO(state->defn, "%S", mr.exp[1]);
state->at = *tfp;
} else if (Regexp__match(&mr, text, L" *!%c*")) {
/* do nothing: this line is a comment */
} else if (Regexp__match(&mr, text, L" *")) {
/* do nothing: this line is blank */
} else if (Str__len(state->name) > 0) {
WRITE_TO(state->defn, "%S\n", text);
} else {
Errors__in_text_file_S(TL_IS_51, tfp);
}
}
#line 1383 "inweb/foundation-module/Chapter 4/JSON.w"
void JSON__process_req_defn(JSON_rrf_state *state) {
if (Str__len(state->name) > 0) {
JSON_requirement *req =
JSON__decode_printing_errors(state->defn, state->dict, &(state->at));
if (req) {
dict_entry *de = Dictionaries__create(state->dict, state->name);
if (de) de->value = req;
}
}
Str__clear(state->name);
Str__clear(state->defn);
}
JSON_requirement *JSON__decode_printing_errors(text_stream *defn, dictionary *dict,
text_file_position *tfp) {
JSON_requirement *req = JSON__decode_req(defn, dict);
if (req == NULL) internal_error("decode_req returned NULL");
int errors_found = FALSE;
JSON_single_requirement *sing;
LOOP_OVER_LINKED_LIST(sing, JSON_single_requirement, req->alternatives) {
if ((sing->this_type) && (sing->this_type->JSON_type == ERROR_JSONTYPE)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "JSON requirement error: %S", sing->this_type->if_error);
Errors__in_text_file_S(err, tfp);
errors_found = TRUE;
DISCARD_TEXT(err)
}
}
if (errors_found == FALSE) return req;
return NULL;
}
JSON_requirement *JSON__look_up_requirements(dictionary *known, text_stream *name) {
dict_entry *de = Dictionaries__find(known, name);
if (de == NULL) return NULL;
return de->value;
}
#line 8 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__header(OUTPUT_STREAM, text_stream *title, filename *css1, filename *css2,
filename *js1, filename *js2, void *state) {
HTML__declare_as_HTML(OUT, FALSE);
HTML__begin_head(OUT, NULL);
HTML__title(OUT, title);
if (css1) HTML__incorporate_CSS(OUT, css1);
if (css2) HTML__incorporate_CSS(OUT, css2);
if (js1) HTML__incorporate_javascript(OUT, TRUE, js1);
if (js2) HTML__incorporate_javascript(OUT, TRUE, js2);
#ifdef ADDITIONAL_SCRIPTING_HTML_CALLBACK
ADDITIONAL_SCRIPTING_HTML_CALLBACK(OUT, state);
#endif
HTML__end_head(OUT);
HTML__begin_body(OUT, NULL);
HTML__comment(OUT, TL_IS_52);
}
void HTML__footer(OUTPUT_STREAM) {
WRITE("\n");
HTML__comment(OUT, TL_IS_53);
HTML__end_body(OUT);
}
#line 63 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__declare_as_HTML(OUTPUT_STREAM, int XHTML) {
HTML_file_state *hs = CREATE(HTML_file_state);
hs->XHTML_flag = XHTML;
hs->tag_stack = NEW_LIFO_STACK(HTML_tag);
hs->CSS_included = 0;
hs->JS_included = 0;
Streams__declare_as_HTML(OUT, hs);
}
#line 78 "inweb/foundation-module/Chapter 5/HTML.w"
int unique_xref = 0;
#line 86 "inweb/foundation-module/Chapter 5/HTML.w"
int HTML__push_tag(OUTPUT_STREAM, char *tag, char *fn, int lc) {
int u = unique_xref++;
HTML_file_state *hs = Streams__get_HTML_file_state(OUT);
if (hs) {
HTML_tag *ht = CREATE(HTML_tag);
ht->tag_name = tag;
ht->tag_xref = u;
ht->from_filename = fn;
ht->from_line = lc;
PUSH_TO_LIFO_STACK(ht, HTML_tag, hs->tag_stack);
}
return u;
}
#line 102 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__pop_tag(OUTPUT_STREAM, char *tag, char *fn, int lc) {
HTML_file_state *hs = Streams__get_HTML_file_state(OUT);
if (hs) {
if (LIFO_STACK_EMPTY(HTML_tag, hs->tag_stack)) {
LOG("Trying to close %s at line %d of '%s', but:\n", tag, lc, fn);
tag_error("closed HTML tag which wasn't open");
} else {
HTML_tag *ht = TOP_OF_LIFO_STACK(HTML_tag, hs->tag_stack);
if ((ht == NULL) || (strcmp(tag, ht->tag_name) != 0)) {
LOG("Trying to close %s at line %d of '%s', but:\n", tag, lc, fn);
tag_error("closed HTML tag which wasn't open");
}
POP_LIFO_STACK(HTML_tag, hs->tag_stack);
}
}
}
#line 122 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__completed(OUTPUT_STREAM) {
HTML_file_state *hs = Streams__get_HTML_file_state(OUT);
if ((hs) && (LIFO_STACK_EMPTY(HTML_tag, hs->tag_stack) == FALSE)) {
tag_error("HTML tags still open");
}
}
#line 137 "inweb/foundation-module/Chapter 5/HTML.w"
#define HTML_TAG_WITH(tag, args...) { \
TEMPORARY_TEXT(details) \
WRITE_TO(details, args); \
HTML__tag(OUT, tag, details); \
DISCARD_TEXT(details) \
}
#define HTML_OPEN_WITH(tag, args...) { \
TEMPORARY_TEXT(details) \
WRITE_TO(details, args); \
HTML__open(OUT, tag, details, __FILE__, __LINE__); \
DISCARD_TEXT(details) \
}
#line 154 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__tag(OUTPUT_STREAM, char *tag, text_stream *details) {
WRITE("<%s", tag);
if (Str__len(details) > 0) WRITE(" %S", details);
HTML_file_state *hs = Streams__get_HTML_file_state(OUT);
if ((hs) && (hs->XHTML_flag)) WRITE(" /");
WRITE(">");
if (HTML__tag_formatting(tag) >= 1) WRITE("\n");
}
void HTML__tag_sc(OUTPUT_STREAM, char *tag, text_stream *details) {
WRITE("<%s", tag);
if (Str__len(details) > 0) WRITE(" %S", details);
WRITE(" />");
if (HTML__tag_formatting(tag) >= 1) WRITE("\n");
}
int HTML__tag_formatting(char *tag) {
if (strcmp(tag, "meta") == 0) return 1;
if (strcmp(tag, "link") == 0) return 1;
if (strcmp(tag, "hr") == 0) return 1;
if (strcmp(tag, "br") == 0) return 1;
return 0;
}
void HTML__open(OUTPUT_STREAM, char *tag, text_stream *details, char *fn, int lc) {
int f = HTML__pair_formatting(tag);
HTML__push_tag(OUT, tag, fn, lc);
WRITE("<%s", tag);
if (Str__len(details) > 0) WRITE(" %S", details);
WRITE(">");
if (f >= 2) { WRITE("\n"); INDENT; }
}
void HTML__close(OUTPUT_STREAM, char *tag, char *fn, int lc) {
int f = HTML__pair_formatting(tag);
if (f >= 3) WRITE("\n");
if (f >= 2) OUTDENT;
WRITE("</%s>", tag);
HTML__pop_tag(OUT, tag, fn, lc);
if (f >= 1) WRITE("\n");
}
void HTML__open_indented_p(OUTPUT_STREAM, int depth, char *class) {
int margin = depth;
if (margin < 1) internal_error("minimal HTML indentation is 1");
if (margin > 9) margin = 9;
HTML_OPEN_WITH("p", "class=\"%sin%d\"", class, margin);
while (depth > 9) { depth--; WRITE("&nbsp;&nbsp;&nbsp;&nbsp;"); }
}
int HTML__pair_formatting(char *tag) {
if (strcmp(tag, "td") == 0) return 3;
if (strcmp(tag, "head") == 0) return 2;
if (strcmp(tag, "body") == 0) return 2;
if (strcmp(tag, "div") == 0) return 2;
if (strcmp(tag, "table") == 0) return 2;
if (strcmp(tag, "tr") == 0) return 2;
if (strcmp(tag, "script") == 0) return 2;
if (strcmp(tag, "style") == 0) return 2;
if (strcmp(tag, "html") == 0) return 1;
if (strcmp(tag, "p") == 0) return 1;
if (strcmp(tag, "title") == 0) return 1;
if (strcmp(tag, "blockquote") == 0) return 1;
return 0;
}
#line 227 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_head(OUTPUT_STREAM, filename *CSS_file) {
HTML_file_state *hs = Streams__get_HTML_file_state(OUT);
if ((hs) && (hs->XHTML_flag)) {
WRITE("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ");
WRITE("\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
HTML_OPEN_WITH("html", "xmlns=\"http://www.w3.org/1999/xhtml\"");
} else {
WRITE("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" ");
WRITE("\"http://www.w3.org/TR/html4/loose.dtd\">\n");
HTML_OPEN("html");
}
WRITE("\n");
HTML_OPEN("head");
HTML_TAG_WITH("meta", "http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"");
if (CSS_file)
HTML_TAG_WITH("link", "href=\"%/f\" rel=\"stylesheet\" type=\"text/css\"", CSS_file);
}
void HTML__end_head(OUTPUT_STREAM) {
HTML_CLOSE("head");
}
#line 250 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__title(OUTPUT_STREAM, text_stream *title) {
HTML_OPEN("title");
WRITE("%S", title);
HTML_CLOSE("title");
}
#line 259 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__open_javascript(OUTPUT_STREAM, int define_project) {
HTML_OPEN_WITH("script", "type=\"text/javascript\"");
if (define_project) {
WRITE("function project() {\n"); INDENT;
WRITE("return window.Project;\n");
OUTDENT; WRITE("}\n");
}
}
void HTML__close_javascript(OUTPUT_STREAM) {
HTML_CLOSE("script");
}
dictionary *HTML_incorporation_cache = NULL;
void HTML__incorporate_javascript(OUTPUT_STREAM, int define_project, filename *M) {
HTML__open_javascript(OUT, define_project);
if (HTML_incorporation_cache == NULL)
HTML_incorporation_cache = Dictionaries__new(32, TRUE);
TEMPORARY_TEXT(key)
WRITE_TO(key, "%f", M);
text_stream *existing_entry = Dictionaries__get_text(HTML_incorporation_cache, key);
if (existing_entry) {
WRITE("%S", existing_entry);
} else {
text_stream *new_entry = Dictionaries__create_text(HTML_incorporation_cache, key);
HTML__incorporate_javascript_from_file(new_entry, M);
WRITE("%S", new_entry);
}
DISCARD_TEXT(key)
HTML__close_javascript(OUT);
HTML_file_state *hs = Streams__get_HTML_file_state(OUT);
if (hs) hs->JS_included++;
}
void HTML__incorporate_javascript_from_file(OUTPUT_STREAM, filename *M) {
if (TextFiles__read(M, FALSE, NULL, FALSE, HTML__incorporate_helper, NULL, OUT) == FALSE) {
WRITE_TO(STDERR, "%f", M);
internal_error("Unable to open model JS material for reading");
}
}
void HTML__open_CSS(OUTPUT_STREAM) {
HTML_OPEN_WITH("style", "type=\"text/css\"");
WRITE("<!--\n");
}
void HTML__close_CSS(OUTPUT_STREAM) {
WRITE("-->\n");
HTML_CLOSE("style");
}
void HTML__incorporate_CSS(OUTPUT_STREAM, filename *M) {
if (HTML_incorporation_cache == NULL)
HTML_incorporation_cache = Dictionaries__new(32, TRUE);
TEMPORARY_TEXT(key)
WRITE_TO(key, "%f", M);
text_stream *existing_entry = Dictionaries__get_text(HTML_incorporation_cache, key);
if (existing_entry) {
WRITE("%S", existing_entry);
} else {
text_stream *new_entry = Dictionaries__create_text(HTML_incorporation_cache, key);
HTML__incorporate_CSS_from_file(new_entry, M);
WRITE("%S", new_entry);
}
DISCARD_TEXT(key)
HTML_file_state *hs = Streams__get_HTML_file_state(OUT);
if (hs) hs->CSS_included++;
}
void HTML__incorporate_CSS_from_file(OUTPUT_STREAM, filename *M) {
HTML__open_CSS(OUT);
if (TextFiles__read(M, FALSE, NULL, FALSE, HTML__incorporate_helper, NULL, OUT) == FALSE)
internal_error("Unable to open model CSS material for reading");
HTML__close_CSS(OUT);
}
void HTML__incorporate_HTML(OUTPUT_STREAM, filename *M) {
if (HTML_incorporation_cache == NULL)
HTML_incorporation_cache = Dictionaries__new(32, TRUE);
TEMPORARY_TEXT(key)
WRITE_TO(key, "%f", M);
text_stream *existing_entry = Dictionaries__get_text(HTML_incorporation_cache, key);
if (existing_entry) {
WRITE("%S", existing_entry);
} else {
text_stream *new_entry = Dictionaries__create_text(HTML_incorporation_cache, key);
HTML__incorporate_HTML_from_file(new_entry, M);
WRITE("%S", new_entry);
}
DISCARD_TEXT(key)
}
void HTML__incorporate_HTML_from_file(OUTPUT_STREAM, filename *M) {
if (TextFiles__read(M, FALSE, NULL, FALSE, HTML__incorporate_helper, NULL, OUT) == FALSE)
internal_error("Unable to open model HTML material for reading");
}
#line 360 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__incorporate_helper(text_stream *line_of_template,
text_file_position *tfp, void *OUT) {
WRITE("%S\n", line_of_template);
}
#line 368 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_body(OUTPUT_STREAM, text_stream *class) {
if (class) HTML_OPEN_WITH("body", "class=\"%S\"", class)
else HTML_OPEN("body");
}
void HTML__end_body(OUTPUT_STREAM) {
HTML_CLOSE("body");
HTML_CLOSE("html");
}
#line 381 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_div_with_id(OUTPUT_STREAM, char *id) {
HTML_OPEN_WITH("div", "id=\"%s\"", id);
}
void HTML__begin_div_with_class(OUTPUT_STREAM, char *cl) {
HTML_OPEN_WITH("div", "class=\"%s\"", cl);
}
void HTML__begin_div_with_class_and_id(OUTPUT_STREAM, char *cl, char *id, int hide) {
if (hide) HTML_OPEN_WITH("div", "class=\"%s\" id=\"%s\" style=\"display: none;\"", cl, id)
else HTML_OPEN_WITH("div", "class=\"%s\" id=\"%s\"", cl, id);
}
void HTML__begin_div_with_id_S(OUTPUT_STREAM, text_stream *id, char *fn, int lc) {
TEMPORARY_TEXT(details)
WRITE_TO(details, "id=\"%S\"", id);
HTML__open(OUT, "div", details, fn, lc);
DISCARD_TEXT(details)
}
void HTML__begin_div_with_class_S(OUTPUT_STREAM, text_stream *cl, char *fn, int lc) {
TEMPORARY_TEXT(details)
WRITE_TO(details, "class=\"%S\"", cl);
HTML__open(OUT, "div", details, fn, lc);
DISCARD_TEXT(details)
}
void HTML__begin_div_with_class_and_id_S(OUTPUT_STREAM, text_stream *cl,
text_stream *id, int hide, char *fn, int lc) {
TEMPORARY_TEXT(details)
WRITE_TO(details, "class=\"%S\" id=\"%S\"", cl, id);
if (hide) WRITE_TO(details, " style=\"display: none;\"");
HTML__open(OUT, "div", details, fn, lc);
DISCARD_TEXT(details)
}
void HTML__end_div(OUTPUT_STREAM) {
HTML_CLOSE("div");
}
#line 424 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__image(OUTPUT_STREAM, filename *F) {
HTML_TAG_WITH("img", "src=\"%/f\"", F);
}
void HTML__image_to_dimensions(OUTPUT_STREAM, filename *F, int w, int h) {
if ((w > 0) && (h > 0)) {
HTML_TAG_WITH("img", "src=\"%/f\" alt=\"%S\" width=\"%d\" height=\"%d\"",
F, Filenames__get_leafname(F), w, h);
} else if (w > 0) {
HTML_TAG_WITH("img", "src=\"%/f\" alt=\"%S\" width=\"%d\"",
F, Filenames__get_leafname(F), w);
} else if (h > 0) {
HTML_TAG_WITH("img", "src=\"%/f\" alt=\"%S\" height=\"%d\"",
F, Filenames__get_leafname(F), h);
} else {
HTML_TAG_WITH("img", "src=\"%/f\" alt=\"%S\"",
F, Filenames__get_leafname(F));
}
}
#line 449 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__icon_with_tooltip(OUTPUT_STREAM, text_stream *icon_name,
text_stream *tip, text_stream *tip2) {
TEMPORARY_TEXT(img)
WRITE_TO(img, "border=0 src=%S ", icon_name);
if (tip) {
WRITE_TO(img, "title=\"%S", tip);
if (tip2) WRITE_TO(img, " %S", tip2);
WRITE_TO(img, "\"");
}
HTML_TAG_WITH("img", "%S", img);
DISCARD_TEXT(img)
}
#line 465 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__anchor(OUTPUT_STREAM, text_stream *id) {
HTML_OPEN_WITH("a", "id=\"%S\"", id); HTML_CLOSE("a");
}
void HTML__anchor_with_class(OUTPUT_STREAM, text_stream *id, text_stream *cl) {
HTML_OPEN_WITH("a", "id=\"%S\" class=\"%S\"", id, cl); HTML_CLOSE("a");
}
void HTML__begin_link(OUTPUT_STREAM, text_stream *to) {
HTML_OPEN_WITH("a", "href=\"%S\"", to);
}
void HTML__begin_download_link(OUTPUT_STREAM, text_stream *to) {
HTML_OPEN_WITH("a", "href=\"%S\" download", to);
}
void HTML__begin_link_with_class(OUTPUT_STREAM, text_stream *cl, text_stream *to) {
HTML__begin_link_with_class_onclick(OUT, cl, to, NULL);
}
void HTML__begin_link_with_class_title(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *ti) {
HTML__begin_link_with_class_title_onclick(OUT, cl, to, ti, NULL);
}
void HTML__begin_link_with_class_onclick(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *on) {
HTML__begin_link_with_class_title_onclick(OUT, cl, to, NULL, on);
}
void HTML__begin_link_with_class_title_onclick(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *ti, text_stream *on) {
WRITE("<a href=\"%S\" class=\"%S\"", to, cl);
if (Str__len(ti) > 0) WRITE(" title=\"%S\"", ti);
if (Str__len(on) > 0) WRITE(" onclick=\"%S\"", on);
WRITE(">");
}
void HTML__end_link(OUTPUT_STREAM) {
HTML_CLOSE("a");
}
#line 508 "inweb/foundation-module/Chapter 5/HTML.w"
pathname *abbreviate_links_within = NULL;
void HTML__set_link_abbreviation_path(pathname *P) {
abbreviate_links_within = P;
}
pathname *HTML__get_link_abbreviation_path(void) {
return abbreviate_links_within;
}
#line 520 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_plain_html_table(OUTPUT_STREAM) {
HTML__begin_html_table(OUT, NULL, FALSE, 0, 0, 0, 0, 0);
}
void HTML__begin_wide_html_table(OUTPUT_STREAM) {
HTML__begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
}
#line 531 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_html_table(OUTPUT_STREAM, text_stream *classname, int full_width,
int border, int cellspacing, int cellpadding, int height, int width) {
TEMPORARY_TEXT(tab)
WRITE_TO(tab, "border=\"%d\" cellspacing=\"%d\" cellpadding=\"%d\"",
border, cellspacing, cellpadding);
if (Str__len(classname) > 0) WRITE_TO(tab, " class=\"%S\"", classname);
if (full_width) WRITE_TO(tab, " width=100%%");
if (width > 0) WRITE_TO(tab, " width=\"%d\"", width);
if (height > 0) WRITE_TO(tab, " height=\"%d\"", height);
HTML_OPEN_WITH("table", "%S", tab);
DISCARD_TEXT(tab)
}
void HTML__begin_html_table_bg(OUTPUT_STREAM, text_stream *classname, int full_width,
int border, int cellspacing, int cellpadding, int height, int width, text_stream *bg) {
TEMPORARY_TEXT(tab)
WRITE_TO(tab, "border=\"%d\" cellspacing=\"%d\" cellpadding=\"%d\"",
border, cellspacing, cellpadding);
if (Str__len(bg) > 0) WRITE_TO(tab, " background=\"inform:/%S\"", bg);
if (Str__len(classname) > 0) WRITE_TO(tab, " class=\"%S\"", classname);
if (full_width) WRITE_TO(tab, " width=100%%");
if (width > 0) WRITE_TO(tab, " width=\"%d\"", width);
if (height > 0) WRITE_TO(tab, " height=\"%d\"", height);
HTML_OPEN_WITH("table", "%S", tab);
DISCARD_TEXT(tab)
}
void HTML__first_html_column(OUTPUT_STREAM, int width) {
HTML_OPEN("tr");
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\"");
}
void HTML__first_html_column_nowrap(OUTPUT_STREAM, int width, text_stream *classname) {
if (Str__len(classname) > 0)
HTML_OPEN_WITH("tr", "class=\"%S\"", classname)
else
HTML_OPEN("tr");
TEMPORARY_TEXT(col)
WRITE_TO(col, "style=\"white-space:nowrap;\" align=\"left\" valign=\"top\" height=\"20\"");
if (width > 0) WRITE_TO(col, " width=\"%d\"", width);
HTML_OPEN_WITH("td", "%S", col);
DISCARD_TEXT(col)
}
void HTML__first_html_column_spaced(OUTPUT_STREAM, int width) {
HTML_OPEN("tr");
TEMPORARY_TEXT(col)
WRITE_TO(col, "style=\"padding-top: 3px;\" align=\"left\" valign=\"top\"");
if (width > 0) WRITE_TO(col, " width=\"%d\"", width);
HTML_OPEN_WITH("td", "%S", col);
DISCARD_TEXT(col)
}
void HTML__first_html_column_coloured(OUTPUT_STREAM, int width, text_stream *classname,
int cs) {
if (Str__len(classname) > 0)
HTML_OPEN_WITH("tr", "class=\"%S\"", classname)
else
HTML_OPEN("tr");
TEMPORARY_TEXT(col)
WRITE_TO(col, "nowrap=\"nowrap\" align=\"left\" valign=\"top\"");
if (width > 0) WRITE_TO(col, " width=\"%d\"", width);
if (cs > 0) WRITE_TO(col, " colspan=\"%d\"", cs);
HTML_OPEN_WITH("td", "%S", col);
DISCARD_TEXT(col)
}
void HTML__next_html_column(OUTPUT_STREAM, int width) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_centred(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"center\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"center\" valign=\"top\"");
}
void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" colspan=\"%d\" width=\"%d\"", sp, width)
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" colspan=\"%d\"", sp);
}
void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "style=\"white-space:nowrap;\" align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "style=\"white-space:nowrap;\" align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "style=\"padding-top: 3px;\" align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "style=\"padding-top: 3px;\" align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_nw(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "nowrap=\"nowrap\" align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "nowrap=\"nowrap\" align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_w(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) {
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"right\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"right\" valign=\"top\"");
}
void HTML__end_html_row(OUTPUT_STREAM) {
HTML_CLOSE("td");
HTML_CLOSE("tr");
}
void HTML__end_html_table(OUTPUT_STREAM) {
HTML_CLOSE("table");
}
#line 655 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__open_coloured_box(OUTPUT_STREAM, text_stream *classname, int rounding) {
HTML_OPEN_WITH("table",
"width=\"100%%\" cellpadding=\"6\" cellspacing=\"0\" border=\"0\" "
"class=\"%S\"", classname);
HTML_OPEN("tr");
HTML_OPEN("td");
}
void HTML__close_coloured_box(OUTPUT_STREAM, text_stream *classname, int rounding) {
HTML_CLOSE("td");
HTML_CLOSE("tr");
HTML__end_html_table(OUT);
}
void HTML__box_corner(OUTPUT_STREAM, text_stream *classname, text_stream *corner) {
HTML_TAG_WITH("img",
"src=\"inform:/bg_images/%S_corner_%S.gif\" "
"width=\"%d\" height=\"%d\" border=\"0\" alt=\"...\"",
corner, classname, CORNER_SIZE, CORNER_SIZE);
}
#line 679 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__comment(OUTPUT_STREAM, text_stream *text) {
WRITE("<!--%S-->\n", text);
}
void HTML__heading(OUTPUT_STREAM, char *tag, text_stream *text) {
HTML_OPEN(tag);
WRITE("%S", text);
HTML_CLOSE(tag);
WRITE("\n");
}
void HTML__hr(OUTPUT_STREAM, char *class) {
if (class) HTML_TAG_WITH("hr", "class=\"%s\"", class)
else HTML_TAG("hr");
}
#line 703 "inweb/foundation-module/Chapter 5/HTML.w"
colour_translation table_of_translations[] = {
{ L"Alice Blue", L"F0F8FF" },
{ L"Antique White", L"FAEBD7" },
{ L"Aqua", L"00FFFF" },
{ L"Aquamarine", L"7FFFD4" },
{ L"Azure", L"F0FFFF" },
{ L"Beige", L"F5F5DC" },
{ L"Bisque", L"FFE4C4" },
{ L"Black", L"000000" },
{ L"Blanched Almond", L"FFEBCD" },
{ L"Blue", L"0000FF" },
{ L"Blue Violet", L"8A2BE2" },
{ L"Brown", L"A52A2A" },
{ L"Burly Wood", L"DEB887" },
{ L"Cadet Blue", L"5F9EA0" },
{ L"Chartreuse", L"7FFF00" },
{ L"Chocolate", L"D2691E" },
{ L"Coral", L"FF7F50" },
{ L"Cornflower Blue", L"6495ED" },
{ L"Cornsilk", L"FFF8DC" },
{ L"Crimson", L"DC143C" },
{ L"Cyan", L"00FFFF" },
{ L"Dark Blue", L"00008B" },
{ L"Dark Cyan", L"008B8B" },
{ L"Dark Golden Rod", L"B8860B" },
{ L"Dark Gray", L"A9A9A9" },
{ L"Dark Green", L"006400" },
{ L"Dark Khaki", L"BDB76B" },
{ L"Dark Magenta", L"8B008B" },
{ L"Dark Olive Green", L"556B2F" },
{ L"Dark Orange", L"FF8C00" },
{ L"Dark Orchid", L"9932CC" },
{ L"Dark Red", L"8B0000" },
{ L"Dark Salmon", L"E9967A" },
{ L"Dark Sea Green", L"8FBC8F" },
{ L"Dark Slate Blue", L"483D8B" },
{ L"Dark Slate Gray", L"2F4F4F" },
{ L"Dark Turquoise", L"00CED1" },
{ L"Dark Violet", L"9400D3" },
{ L"Deep Pink", L"FF1493" },
{ L"Deep Sky Blue", L"00BFFF" },
{ L"Dim Gray", L"696969" },
{ L"Dodger Blue", L"1E90FF" },
{ L"Feldspar", L"D19275" },
{ L"Fire Brick", L"B22222" },
{ L"Floral White", L"FFFAF0" },
{ L"Forest Green", L"228B22" },
{ L"Fuchsia", L"FF00FF" },
{ L"Gainsboro", L"DCDCDC" },
{ L"Ghost White", L"F8F8FF" },
{ L"Gold", L"FFD700" },
{ L"Golden Rod", L"DAA520" },
{ L"Gray", L"808080" },
{ L"Green", L"008000" },
{ L"Green Yellow", L"ADFF2F" },
{ L"Honey Dew", L"F0FFF0" },
{ L"Hot Pink", L"FF69B4" },
{ L"Indian Red", L"CD5C5C" },
{ L"Indigo", L"4B0082" },
{ L"Ivory", L"FFFFF0" },
{ L"Khaki", L"F0E68C" },
{ L"Lavender", L"E6E6FA" },
{ L"Lavender Blush", L"FFF0F5" },
{ L"Lawn Green", L"7CFC00" },
{ L"Lemon Chiffon", L"FFFACD" },
{ L"Light Blue", L"ADD8E6" },
{ L"Light Coral", L"F08080" },
{ L"Light Cyan", L"E0FFFF" },
{ L"Light Golden Rod Yellow", L"FAFAD2" },
{ L"Light Grey", L"D3D3D3" },
{ L"Light Green", L"90EE90" },
{ L"Light Pink", L"FFB6C1" },
{ L"Light Salmon", L"FFA07A" },
{ L"Light Sea Green", L"20B2AA" },
{ L"Light Sky Blue", L"87CEFA" },
{ L"Light Slate Blue", L"8470FF" },
{ L"Light Slate Gray", L"778899" },
{ L"Light Steel Blue", L"B0C4DE" },
{ L"Light Yellow", L"FFFFE0" },
{ L"Lime", L"00FF00" },
{ L"Lime Green", L"32CD32" },
{ L"Linen", L"FAF0E6" },
{ L"Magenta", L"FF00FF" },
{ L"Maroon", L"800000" },
{ L"Medium Aquamarine", L"66CDAA" },
{ L"Medium Blue", L"0000CD" },
{ L"Medium Orchid", L"BA55D3" },
{ L"Medium Purple", L"9370D8" },
{ L"Medium Sea Green", L"3CB371" },
{ L"Medium Slate Blue", L"7B68EE" },
{ L"Medium Spring Green", L"00FA9A" },
{ L"Medium Turquoise", L"48D1CC" },
{ L"Medium Violet Red", L"CA226B" },
{ L"Midnight Blue", L"191970" },
{ L"Mint Cream", L"F5FFFA" },
{ L"Misty Rose", L"FFE4E1" },
{ L"Moccasin", L"FFE4B5" },
{ L"Navajo White", L"FFDEAD" },
{ L"Navy", L"000080" },
{ L"Old Lace", L"FDF5E6" },
{ L"Olive", L"808000" },
{ L"Olive Drab", L"6B8E23" },
{ L"Orange", L"FFA500" },
{ L"Orange Red", L"FF4500" },
{ L"Orchid", L"DA70D6" },
{ L"Pale Golden Rod", L"EEE8AA" },
{ L"Pale Green", L"98FB98" },
{ L"Pale Turquoise", L"AFEEEE" },
{ L"Pale Violet Red", L"D87093" },
{ L"Papaya Whip", L"FFEFD5" },
{ L"Peach Puff", L"FFDAB9" },
{ L"Peru", L"CD853F" },
{ L"Pink", L"FFC0CB" },
{ L"Plum", L"DDA0DD" },
{ L"Powder Blue", L"B0E0E6" },
{ L"Purple", L"800080" },
{ L"Red", L"FF0000" },
{ L"Rosy Brown", L"BC8F8F" },
{ L"Royal Blue", L"4169E1" },
{ L"Saddle Brown", L"8B4513" },
{ L"Salmon", L"FA8072" },
{ L"Sandy Brown", L"F4A460" },
{ L"Sea Green", L"2E8B57" },
{ L"Sea Shell", L"FFF5EE" },
{ L"Sienna", L"A0522D" },
{ L"Silver", L"C0C0C0" },
{ L"Sky Blue", L"87CEEB" },
{ L"Slate Blue", L"6A5ACD" },
{ L"Slate Gray", L"708090" },
{ L"Snow", L"FFFAFA" },
{ L"Spring Green", L"00FF7F" },
{ L"Steel Blue", L"4682B4" },
{ L"Tan", L"D2B48C" },
{ L"Teal", L"008080" },
{ L"Thistle", L"D8BFD8" },
{ L"Tomato", L"FF6347" },
{ L"Turquoise", L"40E0D0" },
{ L"Violet", L"EE82EE" },
{ L"Violet Red", L"D02090" },
{ L"Wheat", L"F5DEB3" },
{ L"White", L"FFFFFF" },
{ L"White Smoke", L"F5F5F5" },
{ L"Yellow", L"FFFF00" },
{ L"Yellow Green", L"9ACD32" },
{ L"", L"" }
};
#line 855 "inweb/foundation-module/Chapter 5/HTML.w"
wchar_t *HTML__translate_colour_name(wchar_t *original) {
for (int j=0; Wide__cmp(table_of_translations[j].chip_name, L""); j++)
if (Wide__cmp(table_of_translations[j].chip_name, original) == 0)
return table_of_translations[j].html_colour;
return NULL;
}
#line 863 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_colour(OUTPUT_STREAM, text_stream *col) {
HTML_OPEN_WITH("span", "style='color:#%S'", col);
}
void HTML__end_colour(OUTPUT_STREAM) {
HTML_CLOSE("span");
}
#line 873 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__begin_span(OUTPUT_STREAM, text_stream *class_name) {
if (Str__len(class_name) > 0) {
HTML_OPEN_WITH("span", "class=\"%S\"", class_name);
} else {
HTML_OPEN("span");
}
}
void HTML__end_span(OUTPUT_STREAM) {
HTML_CLOSE("span");
}
#line 888 "inweb/foundation-module/Chapter 5/HTML.w"
void HTML__write_xml_safe_text(OUTPUT_STREAM, text_stream *txt) {
LOOP_THROUGH_TEXT(pos, txt) {
wchar_t c = Str__get(pos);
switch(c) {
case '&': WRITE("&amp;"); break;
case '<': WRITE("&lt;"); break;
case '>': WRITE("&gt;"); break;
default: PUT(c); break;
}
}
}
#line 916 "inweb/foundation-module/Chapter 5/HTML.w"
text_stream *source_ref_fields[3] = { NULL, NULL, NULL }; /* paraphrase, filename, line */
int source_ref_field = -1; /* which field we are buffering */
void HTML__put(OUTPUT_STREAM, int charcode) {
{
#line 943 "inweb/foundation-module/Chapter 5/HTML.w"
if ((source_ref_field >= 0) && (charcode != SOURCE_REF_CHAR)) {
PUT_TO(source_ref_fields[source_ref_field], charcode); return;
}
}
#line 920 "inweb/foundation-module/Chapter 5/HTML.w"
;
switch(charcode) {
case '"': WRITE("&quot;"); break;
case '<': WRITE("&lt;"); break;
case '>': WRITE("&gt;"); break;
case '&': WRITE("&amp;"); break;
case NEWLINE_IN_STRING: HTML_TAG("br"); break;
#ifdef PROBLEMS_MODULE
case FORCE_NEW_PARA_CHAR: HTML_CLOSE("p"); HTML_OPEN_WITH("p", "class=\"in2\"");
HTML__icon_with_tooltip(OUT, TL_IS_54, NULL, NULL);
WRITE("&nbsp;"); break;
#endif
#ifdef WORDS_MODULE
case SOURCE_REF_CHAR:
{
#line 948 "inweb/foundation-module/Chapter 5/HTML.w"
source_ref_field++;
if (source_ref_field == 3) {
source_ref_field = -1;
source_location sl;
sl.file_of_origin = TextFromFiles__filename_to_source_file(source_ref_fields[1]);
sl.line_number = Str__atoi(source_ref_fields[2], 0);
#ifdef HTML_MODULE
SourceLinks__link(OUT, sl, TRUE);
#endif
} else {
if (source_ref_fields[source_ref_field] == NULL)
source_ref_fields[source_ref_field] = Str__new();
Str__clear(source_ref_fields[source_ref_field]);
}
}
#line 935 "inweb/foundation-module/Chapter 5/HTML.w"
; break;
#endif
default: PUT(charcode); break;
}
}
#line 42 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
#line 53 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
#line 63 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
#line 72 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
#line 90 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
#line 96 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
#line 102 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
#line 106 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook *Epub__new(text_stream *title, char *prefix) {
ebook *B = CREATE(ebook);
B->metadata_list = NEW_LINKED_LIST(ebook_datum);
B->OEBPS_path = NULL;
B->ebook_page_list = NEW_LINKED_LIST(ebook_page);
B->ebook_image_list = NEW_LINKED_LIST(ebook_image);
B->ebook_volume_list = NEW_LINKED_LIST(ebook_volume);
B->current_volume = NULL;
B->ebook_chapter_list = NEW_LINKED_LIST(ebook_chapter);
B->current_chapter = NULL;
B->eventual_epub = NULL;
B->prefix = prefix;
Epub__attach_metadata(B, L"title", title);
return B;
}
void Epub__use_CSS_throughout(ebook *B, filename *F) {
B->CSS_file_throughout = F;
}
void Epub__use_CSS(ebook_volume *V, filename *F) {
V->CSS_file = F;
}
text_stream *Epub__attach_metadata(ebook *B, wchar_t *K, text_stream *V) {
ebook_datum *D = NULL;
LOOP_OVER_LINKED_LIST(D, ebook_datum, B->metadata_list)
if (Str__eq_wide_string(D->key, K)) {
Str__copy(D->value, V);
return D->value;
}
D = CREATE(ebook_datum);
D->key = Str__new_from_wide_string(K);
D->value = Str__duplicate(V);
ADD_TO_LINKED_LIST(D, ebook_datum, B->metadata_list);
return D->value;
}
text_stream *Epub__get_metadata(ebook *B, wchar_t *K) {
ebook_datum *D = NULL;
LOOP_OVER_LINKED_LIST(D, ebook_datum, B->metadata_list)
if (Str__eq_wide_string(D->key, K))
return D->value;
return NULL;
}
text_stream *Epub__ensure_metadata(ebook *B, wchar_t *K) {
text_stream *S = Epub__get_metadata(B, K);
if (S == NULL) S = Epub__attach_metadata(B, K, NULL);
return S;
}
ebook_page *Epub__note_page(ebook *B, filename *F, text_stream *title, text_stream *type) {
ebook_page *P = CREATE(ebook_page);
P->relative_URL = F;
P->nav_entry_written = FALSE;
P->in_volume = B->current_volume;
P->in_chapter = B->current_chapter;
P->page_title = Str__duplicate(title);
P->page_type = Str__duplicate(type);
P->page_ID = Str__new();
WRITE_TO(P->page_ID, B->prefix);
Filenames__write_unextended_leafname(P->page_ID, F);
LOOP_THROUGH_TEXT(pos, P->page_ID) {
wchar_t c = Str__get(pos);
if ((c == '-') || (c == ' ')) Str__put(pos, '_');
}
ADD_TO_LINKED_LIST(P, ebook_page, B->ebook_page_list);
return P;
}
void Epub__note_image(ebook *B, filename *F) {
ebook_image *I = CREATE(ebook_image);
I->relative_URL = F;
I->image_ID = Str__new();
Filenames__write_unextended_leafname(I->image_ID, F);
ADD_TO_LINKED_LIST(I, ebook_image, B->ebook_image_list);
}
ebook_volume *Epub__starts_volume(ebook *B, ebook_page *P, text_stream *title) {
ebook_volume *V = CREATE(ebook_volume);
V->volume_starts = P;
P->in_volume = V;
V->volume_title = Str__duplicate(title);
B->current_volume = V;
V->CSS_file = NULL;
ADD_TO_LINKED_LIST(V, ebook_volume, B->ebook_volume_list);
return V;
}
ebook_chapter *Epub__starts_chapter(ebook *B, ebook_page *P, text_stream *title, text_stream *URL) {
ebook_chapter *C = CREATE(ebook_chapter);
C->chapter_starts = P;
C->in_volume = B->current_volume;
C->chapter_title = Str__duplicate(title);
C->start_URL = Str__duplicate(URL);
C->ebook_mark_list = NEW_LINKED_LIST(ebook_mark);
ADD_TO_LINKED_LIST(C, ebook_chapter, B->ebook_chapter_list);
B->current_chapter = C;
P->in_chapter = C;
return C;
}
void Epub__set_mark_in_chapter(ebook_chapter *C, text_stream *text, text_stream *URL) {
ebook_mark *M = CREATE(ebook_mark);
M->mark_text = Str__duplicate(text);
M->mark_URL = Str__duplicate(URL);
ADD_TO_LINKED_LIST(M, ebook_mark, C->ebook_mark_list);
}
#line 223 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
pathname *Epub__begin_construction(ebook *B, pathname *P, filename *cover_image) {
if (Pathnames__create_in_file_system(P) == FALSE) return NULL;
TEMPORARY_TEXT(TEMP)
WRITE_TO(TEMP, "%S.epub", Epub__get_metadata(B, L"title"));
B->eventual_epub = Filenames__in(P, TEMP);
DISCARD_TEXT(TEMP)
pathname *Holder = Pathnames__down(P, TL_IS_55);
if (Pathnames__create_in_file_system(Holder) == FALSE) return NULL;
B->holder = Holder;
{
#line 245 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
filename *Mimetype = Filenames__in(Holder, TL_IS_57);
text_stream EM_struct; text_stream *OUT = &EM_struct;
if (STREAM_OPEN_TO_FILE(OUT, Mimetype, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to open mimetype file for output: %f",
Mimetype);
WRITE("application/epub+zip"); /* EPUB requires there be no newline here */
STREAM_CLOSE(OUT);
}
#line 235 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 254 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
pathname *META_INF = Pathnames__down(Holder, TL_IS_58);
if (Pathnames__create_in_file_system(META_INF) == FALSE) return NULL;
filename *container = Filenames__in(META_INF, TL_IS_59);
text_stream C_struct; text_stream *OUT = &C_struct;
if (STREAM_OPEN_TO_FILE(OUT, container, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to open container file for output: %f",
container);
WRITE("<?xml version=\"1.0\"?>\n");
WRITE("<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n");
INDENT;
WRITE("<rootfiles>\n");
INDENT;
WRITE("<rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\" />\n");
OUTDENT;
WRITE("</rootfiles>\n");
OUTDENT;
WRITE("</container>\n");
STREAM_CLOSE(OUT);
}
#line 236 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
pathname *OEBPS = Pathnames__down(Holder, TL_IS_56);
if (Pathnames__create_in_file_system(OEBPS) == FALSE) return NULL;
if (cover_image)
{
#line 280 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
filename *cover = Filenames__in(OEBPS, TL_IS_60);
text_stream C_struct; text_stream *OUT = &C_struct;
if (STREAM_OPEN_TO_FILE(OUT, cover, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to open cover file for output: %f",
cover);
Epub__note_page(B, cover, TL_IS_61, TL_IS_62);
HTML__declare_as_HTML(OUT, TRUE);
HTML__begin_head(OUT, NULL);
HTML_OPEN("title");
WRITE("Cover");
HTML_CLOSE("title");
HTML_OPEN_WITH("style", "type=\"text/css\"");
WRITE("img { max-width: 100%%; }\n");
HTML_CLOSE("style");
HTML__end_head(OUT);
HTML__begin_body(OUT, NULL);
HTML_OPEN_WITH("div", "id=\"cover-image\"");
HTML_TAG_WITH("img", "src=\"%/f\" alt=\"%S\"", cover_image, Epub__get_metadata(B, L"title"));
WRITE("\n");
HTML_CLOSE("div");
HTML__end_body(OUT);
HTML__completed(OUT);
STREAM_CLOSE(OUT);
}
#line 239 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
B->OEBPS_path = OEBPS;
return OEBPS;
}
#line 307 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
void Epub__end_construction(ebook *B) {
{
#line 315 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
text_stream *datestamp = Epub__ensure_metadata(B, L"date");
if (Str__len(datestamp) == 0) {
WRITE_TO(datestamp, "%04d-%02d-%02d", the_present->tm_year + 1900,
(the_present->tm_mon)+1, the_present->tm_mday);
}
TEMPORARY_TEXT(TEMP)
WRITE_TO(TEMP, "urn:www.inform7.com:");
text_stream *identifier = Epub__ensure_metadata(B, L"identifier");
if (Str__len(identifier) == 0)
WRITE_TO(TEMP, "%S", Epub__get_metadata(B, L"title"));
else
WRITE_TO(TEMP, "%S", identifier);
Str__copy(identifier, TEMP);
DISCARD_TEXT(TEMP)
text_stream *lang = Epub__ensure_metadata(B, L"language");
if (Str__len(lang) == 0) WRITE_TO(lang, "en-UK");
}
#line 308 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 335 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
filename *content = Filenames__in(B->OEBPS_path, TL_IS_63);
text_stream C_struct; text_stream *OUT = &C_struct;
if (STREAM_OPEN_TO_FILE(OUT, content, UTF8_ENC) == FALSE)
Errors__fatal_with_file("unable to open content file for output: %f",
content);
WRITE("<?xml version='1.0' encoding='utf-8'?>\n");
WRITE("<package xmlns=\"http://www.idpf.org/2007/opf\"\n");
WRITE("xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n");
WRITE("unique-identifier=\"bookid\" version=\"2.0\">\n"); INDENT;
{
#line 357 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<metadata>\n"); INDENT;
ebook_datum *D = NULL;
LOOP_OVER_LINKED_LIST(D, ebook_datum, B->metadata_list) {
WRITE("<dc:%S", D->key);
if (Str__eq_wide_string(D->key, L"identifier")) WRITE(" id=\"bookid\"");
WRITE(">");
WRITE("%S</dc:%S>\n", D->value, D->key);
}
WRITE("<meta name=\"cover\" content=\"cover-image\" />\n");
OUTDENT; WRITE("</metadata>\n");
}
#line 345 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 369 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<manifest>\n"); INDENT;
WRITE("<item id=\"ncx\" href=\"toc.ncx\" media-type=\"application/x-dtbncx+xml\"/>\n");
{
#line 377 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
int cssc = 1;
if (B->CSS_file_throughout)
WRITE("<item id=\"css%d\" href=\"%S\" media-type=\"text/css\"/>\n",
cssc++, Filenames__get_leafname(B->CSS_file_throughout));
ebook_volume *V;
LOOP_OVER_LINKED_LIST(V, ebook_volume, B->ebook_volume_list)
if (V->CSS_file)
WRITE("<item id=\"css%d\" href=\"%S\" media-type=\"text/css\"/>\n",
cssc++, Filenames__get_leafname(V->CSS_file));
}
#line 371 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 388 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list)
WRITE("<item id=\"%S\" href=\"%S\" media-type=\"application/xhtml+xml\"/>\n",
P->page_ID, Filenames__get_leafname(P->relative_URL));
}
#line 372 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 394 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_image *I;
LOOP_OVER_LINKED_LIST(I, ebook_image, B->ebook_image_list) {
char *image_type = "";
switch (Filenames__guess_format(I->relative_URL)) {
case FORMAT_PERHAPS_PNG: image_type = "png"; break;
case FORMAT_PERHAPS_JPEG: image_type = "jpeg"; break;
case FORMAT_PERHAPS_SVG: image_type = "svg"; break;
case FORMAT_PERHAPS_GIF: image_type = "gif"; break;
default: Errors__nowhere("image not .gif, .png, .jpg or .svg"); break;
}
WRITE("<item id=\"%S\" href=\"%/f\" media-type=\"image/%s\"/>\n",
I->image_ID, I->relative_URL, image_type);
}
}
#line 373 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
OUTDENT; WRITE("</manifest>\n");
}
#line 346 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 409 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<spine toc=\"ncx\">\n"); INDENT;
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
WRITE("<itemref idref=\"%S\"", P->page_ID);
if (Str__len(P->page_type) > 0) WRITE(" linear=\"no\"");
WRITE("/>\n");
}
OUTDENT; WRITE("</spine>\n");
}
#line 347 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 419 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<guide>\n"); INDENT;
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
if (Str__len(P->page_type) > 0) {
WRITE("<reference href=\"%S\" type=\"%S\" title=\"%S\"/>\n",
Filenames__get_leafname(P->relative_URL), P->page_type, P->page_title);
}
}
OUTDENT; WRITE("</guide>\n");
}
#line 348 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
OUTDENT; WRITE("</package>\n");
STREAM_CLOSE(OUT);
}
#line 309 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 434 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
filename *toc = Filenames__in(B->OEBPS_path, TL_IS_64);
text_stream C_struct; text_stream *OUT = &C_struct;
if (STREAM_OPEN_TO_FILE(OUT, toc, UTF8_ENC) == FALSE)
Errors__fatal_with_file("unable to open ncx file for output: %f",
toc);
WRITE("<?xml version='1.0' encoding='utf-8'?>\n");
WRITE("<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\"\n");
WRITE(" \"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">\n");
WRITE("<ncx xmlns=\"http://www.daisy.org/z3986/2005/ncx/\" version=\"2005-1\">\n");
int depth = 1; /* there are surely at least sections */
if (LinkedLists__len(B->ebook_chapter_list) > 0) depth = 2;
if (LinkedLists__len(B->ebook_volume_list) > 0) depth = 3;
{
#line 456 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<head>\n"); INDENT;
WRITE("<meta name=\"dtb:uid\" content=\"%S\"/>\n", Epub__get_metadata(B, L"identifier"));
WRITE("<meta name=\"dtb:depth\" content=\"%d\"/>\n", depth);
WRITE("<meta name=\"dtb:totalPageCount\" content=\"0\"/>\n");
WRITE("<meta name=\"dtb:maxPageNumber\" content=\"0\"/>\n");
OUTDENT; WRITE("</head>\n");
WRITE("<docTitle>\n"); INDENT;
WRITE("<text>%S</text>\n", Epub__get_metadata(B, L"title"));
OUTDENT; WRITE("</docTitle>\n");
}
#line 449 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 467 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navMap>\n"); INDENT;
int navpoint_count = 1;
int navmap_depth = 1;
int phase = 0;
{
#line 486 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
int in_phase = 1;
if ((Str__eq_wide_string(P->page_ID, L"cover")) ||
(Str__eq_wide_string(P->page_ID, L"index")))
in_phase = 0;
if ((in_phase == phase) && (P->nav_entry_written == FALSE)) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 493 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel> <content src=\"%S\"/>\n",
P->page_title, Filenames__get_leafname(P->relative_URL));
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 496 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
}
#line 471 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
ebook_volume *V = NULL;
LOOP_OVER_LINKED_LIST(V, ebook_volume, B->ebook_volume_list) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 474 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", V->volume_title);
WRITE("<content src=\"%S\"/>\n", Filenames__get_leafname(V->volume_starts->relative_URL));
{
#line 501 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_chapter *C = NULL;
LOOP_OVER_LINKED_LIST(C, ebook_chapter, B->ebook_chapter_list)
if (C->in_volume == V) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 504 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", C->chapter_title);
WRITE("<content src=\"%S\"/>\n", C->start_URL);
if (C->ebook_mark_list)
{
#line 531 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_mark *M;
LOOP_OVER_LINKED_LIST(M, ebook_mark, C->ebook_mark_list) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 533 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", M->mark_text);
WRITE("<content src=\"%S\"/>\n", M->mark_URL);
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 536 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
#line 508 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
else
{
#line 519 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
if ((P->in_chapter == C) && (P->nav_entry_written == FALSE)) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 522 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", P->page_title);
WRITE("<content src=\"%S\"/>\n", Filenames__get_leafname(P->relative_URL));
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 525 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
P->nav_entry_written = TRUE;
}
}
}
#line 510 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list)
if (P->in_chapter == C)
P->nav_entry_written = TRUE;
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 515 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
#line 477 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 478 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
phase = 1;
{
#line 486 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
int in_phase = 1;
if ((Str__eq_wide_string(P->page_ID, L"cover")) ||
(Str__eq_wide_string(P->page_ID, L"index")))
in_phase = 0;
if ((in_phase == phase) && (P->nav_entry_written == FALSE)) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 493 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel> <content src=\"%S\"/>\n",
P->page_title, Filenames__get_leafname(P->relative_URL));
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 496 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
}
#line 481 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
OUTDENT; WRITE("</navMap>\n");
if (navmap_depth != 1) internal_error("navMap numbering unbalanced");
}
#line 450 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("</ncx>\n");
STREAM_CLOSE(OUT);
}
#line 310 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 551 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
pathname *up = Pathnames__from_text(TL_IS_65);
filename *ePub_relative =
Filenames__in(up, Filenames__get_leafname(B->eventual_epub));
{
#line 558 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
TEMPORARY_TEXT(COMMAND)
Shell__plain(COMMAND, "cd ");
Shell__quote_path(COMMAND, B->holder);
Shell__plain(COMMAND, "; zip -0Xq ");
Shell__quote_file(COMMAND, ePub_relative);
Shell__plain(COMMAND, " mimetype");
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
#line 554 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 568 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
TEMPORARY_TEXT(COMMAND)
Shell__plain(COMMAND, "cd ");
Shell__quote_path(COMMAND, B->holder);
Shell__plain(COMMAND, "; zip -Xr9Dq ");
Shell__quote_file(COMMAND, ePub_relative);
Shell__plain(COMMAND, " *");
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
#line 555 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
#line 311 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
#line 10 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_int8(FILE *binary_file, unsigned int *result) {
int c1 = getc(binary_file);
if (c1 == EOF) return FALSE;
*result = (unsigned int) c1;
return TRUE;
}
int BinaryFiles__read_int16(FILE *binary_file, unsigned int *result) {
int c1, c2;
c1 = getc(binary_file);
c2 = getc(binary_file);
if (c1 == EOF || c2 == EOF) return FALSE;
*result = (((unsigned int) c1) << 8) + ((unsigned int) c2);
return TRUE;
}
int BinaryFiles__read_int32(FILE *binary_file, unsigned int *result) {
int c1, c2, c3, c4;
c1 = getc(binary_file);
c2 = getc(binary_file);
c3 = getc(binary_file);
c4 = getc(binary_file);
if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF) return FALSE;
*result = (((unsigned int) c1) << 24) +
(((unsigned int) c2) << 16) +
(((unsigned int) c3) << 8) + ((unsigned int) c4);
return TRUE;
}
int BinaryFiles__read_int64(FILE *binary_file, unsigned long long *result) {
int c1, c2, c3, c4, c5, c6, c7, c8;
c1 = getc(binary_file);
c2 = getc(binary_file);
c3 = getc(binary_file);
c4 = getc(binary_file);
c5 = getc(binary_file);
c6 = getc(binary_file);
c7 = getc(binary_file);
c8 = getc(binary_file);
if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF || c5 == EOF
|| c6 == EOF || c7 == EOF || c8 == EOF) return FALSE;
*result = (((unsigned long long) c1) << 56) +
(((unsigned long long) c2) << 48) +
(((unsigned long long) c3) << 40) +
(((unsigned long long) c4) << 32) +
(((unsigned long long) c5) << 24) +
(((unsigned long long) c6) << 16) +
(((unsigned long long) c7) << 8) +
((unsigned long long) c8);
return TRUE;
}
#line 70 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__write_int32(FILE *binary_file, unsigned int val) {
int c1 = (int) ((val >> 24) & 0xFF);
int c2 = (int) ((val >> 16) & 0xFF);
int c3 = (int) ((val >> 8) & 0xFF);
int c4 = (int) (val & 0xFF);
if (putc(c1, binary_file) == EOF) return FALSE;
if (putc(c2, binary_file) == EOF) return FALSE;
if (putc(c3, binary_file) == EOF) return FALSE;
if (putc(c4, binary_file) == EOF) return FALSE;
return TRUE;
}
#line 87 "inweb/foundation-module/Chapter 6/Binary Files.w"
void BinaryFiles__swap_bytes32(unsigned int *value) {
unsigned int result = (((*value & 0xff) << 24) +
((*value & 0xff00) << 8) +
((*value & 0xff0000) >> 8) +
((*value & 0xff000000) >> 24 ) );
*value = result;
}
void BinaryFiles__swap_bytes64(unsigned long long *value) {
unsigned long long result = (((*value & 0xff) << 56) +
((*value & 0xff00) << 40) +
((*value & 0xff0000) << 24) +
((*value & 0xff000000) << 8) +
((*value >> 8) & 0xff000000) +
((*value >> 24) & 0xff0000) +
((*value >> 40) & 0xff00) +
((*value >> 56) & 0xff) );
*value = result;
}
#line 113 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_variable_length_integer(FILE *binary_file, unsigned int *result) {
int c;
*result = 0;
do {
c = getc(binary_file);
if (c == EOF) return FALSE;
*result = (*result << 7) + (((unsigned char) c) & 0x7F);
} while (((unsigned char) c) & 0x80);
return TRUE;
}
#line 130 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_float80(FILE *binary_file, unsigned int *result) {
int c1, c2, exp;
unsigned int prev = 0, mantissa;
c1 = getc(binary_file);
c2 = getc(binary_file);
if (c1 == EOF || c2 == EOF) return FALSE;
if (!BinaryFiles__read_int32(binary_file, &mantissa)) return FALSE;
exp = 30 - c2;
while (exp--) {
prev = mantissa;
mantissa >>= 1;
}
if (prev & 1) mantissa++;
*result = (unsigned int) mantissa;
return TRUE;
}
#line 155 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__read_string(FILE *binary_file, char *string, unsigned int length) {
if (length > 0) {
if (fread(string, 1, length, binary_file) != length) return FALSE;
}
string[length] = 0;
return TRUE;
}
#line 167 "inweb/foundation-module/Chapter 6/Binary Files.w"
long int BinaryFiles__size(filename *F) {
FILE *TEST_FILE = BinaryFiles__try_to_open_for_reading(F);
if (TEST_FILE) {
if (fseek(TEST_FILE, 0, SEEK_END) == 0) {
long int file_size = ftell(TEST_FILE);
if (file_size == -1L) Errors__fatal_with_file("ftell failed on linked file", F);
BinaryFiles__close(TEST_FILE);
return file_size;
} else Errors__fatal_with_file("fseek failed on linked file", F);
BinaryFiles__close(TEST_FILE);
}
return -1L;
}
#line 184 "inweb/foundation-module/Chapter 6/Binary Files.w"
FILE *BinaryFiles__open_for_reading(filename *F) {
FILE *handle = Filenames__fopen(F, "rb");
if (handle == NULL) Errors__fatal_with_file("unable to read file", F);
return handle;
}
FILE *BinaryFiles__try_to_open_for_reading(filename *F) {
return Filenames__fopen(F, "rb");
}
FILE *BinaryFiles__open_for_writing(filename *F) {
FILE *handle = Filenames__fopen(F, "wb");
if (handle == NULL) Errors__fatal_with_file("unable to write file", F);
return handle;
}
FILE *BinaryFiles__try_to_open_for_writing(filename *F) {
return Filenames__fopen(F, "wb");
}
void BinaryFiles__close(FILE *handle) {
fclose(handle);
}
#line 213 "inweb/foundation-module/Chapter 6/Binary Files.w"
int BinaryFiles__copy(filename *from, filename *to, int suppress_error) {
if ((from == NULL) || (to == NULL))
Errors__fatal("files confused in copier");
FILE *FROM = BinaryFiles__try_to_open_for_reading(from);
if (FROM == NULL) {
if (suppress_error == FALSE) Errors__fatal_with_file("unable to read file", from);
return -1;
}
FILE *TO = BinaryFiles__try_to_open_for_writing(to);
if (TO == NULL) {
if (suppress_error == FALSE) Errors__fatal_with_file("unable to write to file", to);
return -1;
}
int size = 0;
while (TRUE) {
int c = fgetc(FROM);
if (c == EOF) break;
size++;
putc(c, TO);
}
BinaryFiles__close(FROM); BinaryFiles__close(TO);
return size;
}
#line 259 "inweb/foundation-module/Chapter 6/Binary Files.w"
void BinaryFiles__md5(OUTPUT_STREAM, filename *F, int (*mask)(uint64_t)) {
uint32_t s[64] = {
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 };
uint32_t K[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
uint32_t a0 = 0x67452301;
uint32_t b0 = 0xefcdab89;
uint32_t c0 = 0x98badcfe;
uint32_t d0 = 0x10325476;
unsigned int buffer[64];
int bc = 0;
FILE *bin = BinaryFiles__open_for_reading(F);
if (bin == NULL) Errors__fatal_with_file("unable to open binary file", F);
unsigned int b = 0;
uint64_t L = 0;
while (BinaryFiles__read_int8(bin, &b)) {
if ((mask) && (mask(L))) b = 0;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 297 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
L++;
}
uint64_t original_length = L*8;
b = 0x80;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 303 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
L++;
while (L % 64 != 56) {
b = 0;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 307 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
L++;
}
b = (original_length & 0x00000000000000FF) >> 0;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 312 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
b = (original_length & 0x000000000000FF00) >> 8;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 314 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
b = (original_length & 0x0000000000FF0000) >> 16;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 316 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
b = (original_length & 0x00000000FF000000) >> 24;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 318 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
b = (original_length & 0x000000FF00000000) >> 32;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 320 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
b = (original_length & 0x0000FF0000000000) >> 40;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 322 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
b = (original_length & 0x00FF000000000000) >> 48;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 324 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
b = (original_length & 0xFF00000000000000) >> 56;
{
#line 341 "inweb/foundation-module/Chapter 6/Binary Files.w"
buffer[bc++] = (b % 0x100);
if (bc == 64) {
bc = 0;
uint32_t M[16];
for (uint32_t i=0; i<16; i++)
M[i] = buffer[i*4+3]*0x1000000 + buffer[i*4+2]*0x10000 +
buffer[i*4+1]*0x100 + buffer[i*4+0];
uint32_t A = a0;
uint32_t B = b0;
uint32_t C = c0;
uint32_t D = d0;
for (uint32_t i=0; i<64; i++) {
uint32_t F, g;
if (i < 16) {
F = (B & C) | ((~ B) & D);
g = i;
} else if (i < 32) {
F = (D & B) | ((~ D) & C);
g = (5*i + 1) % 16;
} else if (i < 48) {
F = B ^ C ^ D;
g = (3*i + 5) % 16;
} else {
F = C ^ (B | (~ D));
g = (7*i) % 16;
}
F += A + K[i] + M[g];
A = D;
D = C;
C = B;
B = B + BinaryFiles__rotate(F, s[i]);
}
a0 += A;
b0 += B;
c0 += C;
d0 += D;
}
}
#line 326 "inweb/foundation-module/Chapter 6/Binary Files.w"
;
WRITE("%02x%02x%02x%02x",
a0 % 0x100, (a0 >> 8) % 0x100, (a0 >> 16) % 0x100, (a0 >> 24) % 0x100);
WRITE("%02x%02x%02x%02x",
b0 % 0x100, (b0 >> 8) % 0x100, (b0 >> 16) % 0x100, (b0 >> 24) % 0x100);
WRITE("%02x%02x%02x%02x",
c0 % 0x100, (c0 >> 8) % 0x100, (c0 >> 16) % 0x100, (c0 >> 24) % 0x100);
WRITE("%02x%02x%02x%02x",
d0 % 0x100, (d0 >> 8) % 0x100, (d0 >> 16) % 0x100, (d0 >> 24) % 0x100);
BinaryFiles__close(bin);
}
#line 383 "inweb/foundation-module/Chapter 6/Binary Files.w"
uint32_t BinaryFiles__rotate(uint32_t value, uint32_t shift) {
if ((shift &= sizeof(value)*8 - 1) == 0) return value;
return (value << shift) | (value >> (sizeof(value)*8 - shift));
}
#line 24 "inweb/foundation-module/Chapter 6/Image Dimensions.w"
int ImageFiles__get_JPEG_dimensions(FILE *JPEG_file, unsigned int *width, unsigned int *height) {
unsigned int sig, length;
int marker;
if (!BinaryFiles__read_int16(JPEG_file, &sig)) return FALSE;
if (sig != 0xFFD8) return FALSE; /* |0xFF| (marker) then |0xD8| (SOI) */
do {
do {
marker = getc(JPEG_file);
if (marker == EOF) return FALSE;
} while (marker != 0xff); /* skip to next |0xFF| byte */
do {
marker = getc(JPEG_file);
} while (marker == 0xff); /* skip to next non |FF| byte */
if (!BinaryFiles__read_int16(JPEG_file, &length)) return FALSE; /* length of marker */
switch(marker) {
/* all variant forms of "start of frame": e.g., |0xC0| is a baseline DCT image */
case 0xc0:
case 0xc1: case 0xc2: case 0xc3:
case 0xc5: case 0xc6: case 0xc7:
case 0xc9: case 0xca: case 0xcb:
case 0xcd: case 0xce: case 0xcf: {
/* fortunately these markers all then open with the same format */
if (getc(JPEG_file) == EOF) return FALSE; /* skip 1 byte of data precision */
if (!BinaryFiles__read_int16(JPEG_file, height)) return FALSE;
if (!BinaryFiles__read_int16(JPEG_file, width)) return FALSE;
return TRUE;
}
default:
if (fseek(JPEG_file, (long) (length - 2), SEEK_CUR) != 0) return FALSE; /* skip rest of marker */
}
}
while (marker != EOF);
return FALSE;
}
#line 77 "inweb/foundation-module/Chapter 6/Image Dimensions.w"
int ImageFiles__get_PNG_dimensions(FILE *PNG_file, unsigned int *width, unsigned int *height) {
unsigned int sig1, sig2, length, type;
/* Check PNG signature */
if (!BinaryFiles__read_int32(PNG_file, &sig1)) return FALSE;
if (!BinaryFiles__read_int32(PNG_file, &sig2)) return FALSE;
if ((sig1 != 0x89504e47) || (sig2 != 0x0d0a1a0a)) return FALSE;
/* Read first chunk */
if (!BinaryFiles__read_int32(PNG_file, &length)) return FALSE;
if (!BinaryFiles__read_int32(PNG_file, &type)) return FALSE;
/* First chunk must be IHDR */
if (type != 0x49484452) return FALSE;
/* Width and height follow */
if (!BinaryFiles__read_int32(PNG_file, width)) return FALSE;
if (!BinaryFiles__read_int32(PNG_file, height)) return FALSE;
return TRUE;
}
#line 12 "inweb/foundation-module/Chapter 6/Sound Durations.w"
int SoundFiles__get_AIFF_duration(FILE *pFile, unsigned int *pDuration,
unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) {
unsigned int sig;
unsigned int chunkID;
unsigned int chunkLength;
unsigned int numSampleFrames;
unsigned int sampleSize;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x464F524D) return FALSE; /* |"FORM"| indicating an IFF file */
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x41494646) return FALSE; /* |"AIFF"| indicating an AIFF file */
/* Read chunks, skipping over those we are not interested in */
while (TRUE) {
if (!BinaryFiles__read_int32(pFile, &chunkID)) return FALSE;
if (!BinaryFiles__read_int32(pFile, &chunkLength)) return FALSE;
if (chunkID == 0x434F4D4D) { /* |"COMM"| indicates common AIFF data */
if (chunkLength < 18) return FALSE; /* Check we have enough data to read */
if (!BinaryFiles__read_int16(pFile, pChannels)) return FALSE;
if (!BinaryFiles__read_int32(pFile, &numSampleFrames)) return FALSE;
if (!BinaryFiles__read_int16(pFile, &sampleSize)) return FALSE;
if (!BinaryFiles__read_float80(pFile, pSampleRate)) return FALSE;
if (*pSampleRate == 0) return FALSE; /* Sanity check to avoid a divide by zero */
/* Result is in centiseconds */
*pDuration = (unsigned int) (((unsigned long long) numSampleFrames * 100) / *pSampleRate);
*pBitsPerSecond = *pSampleRate * *pChannels * sampleSize;
break;
} else {
/* Skip unwanted chunk */
if (fseek(pFile, (long) chunkLength, SEEK_CUR) != 0) return FALSE;
}
}
return TRUE;
}
#line 59 "inweb/foundation-module/Chapter 6/Sound Durations.w"
int SoundFiles__get_OggVorbis_duration(FILE *pFile, unsigned int *pDuration,
unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) {
unsigned int sig;
unsigned int version;
unsigned int numSegments;
unsigned int packetType;
unsigned int vorbisSig1;
unsigned int vorbisSig2;
unsigned int seekPos;
unsigned int fileLength, bytesToRead, lastSig, index;
unsigned long long granulePosition;
unsigned char buffer[256];
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x4F676753) return FALSE; /* |"OggS"| indicating an OGG file */
/* Check OGG version is zero */
if (!BinaryFiles__read_int8(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Skip header type, granule position, serial number, page sequence and CRC */
if (fseek(pFile, 21, SEEK_CUR) != 0) return FALSE;
/* Read number of page segments */
if (!BinaryFiles__read_int8(pFile, &numSegments)) return FALSE;
/* Skip segment table */
if (fseek(pFile, (long) numSegments, SEEK_CUR) != 0) return FALSE;
/* Vorbis Identification header */
if (!BinaryFiles__read_int8(pFile, &packetType)) return FALSE;
if (packetType != 1) return FALSE;
if (!BinaryFiles__read_int32(pFile, &vorbisSig1)) return FALSE;
if (vorbisSig1 != 0x766F7262) return FALSE; /* |"VORB"| */
if (!BinaryFiles__read_int16(pFile, &vorbisSig2)) return FALSE;
if (vorbisSig2 != 0x6973) return FALSE; /* |"IS"| */
/* Check Vorbis version is zero */
if (!BinaryFiles__read_int32(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Read number of channels */
if (!BinaryFiles__read_int8(pFile, pChannels)) return FALSE;
/* Read sample rate */
if (!BinaryFiles__read_int32(pFile, pSampleRate)) return FALSE;
BinaryFiles__swap_bytes32(pSampleRate); /* Ogg Vorbis uses LSB first */
/* Skip bitrate maximum */
if (fseek(pFile, 4, SEEK_CUR) != 0) return FALSE;
/* Read Nominal Bitrate */
if (!BinaryFiles__read_int32(pFile, pBitsPerSecond)) return FALSE;
BinaryFiles__swap_bytes32(pBitsPerSecond); /* Ogg Vorbis uses LSB first */
/* Encoders can be unhelpful and give no bitrate in the header */
if (pBitsPerSecond == 0) return FALSE;
/* Search for the final Ogg page (near the end of the file) to read duration, */
/* i.e., read the last 4K of the file and look for the final |"OggS"| sig */
if (fseek(pFile, 0, SEEK_END) != 0) return FALSE;
fileLength = (unsigned int) ftell(pFile);
if (fileLength < 4096) seekPos = 0;
else seekPos = fileLength - 4096;
lastSig = 0xFFFFFFFF;
while (seekPos < fileLength) {
if (fseek(pFile, (long) seekPos, SEEK_SET) != 0) return FALSE;
bytesToRead = fileLength - seekPos;
if (bytesToRead > 256) bytesToRead = 256;
if (fread(buffer, 1, bytesToRead, pFile) != bytesToRead) return FALSE;
for(index = 0; index < bytesToRead; index++) {
if ((buffer[index] == 0x4F) &&
(buffer[index + 1] == 0x67) &&
(buffer[index + 2] == 0x67) &&
(buffer[index + 3] == 0x53)) {
lastSig = seekPos + index;
}
}
/* Next place to read from is 256 bytes further on, but to catch */
/* sigs that span between these blocks, read the last four bytes again */
seekPos += 256 - 4;
}
if (lastSig == 0xFFFFFFFF) return FALSE;
if (fseek(pFile, (long) lastSig, SEEK_SET) != 0) return FALSE;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x4F676753) return FALSE; /* |"OggS"| indicating an OGG file */
/* Check OGG version is zero */
if (!BinaryFiles__read_int8(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Skip header Type */
if (fseek(pFile, 1, SEEK_CUR) != 0) return FALSE;
if (!BinaryFiles__read_int64(pFile, &granulePosition)) return FALSE;
BinaryFiles__swap_bytes64(&granulePosition);
*pDuration = (unsigned int) ((granulePosition * 100) /
(unsigned long long) *pSampleRate);
return TRUE;
}
#line 181 "inweb/foundation-module/Chapter 6/Sound Durations.w"
int SoundFiles__get_MIDI_information(FILE *pFile, unsigned int *pType,
unsigned int *pNumTracks) {
unsigned int sig;
unsigned int length;
unsigned int pulses;
unsigned int frames_per_second;
unsigned int subframes_per_frame;
unsigned int clocks_per_second;
unsigned int start_of_chunk_data;
unsigned int status;
unsigned int clocks;
unsigned int sysex_length;
unsigned int non_midi_event_length;
unsigned int start_of_non_midi_data;
unsigned int non_midi_event;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
/* |"RIFF"| indicating a RIFF file */
if (sig == 0x52494646) {
/* Skip the filesize and typeID */
if (fseek(pFile, 8, SEEK_CUR) != 0) return FALSE;
/* now read the real MIDI sig */
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
}
/* |"MThd"| indicating a MIDI file */
if (sig != 0x4D546864) return FALSE;
/* Read length of chunk */
if (!BinaryFiles__read_int32(pFile, &length)) return FALSE;
/* Make sure we have enough data to read */
if (length < 6) return FALSE;
/* Read the MIDI type: 0,1 or 2 */
/* 0 means one track containing up to 16 channels to make a single tune */
/* 1 means one or more tracks, commonly each with a single channel, making up a single tune */
/* 2 means one or more tracks, where each is a separate tune in it's own right */
if (!BinaryFiles__read_int16(pFile, pType)) return FALSE;
/* Read the number of tracks */
if (!BinaryFiles__read_int16(pFile, pNumTracks)) return FALSE;
/* Read "Pulses Per Quarter Note" (PPQN) */
if (!BinaryFiles__read_int16(pFile, &pulses)) return FALSE;
/* if top bit set, then number of subframes per second can be deduced */
if (pulses >= 0x8000) {
/* First byte is a negative number for the frames per second */
/* Second byte is the number of subframes in each frame */
frames_per_second = (256 - (pulses & 0xff));
subframes_per_frame = (pulses >> 8);
clocks_per_second = frames_per_second * subframes_per_frame;
LOG("frames_per_second = %d\n", frames_per_second);
LOG("subframes_per_frame = %d\n", subframes_per_frame);
LOG("clocks_per_second = %d\n", clocks_per_second);
/* Number of pulses per quarter note unknown */
pulses = 0;
} else {
/* unknown values */
frames_per_second = 0;
subframes_per_frame = 0;
clocks_per_second = 0;
LOG("pulses per quarter note = %d\n", pulses);
}
/* Skip any remaining bytes in the MThd chunk */
if (fseek(pFile, (long) (length - 6), SEEK_CUR) != 0) return FALSE;
/* Keep reading chunks, looking for |"MTrk"| */
do {
/* Read chunk signature and length */
if (!BinaryFiles__read_int32(pFile, &sig)) {
if (feof(pFile)) return TRUE;
return FALSE;
}
if (!BinaryFiles__read_int32(pFile, &length)) return FALSE;
start_of_chunk_data = (unsigned int) ftell(pFile);
if (sig == 0x4D54726B) { /* |"MTrk"| */
LOG("track starts\n");
/* Read each event, looking for information before the real tune starts, e.g., tempo */
do {
/* Read the number of clocks since the previous event */
if (!BinaryFiles__read_variable_length_integer(pFile, &clocks))
return FALSE;
/* We bail out when the track starts */
if (clocks > 0) break;
/* Read the MIDI Status byte */
if (!BinaryFiles__read_int8(pFile, &status)) return FALSE;
/* Start or continuation of system exclusive data */
if ((status == 0xF0) || (status == 0xF7)) {
/* Read length of system exclusive event data */
if (!BinaryFiles__read_variable_length_integer(pFile, &sysex_length)) return FALSE;
/* Skip sysex event */
if (fseek(pFile, (long) sysex_length, SEEK_CUR) != 0) return FALSE;
} else if (status == 0xFF) { /* Non-MIDI event */
/* Read the Non-MIDI event type and length */
if (!BinaryFiles__read_int8(pFile, &non_midi_event)) return FALSE;
if (!BinaryFiles__read_variable_length_integer(pFile, &non_midi_event_length))
return FALSE;
start_of_non_midi_data = (unsigned int) ftell(pFile);
switch(non_midi_event) {
case 0x01: /* Comment text */
case 0x02: /* Copyright text */
case 0x03: /* Track name */
case 0x04: { /* Instrument name */
char text[257];
if (!BinaryFiles__read_string(pFile, text, non_midi_event_length))
return FALSE;
LOG("%d: %s\n", non_midi_event, text);
break;
}
case 0x51: /* Tempo change */
case 0x58: /* Time signature */
case 0x59: /* Key signature */
break;
}
/* Skip non-midi event */
if (fseek(pFile,
(long) (start_of_non_midi_data + non_midi_event_length), SEEK_SET) != 0)
return FALSE;
} else {
/* Real MIDI data found: we've read all we can so bail out at this point */
break;
}
}
while (TRUE);
}
/* Seek to start of next chunk */
if (fseek(pFile, (long) (start_of_chunk_data + length), SEEK_SET) != 0) return FALSE;
/* Reached end of file */
if (feof(pFile)) return TRUE;
/* Did we try to seek beyond the end of the file? */
unsigned int position_in_file = (unsigned int) ftell(pFile);
if (position_in_file < (start_of_chunk_data + length)) return TRUE;
}
while (TRUE);
return TRUE;
}
#line 65 "inweb/foundation-module/Chapter 7/Version Numbers.w"
#line 70 "inweb/foundation-module/Chapter 7/Version Numbers.w"
#line 77 "inweb/foundation-module/Chapter 7/Version Numbers.w"
semantic_version_number VersionNumbers__null(void) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconditional-uninitialized"
semantic_version_number V;
for (int i=0; i<SEMVER_NUMBER_DEPTH; i++) V.version_numbers[i] = -1;
V.prerelease_segments = NULL;
V.build_metadata = NULL;
return V;
#pragma clang diagnostic pop
}
int VersionNumbers__is_null(semantic_version_number V) {
for (int i=0, allow=TRUE; i<SEMVER_NUMBER_DEPTH; i++) {
if (V.version_numbers[i] < -1) return TRUE; /* should never happen */
if (V.version_numbers[i] == -1) allow = FALSE;
else if (allow == FALSE) return TRUE; /* should never happen */
}
if (V.version_numbers[0] < 0) return TRUE;
return FALSE;
}
#line 102 "inweb/foundation-module/Chapter 7/Version Numbers.w"
void VersionNumbers__to_text(OUTPUT_STREAM, semantic_version_number V) {
if (VersionNumbers__is_null(V)) { WRITE("null"); return; }
for (int i=0; (i<SEMVER_NUMBER_DEPTH) && (V.version_numbers[i] >= 0); i++) {
if (i>0) WRITE(".");
WRITE("%d", V.version_numbers[i]);
}
if (V.prerelease_segments) {
int c = 0;
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, V.prerelease_segments) {
if (c++ == 0) WRITE("-"); else WRITE(".");
WRITE("%S", T);
}
}
if (V.build_metadata) WRITE("+%S", V.build_metadata);
}
#line 125 "inweb/foundation-module/Chapter 7/Version Numbers.w"
void VersionNumbers__writer(OUTPUT_STREAM, char *format_string, void *vE) {
semantic_version_number *V = (semantic_version_number *) vE;
VersionNumbers__to_text(OUT, *V);
}
#line 141 "inweb/foundation-module/Chapter 7/Version Numbers.w"
#line 143 "inweb/foundation-module/Chapter 7/Version Numbers.w"
semantic_version_number VersionNumbers__from_text(text_stream *T) {
semantic_version_number V = VersionNumbers__null();
int component = 0, val = -1, dots_used = 0, slashes_used = 0, count = 0;
int part = MMP_SEMVERPART;
TEMPORARY_TEXT(prerelease)
LOOP_THROUGH_TEXT(pos, T) {
wchar_t c = Str__get(pos);
switch (part) {
case MMP_SEMVERPART:
if (c == '.') dots_used++;
if (c == '/') slashes_used++;
if ((c == '.') || (c == '/') || (c == '-') || (c == '+')) {
if (val == -1) return VersionNumbers__null();
if (component >= SEMVER_NUMBER_DEPTH) return VersionNumbers__null();
V.version_numbers[component] = val;
component++; val = -1; count = 0;
if (c == '-') part = PRE_SEMVERPART;
if (c == '+') part = BM_SEMVERPART;
} else if (Characters__isdigit(c)) {
int digit = c - '0';
if ((val == 0) && (slashes_used == 0))
return VersionNumbers__null();
if (val < 0) val = digit; else val = 10*val + digit;
count++;
} else return VersionNumbers__null();
break;
case PRE_SEMVERPART:
if (c == '.') {
{
#line 202 "inweb/foundation-module/Chapter 7/Version Numbers.w"
if (Str__len(prerelease) == 0) return VersionNumbers__null();
if (V.prerelease_segments == NULL) V.prerelease_segments = NEW_LINKED_LIST(text_stream);
ADD_TO_LINKED_LIST(Str__duplicate(prerelease), text_stream, V.prerelease_segments);
Str__clear(prerelease);
}
#line 171 "inweb/foundation-module/Chapter 7/Version Numbers.w"
;
} else if (c == '+') {
{
#line 202 "inweb/foundation-module/Chapter 7/Version Numbers.w"
if (Str__len(prerelease) == 0) return VersionNumbers__null();
if (V.prerelease_segments == NULL) V.prerelease_segments = NEW_LINKED_LIST(text_stream);
ADD_TO_LINKED_LIST(Str__duplicate(prerelease), text_stream, V.prerelease_segments);
Str__clear(prerelease);
}
#line 173 "inweb/foundation-module/Chapter 7/Version Numbers.w"
; part = BM_SEMVERPART;
} else {
PUT_TO(prerelease, c);
}
break;
case BM_SEMVERPART:
if (V.build_metadata == NULL) V.build_metadata = Str__new();
PUT_TO(V.build_metadata, c);
break;
}
}
if ((part == PRE_SEMVERPART) && (Str__len(prerelease) > 0))
{
#line 202 "inweb/foundation-module/Chapter 7/Version Numbers.w"
if (Str__len(prerelease) == 0) return VersionNumbers__null();
if (V.prerelease_segments == NULL) V.prerelease_segments = NEW_LINKED_LIST(text_stream);
ADD_TO_LINKED_LIST(Str__duplicate(prerelease), text_stream, V.prerelease_segments);
Str__clear(prerelease);
}
#line 184 "inweb/foundation-module/Chapter 7/Version Numbers.w"
;
DISCARD_TEXT(prerelease)
if ((dots_used > 0) && (slashes_used > 0)) return VersionNumbers__null();
if (slashes_used > 0) {
if (component > 1) return VersionNumbers__null();
if (count != 6) return VersionNumbers__null();
V.version_numbers[1] = 0;
component = 2;
}
if (part == MMP_SEMVERPART) {
if (val == -1) return VersionNumbers__null();
if (component >= SEMVER_NUMBER_DEPTH) return VersionNumbers__null();
V.version_numbers[component] = val;
}
return V;
}
#line 218 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__le(semantic_version_number V1, semantic_version_number V2) {
for (int i=0; i<SEMVER_NUMBER_DEPTH; i++) {
int N1 = VersionNumbers__floor(V1.version_numbers[i]);
int N2 = VersionNumbers__floor(V2.version_numbers[i]);
if (N1 > N2) return FALSE;
if (N1 < N2) return TRUE;
}
linked_list_item *I1 = (V1.prerelease_segments)?(LinkedLists__first(V1.prerelease_segments)):NULL;
linked_list_item *I2 = (V2.prerelease_segments)?(LinkedLists__first(V2.prerelease_segments)):NULL;
if ((I1 == NULL) && (I2)) return FALSE;
if ((I1) && (I2 == NULL)) return TRUE;
do {
text_stream *T1 = (text_stream *) LinkedLists__content(I1);
text_stream *T2 = (text_stream *) LinkedLists__content(I2);
int N1 = VersionNumbers__strict_atoi(T1);
int N2 = VersionNumbers__strict_atoi(T2);
if ((N1 >= 0) && (N2 >= 0)) {
if (N1 < N2) return TRUE;
if (N1 > N2) return FALSE;
} else {
if (Str__ne(T1, T2)) {
int c = Str__cmp(T1, T2);
if (c < 0) return TRUE;
if (c > 0) return FALSE;
}
}
I1 = LinkedLists__next(I1);
I2 = LinkedLists__next(I2);
} while ((I1) && (I2));
if ((I1 == NULL) && (I2)) return TRUE;
if ((I1) && (I2 == NULL)) return FALSE;
return TRUE;
}
#line 256 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__floor(int N) {
if (N < 0) return 0;
return N;
}
#line 266 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__strict_atoi(text_stream *T) {
LOOP_THROUGH_TEXT(pos, T)
if (Characters__isdigit(Str__get(pos)) == FALSE)
return -1;
wchar_t c = Str__get_first_char(T);
if ((c == '0') && (Str__len(T) > 1)) return -1;
return Str__atoi(T, 0);
}
#line 282 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__eq(semantic_version_number V1, semantic_version_number V2) {
if ((VersionNumbers__le(V1, V2)) && (VersionNumbers__le(V2, V1)))
return TRUE;
return FALSE;
}
int VersionNumbers__ne(semantic_version_number V1, semantic_version_number V2) {
return (VersionNumbers__eq(V1, V2))?FALSE:TRUE;
}
int VersionNumbers__gt(semantic_version_number V1, semantic_version_number V2) {
return (VersionNumbers__le(V1, V2))?FALSE:TRUE;
}
int VersionNumbers__ge(semantic_version_number V1, semantic_version_number V2) {
return VersionNumbers__le(V2, V1);
}
int VersionNumbers__lt(semantic_version_number V1, semantic_version_number V2) {
return (VersionNumbers__ge(V1, V2))?FALSE:TRUE;
}
#line 307 "inweb/foundation-module/Chapter 7/Version Numbers.w"
int VersionNumbers__cmp(semantic_version_number V1, semantic_version_number V2) {
if (VersionNumbers__eq(V1, V2)) return 0;
if (VersionNumbers__gt(V1, V2)) return 1;
return -1;
}
#line 28 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
#line 34 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
#line 39 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
void VersionNumberRanges__write_range(OUTPUT_STREAM, semver_range *R) {
if (R == NULL) internal_error("no range");
switch(R->lower.end_type) {
case CLOSED_RANGE_END: WRITE("[%v,", &(R->lower.end_value)); break;
case OPEN_RANGE_END: WRITE("(%v,", &(R->lower.end_value)); break;
case INFINITE_RANGE_END: WRITE("(-infty,"); break;
case EMPTY_RANGE_END: WRITE("empty"); break;
}
switch(R->upper.end_type) {
case CLOSED_RANGE_END: WRITE("%v]", &(R->upper.end_value)); break;
case OPEN_RANGE_END: WRITE("%v)", &(R->upper.end_value)); break;
case INFINITE_RANGE_END: WRITE("infty)"); break;
}
}
#line 58 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
semver_range *VersionNumberRanges__any_range(void) {
semver_range *R = CREATE(semver_range);
R->lower.end_type = INFINITE_RANGE_END;
R->lower.end_value = VersionNumbers__null();
R->upper.end_type = INFINITE_RANGE_END;
R->upper.end_value = VersionNumbers__null();
return R;
}
int VersionNumberRanges__is_any_range(semver_range *R) {
if (R == NULL) return TRUE;
if ((R->lower.end_type == INFINITE_RANGE_END) && (R->upper.end_type == INFINITE_RANGE_END))
return TRUE;
return FALSE;
}
#line 87 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
semver_range *VersionNumberRanges__compatibility_range(semantic_version_number V) {
semver_range *R = VersionNumberRanges__any_range();
if (VersionNumbers__is_null(V) == FALSE) {
R->lower.end_type = CLOSED_RANGE_END;
R->lower.end_value = V;
R->upper.end_type = OPEN_RANGE_END;
semantic_version_number W = VersionNumbers__null();
W.version_numbers[0] = V.version_numbers[0] + 1;
W.prerelease_segments = NEW_LINKED_LIST(text_stream);
ADD_TO_LINKED_LIST(TL_IS_66, text_stream, W.prerelease_segments);
R->upper.end_value = W;
}
return R;
}
#line 106 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
semver_range *VersionNumberRanges__at_least_range(semantic_version_number V) {
semver_range *R = VersionNumberRanges__any_range();
R->lower.end_type = CLOSED_RANGE_END;
R->lower.end_value = V;
return R;
}
semver_range *VersionNumberRanges__at_most_range(semantic_version_number V) {
semver_range *R = VersionNumberRanges__any_range();
R->upper.end_type = CLOSED_RANGE_END;
R->upper.end_value = V;
return R;
}
#line 123 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__version_ge_end(semantic_version_number V, range_end E) {
switch (E.end_type) {
case CLOSED_RANGE_END:
if (VersionNumbers__is_null(V)) return FALSE;
if (VersionNumbers__ge(V, E.end_value)) return TRUE;
break;
case OPEN_RANGE_END:
if (VersionNumbers__is_null(V)) return FALSE;
if (VersionNumbers__gt(V, E.end_value)) return TRUE;
break;
case INFINITE_RANGE_END: return TRUE;
case EMPTY_RANGE_END: return FALSE;
}
return FALSE;
}
int VersionNumberRanges__version_le_end(semantic_version_number V, range_end E) {
switch (E.end_type) {
case CLOSED_RANGE_END:
if (VersionNumbers__is_null(V)) return FALSE;
if (VersionNumbers__le(V, E.end_value)) return TRUE;
break;
case OPEN_RANGE_END:
if (VersionNumbers__is_null(V)) return FALSE;
if (VersionNumbers__lt(V, E.end_value)) return TRUE;
break;
case INFINITE_RANGE_END: return TRUE;
case EMPTY_RANGE_END: return FALSE;
}
return FALSE;
}
#line 158 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__in_range(semantic_version_number V, semver_range *R) {
if (R == NULL) return TRUE;
if ((VersionNumberRanges__version_ge_end(V, R->lower)) &&
(VersionNumberRanges__version_le_end(V, R->upper))) return TRUE;
return FALSE;
}
#line 178 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__stricter(range_end E1, range_end E2, int lower) {
if ((E1.end_type == EMPTY_RANGE_END) && (E2.end_type == EMPTY_RANGE_END)) return 0;
if (E1.end_type == EMPTY_RANGE_END) return 1;
if (E2.end_type == EMPTY_RANGE_END) return -1;
if ((E1.end_type == INFINITE_RANGE_END) && (E2.end_type == INFINITE_RANGE_END)) return 0;
if (E1.end_type == INFINITE_RANGE_END) return -1;
if (E2.end_type == INFINITE_RANGE_END) return 1;
int c = VersionNumbers__cmp(E1.end_value, E2.end_value);
if (c != 0) {
if (lower) return c; else return -c;
}
if (E1.end_type == E2.end_type) return 0;
if (E1.end_type == CLOSED_RANGE_END) return -1;
return 1;
}
#line 202 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
int VersionNumberRanges__intersect_range(semver_range *R1, semver_range *R2) {
int lc = VersionNumberRanges__stricter(R1->lower, R2->lower, TRUE);
int uc = VersionNumberRanges__stricter(R1->upper, R2->upper, FALSE);
if ((lc >= 0) && (uc >= 0)) return FALSE;
if (lc < 0) R1->lower = R2->lower;
if (uc < 0) R1->upper = R2->upper;
if (R1->lower.end_type == EMPTY_RANGE_END) R1->upper.end_type = EMPTY_RANGE_END;
else if (R1->upper.end_type == EMPTY_RANGE_END) R1->lower.end_type = EMPTY_RANGE_END;
else if ((R1->lower.end_type != INFINITE_RANGE_END) && (R1->upper.end_type != INFINITE_RANGE_END)) {
int c = VersionNumbers__cmp(R1->lower.end_value, R1->upper.end_value);
if ((c > 0) ||
((c == 0) && ((R1->lower.end_type == OPEN_RANGE_END) ||
(R1->upper.end_type == OPEN_RANGE_END)))) {
R1->lower.end_type = EMPTY_RANGE_END; R1->upper.end_type = EMPTY_RANGE_END;
}
}
return TRUE;
}
#line 46 "inweb/foundation-module/Chapter 8/Web Structure.w"
#line 64 "inweb/foundation-module/Chapter 8/Web Structure.w"
#line 84 "inweb/foundation-module/Chapter 8/Web Structure.w"
#line 92 "inweb/foundation-module/Chapter 8/Web Structure.w"
web_md *WebMetadata__get_without_modules(pathname *P, filename *alt_F) {
return WebMetadata__get(P, alt_F, V2_SYNTAX, NULL, FALSE, FALSE, NULL);
}
web_md *WebMetadata__get(pathname *P, filename *alt_F, int syntax_version,
module_search *I, int verbosely, int including_modules, pathname *path_to_inweb) {
if ((including_modules) && (I == NULL)) I = WebModules__make_search_path(NULL);
web_md *Wm = CREATE(web_md);
{
#line 110 "inweb/foundation-module/Chapter 8/Web Structure.w"
Wm->bibliographic_data = NEW_LINKED_LIST(web_bibliographic_datum);
Bibliographic__initialise_data(Wm);
}
#line 100 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 114 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (P) {
Wm->path_to_web = P;
Wm->single_file = NULL;
Wm->contents_filename = WebMetadata__contents_filename(P);
} else {
Wm->path_to_web = Filenames__up(alt_F);
Wm->single_file = alt_F;
Wm->contents_filename = NULL;
}
Wm->version_number = VersionNumbers__null();
Wm->default_syntax = syntax_version;
Wm->chaptered = FALSE;
Wm->sections_md = NEW_LINKED_LIST(sections_md);
Wm->chapters_md = NEW_LINKED_LIST(chapter_md);
Wm->tangle_target_names = NEW_LINKED_LIST(text_stream);
Wm->main_language_name = Str__new();
Wm->header_filenames = NEW_LINKED_LIST(filename);
Wm->as_module = WebModules__create_main_module(Wm);
}
#line 101 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
WebMetadata__read_contents_page(Wm, Wm->as_module, I, verbosely,
including_modules, NULL, path_to_inweb);
{
#line 134 "inweb/foundation-module/Chapter 8/Web Structure.w"
Bibliographic__check_required_data(Wm);
BuildFiles__set_bibliographic_data_for(Wm);
BuildFiles__deduce_semver(Wm);
}
#line 104 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 141 "inweb/foundation-module/Chapter 8/Web Structure.w"
int sequential = FALSE; /* are we numbering sections sequentially? */
if (Str__eq(Bibliographic__get_datum(Wm, TL_IS_67), TL_IS_68))
sequential = TRUE;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) {
int section_counter = 1;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) {
if (Str__len(Sm->sect_range) == 0)
{
#line 156 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (sequential) {
WRITE_TO(Sm->sect_range, "%S/", Cm->ch_range);
WRITE_TO(Sm->sect_range, "s%d", section_counter);
} else {
text_stream *from = Sm->sect_title;
int letters_from_each_word = 5;
do {
Str__clear(Sm->sect_range);
WRITE_TO(Sm->sect_range, "%S/", Cm->ch_range);
{
#line 176 "inweb/foundation-module/Chapter 8/Web Structure.w"
int sn = 0, sw = Str__len(Sm->sect_range);
if (Platform__is_folder_separator(Str__get_at(from, sn))) sn++;
int letters_from_current_word = 0;
while ((Str__get_at(from, sn)) && (Str__get_at(from, sn) != '.')) {
if (Str__get_at(from, sn) == ' ') letters_from_current_word = 0;
else {
if (letters_from_current_word < letters_from_each_word) {
if (Str__get_at(from, sn) != '-') {
wchar_t l = Characters__tolower(Str__get_at(from, sn));
if ((letters_from_current_word == 0) ||
((l != 'a') && (l != 'e') && (l != 'i') &&
(l != 'o') && (l != 'u'))) {
Str__put_at(Sm->sect_range, sw++, l);
Str__put_at(Sm->sect_range, sw, 0);
letters_from_current_word++;
}
}
}
}
sn++;
}
}
#line 165 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
if (--letters_from_each_word == 0) break;
} while (Str__len(Sm->sect_range) > 5);
{
#line 201 "inweb/foundation-module/Chapter 8/Web Structure.w"
TEMPORARY_TEXT(original_range)
Str__copy(original_range, Sm->sect_range);
int disnum = 0, collision = FALSE;
do {
if (disnum++ > 0) {
int ldn = 4;
if (disnum >= 1000) ldn = 3;
else if (disnum >= 100) ldn = 2;
else if (disnum >= 10) ldn = 1;
else ldn = 0;
Str__clear(Sm->sect_range);
WRITE_TO(Sm->sect_range, "%S", original_range);
Str__truncate(Sm->sect_range, Str__len(Sm->sect_range) - ldn);
WRITE_TO(Sm->sect_range, "%d", disnum);
}
collision = FALSE;
chapter_md *Cm2;
section_md *Sm2;
LOOP_OVER_LINKED_LIST(Cm2, chapter_md, Wm->chapters_md)
LOOP_OVER_LINKED_LIST(Sm2, section_md, Cm2->sections_md)
if ((Sm2 != Sm) && (Str__eq(Sm2->sect_range, Sm->sect_range))) {
collision = TRUE; break;
}
} while (collision);
DISCARD_TEXT(original_range)
}
#line 169 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
}
#line 150 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
section_counter++;
}
}
}
#line 105 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
return Wm;
}
#line 266 "inweb/foundation-module/Chapter 8/Web Structure.w"
void WebMetadata__read_contents_page(web_md *Wm, module *of_module,
module_search *import_path, int verbosely,
int including_modules, pathname *path, pathname *X) {
reader_state RS;
{
#line 286 "inweb/foundation-module/Chapter 8/Web Structure.w"
RS.Wm = Wm;
RS.reading_from = of_module;
RS.in_biblio = TRUE;
RS.in_purpose = FALSE;
RS.chapter_being_scanned = NULL;
RS.chapter_dir_name = Str__new();
RS.titling_line_to_insert = Str__new();
RS.scan_verbosely = verbosely;
RS.including_modules = including_modules;
RS.path_to = path;
RS.import_from = import_path;
RS.halted = FALSE;
RS.path_to_inweb = X;
if (path == NULL) {
path = Wm->path_to_web;
RS.main_web_not_module = TRUE;
} else {
RS.main_web_not_module = FALSE;
}
if (Wm->single_file) {
RS.contents_filename = Wm->single_file;
RS.halt_at_at = TRUE;
} else {
RS.contents_filename = WebMetadata__contents_filename(path);
RS.halt_at_at = FALSE;
}
RS.section_count = 0;
RS.last_section = NULL;
}
#line 271 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
int cl = TextFiles__read(RS.contents_filename, FALSE, "can't open contents file",
TRUE, WebMetadata__read_contents_line, NULL, &RS);
if (verbosely) {
if (Wm->single_file) {
PRINT("Read %d lines of contents part at top of file\n", cl);
} else {
PRINT("Read contents section (%d lines)\n", cl);
}
}
if (RS.section_count == 1) RS.last_section->is_a_singleton = TRUE;
}
#line 322 "inweb/foundation-module/Chapter 8/Web Structure.w"
void WebMetadata__read_contents_line(text_stream *line, text_file_position *tfp, void *X) {
reader_state *RS = (reader_state *) X;
if (RS->halted) return;
int begins_with_white_space = FALSE;
if (Characters__is_whitespace(Str__get_first_char(line)))
begins_with_white_space = TRUE;
Str__trim_white_space(line);
{
#line 346 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (Str__eq(line, TL_IS_69))
RS->Wm->default_syntax = V1_SYNTAX;
else if (Str__eq(line, TL_IS_70))
RS->Wm->default_syntax = V2_SYNTAX;
}
#line 331 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
int syntax = RS->Wm->default_syntax;
filename *filename_of_single_file_web = NULL;
if ((RS->halt_at_at) && (Str__get_at(line, 0) == '@'))
{
#line 357 "inweb/foundation-module/Chapter 8/Web Structure.w"
RS->halted = TRUE;
text_stream *new_chapter_range = TL_IS_71;
text_stream *language_name = NULL;
line = TL_IS_72;
{
#line 560 "inweb/foundation-module/Chapter 8/Web Structure.w"
chapter_md *Cm = CREATE(chapter_md);
Cm->ch_range = Str__duplicate(new_chapter_range);
if (line == NULL) PRINT("Nullity!\n");
Cm->ch_title = Str__duplicate(line);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, Cm->ch_title, L"(%c*?): *(%c*)")) {
Cm->ch_basic_title = Str__duplicate(mr.exp[0]);
Cm->ch_decorated_title = Str__duplicate(mr.exp[1]);
} else {
Cm->ch_basic_title = Str__duplicate(Cm->ch_title);
Cm->ch_decorated_title = Str__new();
}
Regexp__dispose_of(&mr);
Cm->rubric = Str__new();
Cm->ch_language_name = language_name;
Cm->imported = TRUE;
Cm->sections_md = NEW_LINKED_LIST(section_md);
if (RS->main_web_not_module) Cm->imported = FALSE;
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->Wm->chapters_md);
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->reading_from->chapters_md);
RS->chapter_being_scanned = Cm;
}
#line 361 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
line = TL_IS_73;
filename_of_single_file_web = tfp->text_file_filename;
{
#line 588 "inweb/foundation-module/Chapter 8/Web Structure.w"
section_md *Sm = CREATE(section_md);
{
#line 597 "inweb/foundation-module/Chapter 8/Web Structure.w"
Sm->source_file_for_section = filename_of_single_file_web;
Sm->using_syntax = syntax;
Sm->is_a_singleton = FALSE;
Sm->titling_line_to_insert = Str__duplicate(RS->titling_line_to_insert);
Sm->sect_range = Str__new();
Str__clear(RS->titling_line_to_insert);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+) %^\"(%c+)\" *")) {
Sm->sect_title = Str__duplicate(mr.exp[0]);
Sm->tag_name = Str__duplicate(mr.exp[1]);
} else {
Sm->sect_title = Str__duplicate(line);
Sm->tag_name = NULL;
}
Regexp__dispose_of(&mr);
Sm->owning_module = RS->reading_from;
}
#line 589 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 616 "inweb/foundation-module/Chapter 8/Web Structure.w"
chapter_md *Cm = RS->chapter_being_scanned;
RS->section_count++;
RS->last_section = Sm;
ADD_TO_LINKED_LIST(Sm, section_md, Cm->sections_md);
ADD_TO_LINKED_LIST(Sm, section_md, RS->Wm->sections_md);
ADD_TO_LINKED_LIST(Sm, section_md, RS->reading_from->sections_md);
}
#line 590 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 624 "inweb/foundation-module/Chapter 8/Web Structure.w"
Sm->sect_language_name = RS->chapter_being_scanned->ch_language_name; /* by default */
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c*%C) %(Independent (%c*) *%)")) {
text_stream *title_alone = mr.exp[0];
text_stream *language_name = mr.exp[1];
{
#line 635 "inweb/foundation-module/Chapter 8/Web Structure.w"
text_stream *p = language_name;
if (Str__len(p) == 0) p = Bibliographic__get_datum(RS->Wm, TL_IS_77);
Sm->sect_independent_language = Str__duplicate(p);
}
#line 629 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
Str__copy(Sm->sect_title, title_alone);
}
Regexp__dispose_of(&mr);
}
#line 591 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
if (Sm->source_file_for_section == NULL)
{
#line 645 "inweb/foundation-module/Chapter 8/Web Structure.w"
TEMPORARY_TEXT(leafname_to_use)
WRITE_TO(leafname_to_use, "%S.i6t", Sm->sect_title);
pathname *P = RS->path_to;
if (P == NULL) P = RS->Wm->path_to_web;
if (Str__len(RS->chapter_dir_name) > 0)
P = Pathnames__down(P, RS->chapter_dir_name);
Sm->source_file_for_section = Filenames__in(P, leafname_to_use);
if (TextFiles__exists(Sm->source_file_for_section) == FALSE) {
Str__clear(leafname_to_use);
WRITE_TO(leafname_to_use, "%S.w", Sm->sect_title);
Sm->source_file_for_section = Filenames__in(P, leafname_to_use);
}
DISCARD_TEXT(leafname_to_use)
}
#line 594 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 364 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
return;
}
#line 336 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 373 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (Str__len(line) == 0)
{
#line 381 "inweb/foundation-module/Chapter 8/Web Structure.w"
RS->in_biblio = FALSE;
}
#line 373 "inweb/foundation-module/Chapter 8/Web Structure.w"
else if (RS->in_biblio)
{
#line 387 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (RS->main_web_not_module) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+?): (%c+?) *")) {
TEMPORARY_TEXT(key)
Str__copy(key, mr.exp[0]);
TEMPORARY_TEXT(value)
Str__copy(value, mr.exp[1]);
{
#line 407 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (Bibliographic__datum_can_be_declared(RS->Wm, key)) {
if (Bibliographic__datum_on_or_off(RS->Wm, key)) {
if ((Str__ne_wide_string(value, L"On")) && (Str__ne_wide_string(value, L"Off"))) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "this setting must be 'On' or 'Off': %S", key);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err)
Str__clear(value);
WRITE_TO(value, "Off");
}
}
Bibliographic__set_datum(RS->Wm, key, value);
} else {
TEMPORARY_TEXT(err)
WRITE_TO(err, "no such bibliographic datum: %S", key);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err)
}
}
#line 394 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
DISCARD_TEXT(key)
DISCARD_TEXT(value)
} else {
TEMPORARY_TEXT(err)
WRITE_TO(err, "expected 'Setting: Value' but found '%S'", line);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err)
}
Regexp__dispose_of(&mr);
}
}
#line 374 "inweb/foundation-module/Chapter 8/Web Structure.w"
else
{
#line 430 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (begins_with_white_space == FALSE) {
if (Str__get_first_char(line) == '"') {
RS->in_purpose = TRUE; Str__delete_first_character(line);
}
if (RS->in_purpose == TRUE)
{
#line 443 "inweb/foundation-module/Chapter 8/Web Structure.w"
if ((Str__len(line) > 0) && (Str__get_last_char(line) == '"')) {
Str__truncate(line, Str__len(line)-1); RS->in_purpose = FALSE;
}
if (RS->chapter_being_scanned) {
text_stream *r = RS->chapter_being_scanned->rubric;
if (Str__len(r) > 0) WRITE_TO(r, " ");
WRITE_TO(r, "%S", line);
}
}
#line 434 "inweb/foundation-module/Chapter 8/Web Structure.w"
else
{
#line 455 "inweb/foundation-module/Chapter 8/Web Structure.w"
TEMPORARY_TEXT(new_chapter_range) /* e.g., S, P, 1, 2, 3, A, B, ... */
TEMPORARY_TEXT(pdf_leafname)
text_stream *language_name = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c*%C) %(Independent(%c*)%)")) {
text_stream *title_alone = mr.exp[0];
language_name = mr.exp[1];
{
#line 552 "inweb/foundation-module/Chapter 8/Web Structure.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, language_name, L" *"))
language_name = Bibliographic__get_datum(RS->Wm, TL_IS_76);
else if (Regexp__match(&mr, language_name, L" *(%c*?) *"))
language_name = mr.exp[0];
Regexp__dispose_of(&mr);
}
#line 463 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
Str__copy(line, title_alone);
}
int this_is_a_chapter = TRUE;
Str__clear(RS->chapter_dir_name);
if (Str__eq_wide_string(line, L"Sections")) {
WRITE_TO(new_chapter_range, "S");
WRITE_TO(RS->chapter_dir_name, "Sections");
WRITE_TO(pdf_leafname, "Sections.pdf");
RS->Wm->chaptered = FALSE;
Str__clear(RS->titling_line_to_insert);
} else if (Str__eq_wide_string(line, L"Preliminaries")) {
WRITE_TO(new_chapter_range, "P");
WRITE_TO(RS->chapter_dir_name, "Preliminaries");
Str__clear(RS->titling_line_to_insert);
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
WRITE_TO(pdf_leafname, "Preliminaries.pdf");
RS->Wm->chaptered = TRUE;
} else if (Str__eq_wide_string(line, L"Manual")) {
WRITE_TO(new_chapter_range, "M");
WRITE_TO(RS->chapter_dir_name, "Manual");
Str__clear(RS->titling_line_to_insert);
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
WRITE_TO(pdf_leafname, "Manual.pdf");
RS->Wm->chaptered = TRUE;
} else if (Regexp__match(&mr, line, L"Header: (%c+)")) {
pathname *P = RS->path_to;
if (P == NULL) P = RS->Wm->path_to_web;
P = Pathnames__down(P, TL_IS_74);
filename *HF = Filenames__in(P, mr.exp[0]);
ADD_TO_LINKED_LIST(HF, filename, RS->Wm->header_filenames);
this_is_a_chapter = FALSE;
} else if (Regexp__match(&mr, line, L"Import: (%c+)")) {
if (RS->halt_at_at)
Errors__in_text_file_S(TL_IS_75, tfp);
else if (RS->import_from) {
module *imported =
WebModules__find(RS->Wm, RS->import_from, mr.exp[0], RS->path_to_inweb);
if (imported == NULL) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "unable to find module: %S", line);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err)
} else {
if (RS->including_modules) {
int save_syntax = RS->Wm->default_syntax;
WebMetadata__read_contents_page(RS->Wm, imported, RS->import_from,
RS->scan_verbosely, RS->including_modules,
imported->module_location, RS->path_to_inweb);
RS->Wm->default_syntax = save_syntax;
}
}
}
this_is_a_chapter = FALSE;
} else if (Regexp__match(&mr, line, L"Chapter (%d+): %c+")) {
int n = Str__atoi(mr.exp[0], 0);
WRITE_TO(new_chapter_range, "%d", n);
WRITE_TO(RS->chapter_dir_name, "Chapter %d", n);
Str__clear(RS->titling_line_to_insert);
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
WRITE_TO(pdf_leafname, "Chapter-%d.pdf", n);
RS->Wm->chaptered = TRUE;
} else if (Regexp__match(&mr, line, L"Appendix (%c): %c+")) {
text_stream *letter = mr.exp[0];
Str__copy(new_chapter_range, letter);
WRITE_TO(RS->chapter_dir_name, "Appendix %S", letter);
Str__clear(RS->titling_line_to_insert);
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
WRITE_TO(pdf_leafname, "Appendix-%S.pdf", letter);
RS->Wm->chaptered = TRUE;
} else {
TEMPORARY_TEXT(err)
WRITE_TO(err, "segment not understood: %S", line);
Errors__in_text_file_S(err, tfp);
WRITE_TO(STDERR, "(Must be 'Chapter <number>: Title', "
"'Appendix <letter A to O>: Title',\n");
WRITE_TO(STDERR, "'Manual', 'Preliminaries' or 'Sections')\n");
DISCARD_TEXT(err)
}
if (this_is_a_chapter)
{
#line 560 "inweb/foundation-module/Chapter 8/Web Structure.w"
chapter_md *Cm = CREATE(chapter_md);
Cm->ch_range = Str__duplicate(new_chapter_range);
if (line == NULL) PRINT("Nullity!\n");
Cm->ch_title = Str__duplicate(line);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, Cm->ch_title, L"(%c*?): *(%c*)")) {
Cm->ch_basic_title = Str__duplicate(mr.exp[0]);
Cm->ch_decorated_title = Str__duplicate(mr.exp[1]);
} else {
Cm->ch_basic_title = Str__duplicate(Cm->ch_title);
Cm->ch_decorated_title = Str__new();
}
Regexp__dispose_of(&mr);
Cm->rubric = Str__new();
Cm->ch_language_name = language_name;
Cm->imported = TRUE;
Cm->sections_md = NEW_LINKED_LIST(section_md);
if (RS->main_web_not_module) Cm->imported = FALSE;
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->Wm->chapters_md);
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->reading_from->chapters_md);
RS->chapter_being_scanned = Cm;
}
#line 543 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
DISCARD_TEXT(new_chapter_range)
DISCARD_TEXT(pdf_leafname)
Regexp__dispose_of(&mr);
}
#line 435 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
} else
{
#line 588 "inweb/foundation-module/Chapter 8/Web Structure.w"
section_md *Sm = CREATE(section_md);
{
#line 597 "inweb/foundation-module/Chapter 8/Web Structure.w"
Sm->source_file_for_section = filename_of_single_file_web;
Sm->using_syntax = syntax;
Sm->is_a_singleton = FALSE;
Sm->titling_line_to_insert = Str__duplicate(RS->titling_line_to_insert);
Sm->sect_range = Str__new();
Str__clear(RS->titling_line_to_insert);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+) %^\"(%c+)\" *")) {
Sm->sect_title = Str__duplicate(mr.exp[0]);
Sm->tag_name = Str__duplicate(mr.exp[1]);
} else {
Sm->sect_title = Str__duplicate(line);
Sm->tag_name = NULL;
}
Regexp__dispose_of(&mr);
Sm->owning_module = RS->reading_from;
}
#line 589 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 616 "inweb/foundation-module/Chapter 8/Web Structure.w"
chapter_md *Cm = RS->chapter_being_scanned;
RS->section_count++;
RS->last_section = Sm;
ADD_TO_LINKED_LIST(Sm, section_md, Cm->sections_md);
ADD_TO_LINKED_LIST(Sm, section_md, RS->Wm->sections_md);
ADD_TO_LINKED_LIST(Sm, section_md, RS->reading_from->sections_md);
}
#line 590 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 624 "inweb/foundation-module/Chapter 8/Web Structure.w"
Sm->sect_language_name = RS->chapter_being_scanned->ch_language_name; /* by default */
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c*%C) %(Independent (%c*) *%)")) {
text_stream *title_alone = mr.exp[0];
text_stream *language_name = mr.exp[1];
{
#line 635 "inweb/foundation-module/Chapter 8/Web Structure.w"
text_stream *p = language_name;
if (Str__len(p) == 0) p = Bibliographic__get_datum(RS->Wm, TL_IS_77);
Sm->sect_independent_language = Str__duplicate(p);
}
#line 629 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
Str__copy(Sm->sect_title, title_alone);
}
Regexp__dispose_of(&mr);
}
#line 591 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
if (Sm->source_file_for_section == NULL)
{
#line 645 "inweb/foundation-module/Chapter 8/Web Structure.w"
TEMPORARY_TEXT(leafname_to_use)
WRITE_TO(leafname_to_use, "%S.i6t", Sm->sect_title);
pathname *P = RS->path_to;
if (P == NULL) P = RS->Wm->path_to_web;
if (Str__len(RS->chapter_dir_name) > 0)
P = Pathnames__down(P, RS->chapter_dir_name);
Sm->source_file_for_section = Filenames__in(P, leafname_to_use);
if (TextFiles__exists(Sm->source_file_for_section) == FALSE) {
Str__clear(leafname_to_use);
WRITE_TO(leafname_to_use, "%S.w", Sm->sect_title);
Sm->source_file_for_section = Filenames__in(P, leafname_to_use);
}
DISCARD_TEXT(leafname_to_use)
}
#line 594 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 436 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 375 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 338 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 662 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__directory_looks_like_a_web(pathname *P) {
return TextFiles__exists(WebMetadata__contents_filename(P));
}
filename *WebMetadata__contents_filename(pathname *P) {
return Filenames__in(P, TL_IS_78);
}
#line 673 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__chapter_count(web_md *Wm) {
int n = 0;
chapter_md *Cm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) n++;
return n;
}
int WebMetadata__section_count(web_md *Wm) {
int n = 0;
chapter_md *Cm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) {
section_md *Sm;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) n++;
}
return n;
}
#line 20 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
#line 29 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
int Bibliographic__datum_can_be_declared(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if (bd == NULL) return FALSE;
return bd->declaration_permitted;
}
int Bibliographic__datum_on_or_off(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if (bd == NULL) return FALSE;
return bd->on_or_off;
}
#line 45 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
void Bibliographic__initialise_data(web_md *Wm) {
web_bibliographic_datum *bd;
bd = Bibliographic__set_datum(Wm, TL_IS_79, NULL); bd->declaration_mandatory = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_80, NULL); bd->declaration_mandatory = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_81, TL_IS_82);
bd = Bibliographic__set_datum(Wm, TL_IS_83, TL_IS_84);
bd = Bibliographic__set_datum(Wm, TL_IS_85, NULL);
bd->alias = Bibliographic__set_datum(Wm, TL_IS_86, NULL); /* alias US to UK spelling */
Bibliographic__set_datum(Wm, TL_IS_87, NULL);
Bibliographic__set_datum(Wm, TL_IS_88, NULL);
Bibliographic__set_datum(Wm, TL_IS_89, NULL);
Bibliographic__set_datum(Wm, TL_IS_90, NULL);
Bibliographic__set_datum(Wm, TL_IS_91, NULL);
Bibliographic__set_datum(Wm, TL_IS_92, NULL);
Bibliographic__set_datum(Wm, TL_IS_93, TL_IS_94);
Bibliographic__set_datum(Wm, TL_IS_95, NULL);
Bibliographic__set_datum(Wm, TL_IS_96, NULL);
Bibliographic__set_datum(Wm, TL_IS_97, NULL);
bd = Bibliographic__set_datum(Wm, TL_IS_98, TL_IS_99); bd->on_or_off = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_100, TL_IS_101); bd->on_or_off = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_102, TL_IS_103); bd->on_or_off = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_104, TL_IS_105); bd->on_or_off = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_106, TL_IS_107);
bd = Bibliographic__set_datum(Wm, TL_IS_108, TL_IS_109);
bd = Bibliographic__set_datum(Wm, TL_IS_110, TL_IS_111);
bd = Bibliographic__set_datum(Wm, TL_IS_112, TL_IS_113);
bd = Bibliographic__set_datum(Wm, TL_IS_114, TL_IS_115);
bd = Bibliographic__set_datum(Wm, TL_IS_116, TL_IS_117);
bd = Bibliographic__set_datum(Wm, TL_IS_118, TL_IS_119);
bd = Bibliographic__set_datum(Wm, TL_IS_120, NULL);
bd = Bibliographic__set_datum(Wm, TL_IS_121, TL_IS_122);
}
#line 86 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
void Bibliographic__check_required_data(web_md *Wm) {
web_bibliographic_datum *bd;
LOOP_OVER_BIBLIOGRAPHIC_DATA(bd, Wm)
if ((bd->declaration_mandatory) &&
(Str__len(bd->value) == 0))
Errors__fatal_with_text(
"The web does not specify '%S: ...'", bd->key);
}
#line 99 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
text_stream *Bibliographic__get_datum(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if (bd) return bd->value;
return NULL;
}
int Bibliographic__data_exists(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if ((bd) && (Str__len(bd->value) > 0)) return TRUE;
return FALSE;
}
web_bibliographic_datum *Bibliographic__look_up_datum(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd;
LOOP_OVER_BIBLIOGRAPHIC_DATA(bd, Wm)
if (Str__eq(key, bd->key)) {
if (bd->alias) return bd->alias;
return bd;
}
return NULL;
}
#line 126 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
web_bibliographic_datum *Bibliographic__set_datum(web_md *Wm, text_stream *key, text_stream *val) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if (bd == NULL)
{
#line 135 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
bd = CREATE(web_bibliographic_datum);
bd->key = Str__duplicate(key);
bd->value = Str__duplicate(val);
bd->declaration_mandatory = FALSE;
bd->declaration_permitted = TRUE;
bd->on_or_off = FALSE;
bd->alias = NULL;
ADD_TO_LINKED_LIST(bd, web_bibliographic_datum, Wm->bibliographic_data);
}
#line 128 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
else Str__copy(bd->value, val);
if (Str__eq_wide_string(key, L"Title"))
{
#line 150 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
TEMPORARY_TEXT(recapped)
Str__copy(recapped, val);
LOOP_THROUGH_TEXT(P, recapped)
Str__put(P, Characters__toupper(Str__get(P)));
Bibliographic__set_datum(Wm, TL_IS_123, recapped);
DISCARD_TEXT(recapped)
}
#line 130 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
;
return bd;
}
#line 29 "inweb/foundation-module/Chapter 8/Web Modules.w"
#line 31 "inweb/foundation-module/Chapter 8/Web Modules.w"
module *WebModules__new(text_stream *name, pathname *at, int m) {
module *M = CREATE(module);
M->module_location = at;
M->module_name = Str__duplicate(name);
M->dependencies = NEW_LINKED_LIST(module);
M->origin_marker = m;
M->module_tag = TL_IS_124;
M->chapters_md = NEW_LINKED_LIST(chapter_md);
M->sections_md = NEW_LINKED_LIST(section_md);
return M;
}
#line 52 "inweb/foundation-module/Chapter 8/Web Modules.w"
module *WebModules__create_main_module(web_md *WS) {
return WebModules__new(TL_IS_125, WS->path_to_web, READING_WEB_MOM);
}
#line 63 "inweb/foundation-module/Chapter 8/Web Modules.w"
void WebModules__dependency(module *A, module *B) {
if ((A == NULL) || (B == NULL)) internal_error("no module");
ADD_TO_LINKED_LIST(B, module, A->dependencies);
}
#line 77 "inweb/foundation-module/Chapter 8/Web Modules.w"
#line 79 "inweb/foundation-module/Chapter 8/Web Modules.w"
module_search *WebModules__make_search_path(pathname *ext_path) {
module_search *ms = CREATE(module_search);
ms->path_to_search = ext_path;
return ms;
}
#line 89 "inweb/foundation-module/Chapter 8/Web Modules.w"
module *WebModules__find(web_md *WS, module_search *ms, text_stream *name, pathname *X) {
TEMPORARY_TEXT(T)
WRITE_TO(T, "%S-module", name);
pathname *tries[4];
tries[0] = WS?(WS->path_to_web):NULL;
tries[1] = tries[0]?(Pathnames__up(tries[0])):NULL;
tries[2] = X;
tries[3] = ms->path_to_search;
int N = 4;
for (int i=0; i<N; i++) {
pathname *P = Pathnames__from_text_relative(tries[i], T);
if ((P) && (WebModules__exists(P)))
{
#line 110 "inweb/foundation-module/Chapter 8/Web Modules.w"
pathname *Q = Pathnames__from_text(name);
module *M = WebModules__new(Pathnames__directory_name(Q), P, READING_WEB_MOM);
WebModules__dependency(WS->as_module, M);
return M;
}
#line 100 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
DISCARD_TEXT(T)
return NULL;
}
#line 119 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__exists(pathname *P) {
return WebMetadata__directory_looks_like_a_web(P);
}
#line 142 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__named_reference(module **return_M, section_md **return_Sm,
int *named_as_module, text_stream *title, module *from_M, text_stream *text,
int list, int sections_only) {
*return_M = NULL; *return_Sm = NULL; *named_as_module = FALSE;
module *M;
int finds = 0;
if (from_M == NULL) return 0;
match_results mr = Regexp__create_mr();
text_stream *seek = text;
text_stream *seek_module = NULL;
if (Regexp__match(&mr, text, L"(%C+?): *(%c+?) *")) {
seek_module = mr.exp[0]; seek = mr.exp[1];
} else {
seek_module = from_M->module_name; seek = text;
}
LOOP_OVER_LINKED_LIST(M, module, from_M->dependencies) {
if (Str__eq_insensitive(M->module_name, seek_module)) {
{
#line 178 "inweb/foundation-module/Chapter 8/Web Modules.w"
if (M == NULL) internal_error("no module");
if (Str__eq_insensitive(M->module_name, seek))
{
#line 195 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, M->sections_md);
*named_as_module = TRUE;
WRITE_TO(title, "the %S module", M->module_name);
}
if (list) WRITE_TO(STDERR, "(%d) Module '%S'\n", finds, M->module_name);
}
#line 180 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, M->chapters_md) {
if ((sections_only == FALSE) &&
((Str__eq_insensitive(Cm->ch_title, seek)) ||
(Str__eq_insensitive(Cm->ch_basic_title, seek)) ||
(Str__eq_insensitive(Cm->ch_decorated_title, seek))))
{
#line 204 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, Cm->sections_md);
WRITE_TO(title, "%S", Cm->ch_title);
}
if (list) WRITE_TO(STDERR, "(%d) Chapter '%S' of module '%S'\n",
finds, Cm->ch_title, M->module_name);
}
#line 188 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md)
if (Str__eq_insensitive(Sm->sect_title, seek))
{
#line 213 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = Sm;
WRITE_TO(title, "%S", Sm->sect_title);
}
if (list) WRITE_TO(STDERR, "(%d) Section '%S' in chapter '%S' of module '%S'\n",
finds, Sm->sect_title, Cm->ch_title, M->module_name);
}
#line 191 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
#line 159 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
Regexp__dispose_of(&mr);
seek = text;
for (int stage = 1; ((finds == 0) && (stage <= 2)); stage++) {
if (stage == 1) {
M = from_M;
{
#line 178 "inweb/foundation-module/Chapter 8/Web Modules.w"
if (M == NULL) internal_error("no module");
if (Str__eq_insensitive(M->module_name, seek))
{
#line 195 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, M->sections_md);
*named_as_module = TRUE;
WRITE_TO(title, "the %S module", M->module_name);
}
if (list) WRITE_TO(STDERR, "(%d) Module '%S'\n", finds, M->module_name);
}
#line 180 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, M->chapters_md) {
if ((sections_only == FALSE) &&
((Str__eq_insensitive(Cm->ch_title, seek)) ||
(Str__eq_insensitive(Cm->ch_basic_title, seek)) ||
(Str__eq_insensitive(Cm->ch_decorated_title, seek))))
{
#line 204 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, Cm->sections_md);
WRITE_TO(title, "%S", Cm->ch_title);
}
if (list) WRITE_TO(STDERR, "(%d) Chapter '%S' of module '%S'\n",
finds, Cm->ch_title, M->module_name);
}
#line 188 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md)
if (Str__eq_insensitive(Sm->sect_title, seek))
{
#line 213 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = Sm;
WRITE_TO(title, "%S", Sm->sect_title);
}
if (list) WRITE_TO(STDERR, "(%d) Section '%S' in chapter '%S' of module '%S'\n",
finds, Sm->sect_title, Cm->ch_title, M->module_name);
}
#line 191 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
#line 167 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
if (stage == 2) {
LOOP_OVER_LINKED_LIST(M, module, from_M->dependencies)
{
#line 178 "inweb/foundation-module/Chapter 8/Web Modules.w"
if (M == NULL) internal_error("no module");
if (Str__eq_insensitive(M->module_name, seek))
{
#line 195 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, M->sections_md);
*named_as_module = TRUE;
WRITE_TO(title, "the %S module", M->module_name);
}
if (list) WRITE_TO(STDERR, "(%d) Module '%S'\n", finds, M->module_name);
}
#line 180 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, M->chapters_md) {
if ((sections_only == FALSE) &&
((Str__eq_insensitive(Cm->ch_title, seek)) ||
(Str__eq_insensitive(Cm->ch_basic_title, seek)) ||
(Str__eq_insensitive(Cm->ch_decorated_title, seek))))
{
#line 204 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, Cm->sections_md);
WRITE_TO(title, "%S", Cm->ch_title);
}
if (list) WRITE_TO(STDERR, "(%d) Chapter '%S' of module '%S'\n",
finds, Cm->ch_title, M->module_name);
}
#line 188 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md)
if (Str__eq_insensitive(Sm->sect_title, seek))
{
#line 213 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = Sm;
WRITE_TO(title, "%S", Sm->sect_title);
}
if (list) WRITE_TO(STDERR, "(%d) Section '%S' in chapter '%S' of module '%S'\n",
finds, Sm->sect_title, Cm->ch_title, M->module_name);
}
#line 191 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
#line 171 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
return finds;
}
#line 10 "inweb/foundation-module/Chapter 8/Build Files.w"
filename *BuildFiles__build_file_for_web(web_md *WS) {
filename *F = Filenames__in(WS->path_to_web, TL_IS_126);
if (TextFiles__exists(F)) return F;
F = Filenames__in(NULL, TL_IS_127);
if (TextFiles__exists(F)) return F;
return NULL;
}
#line 26 "inweb/foundation-module/Chapter 8/Build Files.w"
#line 30 "inweb/foundation-module/Chapter 8/Build Files.w"
build_file_data BuildFiles__read(filename *F) {
build_file_data bfd;
bfd.prerelease_text = Str__new();
bfd.build_code = Str__new();
bfd.build_date = Str__new();
TextFiles__read(F, FALSE, "unable to read build file", TRUE,
&BuildFiles__build_file_helper, NULL, (void *) &bfd);
return bfd;
}
void BuildFiles__build_file_helper(text_stream *text, text_file_position *tfp, void *state) {
build_file_data *bfd = (build_file_data *) state;
if (Str__len(text) == 0) return;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, text, L"Build Date: *(%c*)")) {
bfd->build_date = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, text, L"Build Number: *(%c*)")) {
bfd->build_code = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, text, L"Prerelease: *(%c*)")) {
bfd->prerelease_text = Str__duplicate(mr.exp[0]);
} else {
Errors__in_text_file("can't parse build file line", tfp);
}
Regexp__dispose_of(&mr);
}
#line 59 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__write(build_file_data bfd, filename *F) {
text_stream vr_stream;
text_stream *OUT = &vr_stream;
if (Streams__open_to_file(OUT, F, UTF8_ENC) == FALSE)
Errors__fatal_with_file("can't write build file", F);
if (Str__len(bfd.prerelease_text) > 0)
WRITE("Prerelease: %S\n", bfd.prerelease_text);
WRITE("Build Date: %S\n", bfd.build_date);
if (Str__len(bfd.build_code) > 0)
WRITE("Build Number: %S\n", bfd.build_code);
Streams__close(OUT);
}
#line 77 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__set_bibliographic_data_for(web_md *WS) {
filename *F = BuildFiles__build_file_for_web(WS);
if (F) {
build_file_data bfd = BuildFiles__read(F);
if (Str__len(bfd.prerelease_text) > 0)
Bibliographic__set_datum(WS, TL_IS_128, bfd.prerelease_text);
if (Str__len(bfd.build_code) > 0)
Bibliographic__set_datum(WS, TL_IS_129, bfd.build_code);
if (Str__len(bfd.build_date) > 0)
Bibliographic__set_datum(WS, TL_IS_130, bfd.build_date);
}
}
#line 99 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__deduce_semver(web_md *WS) {
TEMPORARY_TEXT(combined)
text_stream *s = Bibliographic__get_datum(WS, TL_IS_131);
if (Str__len(s) > 0) WRITE_TO(combined, "%S", s);
else {
text_stream *v = Bibliographic__get_datum(WS, TL_IS_132);
if (Str__len(v) > 0) WRITE_TO(combined, "%S", v);
text_stream *p = Bibliographic__get_datum(WS, TL_IS_133);
if (Str__len(p) > 0) WRITE_TO(combined, "-%S", p);
text_stream *b = Bibliographic__get_datum(WS, TL_IS_134);
if (Str__len(b) > 0) WRITE_TO(combined, "+%S", b);
}
if (Str__len(combined) > 0) {
WS->version_number = VersionNumbers__from_text(combined);
if (VersionNumbers__is_null(WS->version_number)) {
Errors__fatal_with_text(
"Combined version '%S' does not comply with the semver standard",
combined);
} else {
Bibliographic__set_datum(WS, TL_IS_135, combined);
}
}
DISCARD_TEXT(combined)
}
#line 129 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__advance_for_web(web_md *WS) {
filename *F = BuildFiles__build_file_for_web(WS);
if (F) BuildFiles__advance(F);
else Errors__fatal("web has no build file");
}
void BuildFiles__advance(filename *F) {
build_file_data bfd = BuildFiles__read(F);
if (BuildFiles__dated_today(bfd.build_date) == FALSE) {
BuildFiles__increment(bfd.build_code);
BuildFiles__write(bfd, F);
}
}
#line 148 "inweb/foundation-module/Chapter 8/Build Files.w"
int BuildFiles__dated_today(text_stream *dateline) {
char *monthname[12] = { "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" };
TEMPORARY_TEXT(today)
WRITE_TO(today, "%d %s %d",
the_present->tm_mday, monthname[the_present->tm_mon], the_present->tm_year+1900);
int rv = TRUE;
if (Str__ne(dateline, today)) {
rv = FALSE;
Str__clear(dateline);
Str__copy(dateline, today);
}
DISCARD_TEXT(today)
return rv;
}
#line 174 "inweb/foundation-module/Chapter 8/Build Files.w"
void BuildFiles__increment(text_stream *T) {
if (Str__len(T) != 4) Errors__with_text("build code malformed: %S", T);
else {
int N = Str__get_at(T, 0) - '0';
int L = Str__get_at(T, 1);
int M1 = Str__get_at(T, 2) - '0';
int M2 = Str__get_at(T, 3) - '0';
if ((N < 0) || (N > 9) || (L < 'A') || (L > 'Z') ||
(M1 < 0) || (M1 > 9) || (M2 < 0) || (M2 > 9)) {
Errors__with_text("build code malformed: %S", T);
} else {
M2++;
if (M2 == 10) { M2 = 0; M1++; }
if (M1 == 10) { M1 = 0; M2 = 1; L++; }
if ((L == 'I') || (L == 'O')) L++;
if (L > 'Z') { L = 'A'; N++; }
if (N == 10) Errors__with_text("build code overflowed: %S", T);
else {
Str__clear(T);
WRITE_TO(T, "%d%c%d%d", N, L, M1, M2);
PRINT("Build code advanced to %S\n", T);
}
}
}
}
#line 29 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
#line 31 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
simple_tangle_docket SimpleTangler__new_docket(
void (*A)(struct text_stream *, struct simple_tangle_docket *),
void (*B)(struct text_stream *, struct text_stream *,
struct text_stream *, struct simple_tangle_docket *),
void (*C)(struct text_stream *, struct simple_tangle_docket *),
void (*D)(char *, struct text_stream *),
pathname *web_path, void *initial_state) {
simple_tangle_docket docket;
docket.raw_callback = A;
docket.command_callback = B;
docket.bplus_callback = C;
docket.error_callback = D;
docket.state = initial_state;
docket.web_path = web_path;
return docket;
}
#line 53 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_text(simple_tangle_docket *docket, text_stream *text) {
SimpleTangler__tangle_L1(docket, text, NULL, NULL, FALSE);
}
void SimpleTangler__tangle_file(simple_tangle_docket *docket, filename *F) {
SimpleTangler__tangle_L1(docket, NULL, F, NULL, FALSE);
}
void SimpleTangler__tangle_section(simple_tangle_docket *docket, text_stream *leafname) {
SimpleTangler__tangle_L1(docket, NULL, NULL, leafname, FALSE);
}
void SimpleTangler__tangle_web(simple_tangle_docket *docket) {
SimpleTangler__tangle_L1(docket, NULL, NULL, NULL, TRUE);
}
#line 70 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_L1(simple_tangle_docket *docket, text_stream *text,
filename *F, text_stream *leafname, int whole_web) {
TEMPORARY_TEXT(T)
SimpleTangler__tangle_L2(T, text, F, leafname, docket, whole_web);
(*(docket->raw_callback))(T, docket);
DISCARD_TEXT(T)
}
#line 81 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_L2(OUTPUT_STREAM, text_stream *text, filename *F,
text_stream *leafname, simple_tangle_docket *docket, int whole_web) {
if (whole_web) {
web_md *Wm = WebMetadata__get(docket->web_path, NULL, V2_SYNTAX, NULL, FALSE, TRUE, NULL);
chapter_md *Cm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) {
section_md *Sm;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) {
filename *SF = Sm->source_file_for_section;
SimpleTangler__tangle_L3(OUT, text, Sm->sect_title, docket, SF);
}
}
} else {
SimpleTangler__tangle_L3(OUT, text, leafname, docket, F);
}
}
#line 102 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
void SimpleTangler__tangle_L3(OUTPUT_STREAM, text_stream *text,
text_stream *leafname, simple_tangle_docket *docket, filename *F) {
int comment = FALSE;
FILE *Input_File = NULL;
if ((Str__len(leafname) > 0) || (F)) {
{
#line 118 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (F) {
Input_File = Filenames__fopen(F, "r");
} else if (Str__len(leafname) > 0) {
pathname *P = Pathnames__down(docket->web_path, TL_IS_136);
Input_File = Filenames__fopen(Filenames__in(P, leafname), "r");
}
if (Input_File == NULL)
(*(docket->error_callback))("unable to open the file '%S'", leafname);
}
#line 107 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
comment = TRUE;
}
{
#line 128 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
TEMPORARY_TEXT(command)
TEMPORARY_TEXT(argument)
int skip_part = FALSE, extract = FALSE;
int col = 1, cr, sfp = 0;
do {
Str__clear(command);
Str__clear(argument);
{
#line 156 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (Input_File) cr = fgetc(Input_File);
else if (text) {
cr = Str__get_at(text, sfp); if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 135 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
NewCharacter: if (cr == EOF) break;
if (((cr == '@') || (cr == '=')) && (col == 1)) {
int inweb_syntax = -1;
if (cr == '=')
{
#line 214 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
TEMPORARY_TEXT(equals_cmd)
while (TRUE) {
{
#line 156 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (Input_File) cr = fgetc(Input_File);
else if (text) {
cr = Str__get_at(text, sfp); if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 216 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if ((cr == 10) || (cr == 13)) break;
PUT_TO(equals_cmd, cr);
}
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, equals_cmd, L" %(text%c*%) *")) {
inweb_syntax = INWEB_EXTRACT_SYNTAX;
} else if (Regexp__match(&mr, equals_cmd, L" %(figure%c*%) *")) {
inweb_syntax = INWEB_FIGURE_SYNTAX;
} else if (Regexp__match(&mr, equals_cmd, L" %(%c*%) *")) {
(*(docket->error_callback))(
"unsupported '= (...)' marker at column 0", NULL);
} else {
inweb_syntax = INWEB_EQUALS_SYNTAX;
}
Regexp__dispose_of(&mr);
DISCARD_TEXT(equals_cmd)
}
#line 139 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
else
{
#line 174 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
TEMPORARY_TEXT(at_cmd)
int committed = FALSE, unacceptable_character = FALSE;
while (TRUE) {
{
#line 156 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (Input_File) cr = fgetc(Input_File);
else if (text) {
cr = Str__get_at(text, sfp); if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 177 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if ((committed == FALSE) && ((cr == 10) || (cr == 13) || (cr == ' '))) {
if (Str__eq_wide_string(at_cmd, L"p"))
inweb_syntax = INWEB_PARAGRAPH_SYNTAX;
else if (Str__eq_wide_string(at_cmd, L"h"))
inweb_syntax = INWEB_PARAGRAPH_SYNTAX;
else if (Str__eq_wide_string(at_cmd, L"c"))
inweb_syntax = INWEB_CODE_SYNTAX;
else if (Str__get_first_char(at_cmd) == '-')
inweb_syntax = INWEB_DASH_SYNTAX;
else if (Str__begins_with_wide_string(at_cmd, L"Purpose:"))
inweb_syntax = INWEB_PURPOSE_SYNTAX;
committed = TRUE;
if (inweb_syntax == -1) {
if (unacceptable_character == FALSE) {
PUT_TO(OUT, '@');
WRITE_TO(OUT, "%S", at_cmd);
PUT_TO(OUT, cr);
break;
} else {
LOG("heading begins: <%S>\n", at_cmd);
(*(docket->error_callback))(
"unknown '@...' marker at column 0: '%S'", at_cmd);
}
}
}
if (!(((cr >= 'A') && (cr <= 'Z')) || ((cr >= 'a') && (cr <= 'z'))
|| ((cr >= '0') && (cr <= '9'))
|| (cr == '-') || (cr == '>') || (cr == ':') || (cr == '_')))
unacceptable_character = TRUE;
if ((cr == 10) || (cr == 13)) break;
PUT_TO(at_cmd, cr);
}
Str__copy(command, at_cmd);
DISCARD_TEXT(at_cmd)
}
#line 140 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
{
#line 235 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
switch (inweb_syntax) {
case INWEB_PARAGRAPH_SYNTAX: {
TEMPORARY_TEXT(heading_name)
Str__copy_tail(heading_name, command, 2);
int c;
while (((c = Str__get_last_char(heading_name)) != 0) &&
((c == ' ') || (c == '\t') || (c == '.')))
Str__delete_last_character(heading_name);
if (Str__len(heading_name) == 0)
(*(docket->error_callback))("Empty heading name", NULL);
DISCARD_TEXT(heading_name)
extract = FALSE;
comment = TRUE; skip_part = FALSE;
break;
}
case INWEB_CODE_SYNTAX:
extract = FALSE;
if (skip_part == FALSE) comment = FALSE;
break;
case INWEB_EQUALS_SYNTAX:
if (extract) {
comment = TRUE; extract = FALSE;
} else {
if (skip_part == FALSE) comment = FALSE;
}
break;
case INWEB_EXTRACT_SYNTAX:
comment = TRUE; extract = TRUE;
break;
case INWEB_DASH_SYNTAX: break;
case INWEB_PURPOSE_SYNTAX: break;
case INWEB_FIGURE_SYNTAX: break;
}
}
#line 141 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
continue;
}
if (comment == FALSE)
{
#line 270 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (cr == '{') {
{
#line 156 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (Input_File) cr = fgetc(Input_File);
else if (text) {
cr = Str__get_at(text, sfp); if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 271 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if ((cr == '-') && (docket->command_callback)) {
{
#line 299 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
Str__clear(command);
Str__clear(argument);
int com_mode = TRUE;
while (TRUE) {
{
#line 156 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (Input_File) cr = fgetc(Input_File);
else if (text) {
cr = Str__get_at(text, sfp); if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 303 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if ((cr == '}') || (cr == EOF)) break;
if ((cr == ':') && (com_mode)) { com_mode = FALSE; continue; }
if (com_mode) PUT_TO(command, cr);
else PUT_TO(argument, cr);
}
}
#line 273 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if (Str__get_first_char(command) == '!') continue;
(*(docket->command_callback))(OUT, command, argument, docket);
continue;
} else { /* otherwise the open brace was a literal */
PUT_TO(OUT, '{');
goto NewCharacter;
}
}
if ((cr == '(') && (docket->bplus_callback)) {
{
#line 156 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (Input_File) cr = fgetc(Input_File);
else if (text) {
cr = Str__get_at(text, sfp); if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 283 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if (cr == '+') {
{
#line 314 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
TEMPORARY_TEXT(material)
while (TRUE) {
{
#line 156 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
if (Input_File) cr = fgetc(Input_File);
else if (text) {
cr = Str__get_at(text, sfp); if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 316 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if (cr == EOF) break;
if ((cr == ')') && (Str__get_last_char(material) == '+')) {
Str__delete_last_character(material); break; }
PUT_TO(material, cr);
}
(*(docket->bplus_callback))(material, docket);
DISCARD_TEXT(material)
}
#line 285 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
continue;
} else { /* otherwise the open bracket was a literal */
PUT_TO(OUT, '(');
goto NewCharacter;
}
}
PUT_TO(OUT, cr);
}
#line 144 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
} while (cr != EOF);
DISCARD_TEXT(command)
DISCARD_TEXT(argument)
}
#line 110 "inweb/foundation-module/Chapter 8/Simple Tangler.w"
;
if (Input_File) fclose(Input_File);
}
#line 101 "inweb/Chapter 1/Basics.w"
DECLARE_CLASS_ALLOCATED_IN_ARRAYS(source_line, 1000)
DECLARE_CLASS(asset_rule)
DECLARE_CLASS(breadcrumb_request)
DECLARE_CLASS(chapter)
DECLARE_CLASS(colony)
DECLARE_CLASS(colony_member)
DECLARE_CLASS(colour_scheme)
DECLARE_CLASS(colouring_language_block)
DECLARE_CLASS(colouring_rule)
DECLARE_CLASS(defined_constant)
DECLARE_CLASS(enumeration_set)
DECLARE_CLASS(footnote)
DECLARE_CLASS(hash_table_entry_usage)
DECLARE_CLASS(hash_table_entry)
DECLARE_CLASS(language_function)
DECLARE_CLASS(language_type)
DECLARE_CLASS(macro_usage)
DECLARE_CLASS(makefile_specifics)
DECLARE_CLASS(nonterminal_variable)
DECLARE_CLASS(para_macro)
DECLARE_CLASS(paragraph_tagging)
DECLARE_CLASS(paragraph)
DECLARE_CLASS(preform_nonterminal)
DECLARE_CLASS(programming_language)
DECLARE_CLASS(reserved_word)
DECLARE_CLASS(section)
DECLARE_CLASS(structure_element)
DECLARE_CLASS(tangle_target)
DECLARE_CLASS(tex_results)
DECLARE_CLASS(text_literal)
DECLARE_CLASS(theme_tag)
DECLARE_CLASS(weave_format)
DECLARE_CLASS(weave_pattern)
DECLARE_CLASS(weave_plugin)
DECLARE_CLASS(weave_order)
DECLARE_CLASS(web)
DECLARE_CLASS(writeme_asset)
DECLARE_CLASS(weave_document_node)
DECLARE_CLASS(weave_head_node)
DECLARE_CLASS(weave_body_node)
DECLARE_CLASS(weave_tail_node)
DECLARE_CLASS(weave_section_header_node)
DECLARE_CLASS(weave_section_footer_node)
DECLARE_CLASS(weave_chapter_header_node)
DECLARE_CLASS(weave_chapter_footer_node)
DECLARE_CLASS(weave_verbatim_node)
DECLARE_CLASS(weave_section_purpose_node)
DECLARE_CLASS(weave_subheading_node)
DECLARE_CLASS(weave_bar_node)
DECLARE_CLASS(weave_linebreak_node)
DECLARE_CLASS(weave_pagebreak_node)
DECLARE_CLASS(weave_paragraph_heading_node)
DECLARE_CLASS(weave_endnote_node)
DECLARE_CLASS(weave_material_node)
DECLARE_CLASS(weave_figure_node)
DECLARE_CLASS(weave_extract_node)
DECLARE_CLASS(weave_audio_node)
DECLARE_CLASS(weave_video_node)
DECLARE_CLASS(weave_download_node)
DECLARE_CLASS(weave_embed_node)
DECLARE_CLASS(weave_pmac_node)
DECLARE_CLASS(weave_vskip_node)
DECLARE_CLASS(weave_chapter_node)
DECLARE_CLASS(weave_section_node)
DECLARE_CLASS(weave_code_line_node)
DECLARE_CLASS(weave_function_usage_node)
DECLARE_CLASS(weave_commentary_node)
DECLARE_CLASS(weave_carousel_slide_node)
DECLARE_CLASS(weave_toc_node)
DECLARE_CLASS(weave_toc_line_node)
DECLARE_CLASS(weave_chapter_title_page_node)
DECLARE_CLASS(weave_defn_node)
DECLARE_CLASS(weave_source_code_node)
DECLARE_CLASS(weave_url_node)
DECLARE_CLASS(weave_footnote_cue_node)
DECLARE_CLASS(weave_begin_footnote_text_node)
DECLARE_CLASS(weave_display_line_node)
DECLARE_CLASS(weave_item_node)
DECLARE_CLASS(weave_grammar_index_node)
DECLARE_CLASS(weave_inline_node)
DECLARE_CLASS(weave_locale_node)
DECLARE_CLASS(weave_maths_node)
DECLARE_CLASS(weave_function_defn_node)
#line 10 "inweb/Chapter 1/Program Control.w"
int default_inweb_syntax = V2_SYNTAX;
#line 22 "inweb/Chapter 1/Program Control.w"
#line 24 "inweb/Chapter 1/Program Control.w"
int fundamental_mode = NO_MODE;
#line 43 "inweb/Chapter 1/Program Control.w"
#line 51 "inweb/Chapter 1/Program Control.w"
pathname *path_to_inweb = NULL; /* where we are installed */
pathname *path_to_inweb_materials = NULL; /* the materials pathname */
pathname *path_to_inweb_patterns = NULL; /* where built-in patterns are stored */
#line 58 "inweb/Chapter 1/Program Control.w"
int no_inweb_errors = 0;
int verbose_mode = FALSE;
#line 64 "inweb/Chapter 1/Program Control.w"
int main(int argc, char **argv) {
{
#line 83 "inweb/Chapter 1/Program Control.w"
Foundation__start(argc, argv);
Formats__create_weave_formats();
}
#line 65 "inweb/Chapter 1/Program Control.w"
;
inweb_instructions args = Configuration__read(argc, argv);
verbose_mode = args.verbose_switch;
fundamental_mode = args.inweb_mode;
path_to_inweb = Pathnames__installation_path("INWEB_PATH", TL_IS_137);
if (verbose_mode) {
PRINT("Installation path is %p\n", path_to_inweb);
Locales__write_locales(STDOUT);
}
path_to_inweb_patterns = Pathnames__down(path_to_inweb, TL_IS_138);
path_to_inweb_materials = Pathnames__down(path_to_inweb, TL_IS_139);
Main__follow_instructions(&args);
{
#line 87 "inweb/Chapter 1/Program Control.w"
Foundation__end();
return (no_inweb_errors == 0)?0:1;
}
#line 79 "inweb/Chapter 1/Program Control.w"
;
}
#line 95 "inweb/Chapter 1/Program Control.w"
void Main__follow_instructions(inweb_instructions *ins) {
web *W = NULL;
if ((ins->chosen_web) || (ins->chosen_file)) {
W = Reader__load_web(ins->chosen_web, ins->chosen_file,
WebModules__make_search_path(ins->import_setting), TRUE);
W->redirect_weaves_to = ins->weave_into_setting;
Reader__read_web(W);
Parser__parse_web(W, ins->inweb_mode);
}
if (no_inweb_errors == 0) {
if (ins->inweb_mode == TRANSLATE_MODE)
{
#line 115 "inweb/Chapter 1/Program Control.w"
if ((ins->makefile_setting) && (ins->prototype_setting == NULL))
ins->prototype_setting = Filenames__from_text(TL_IS_140);
if ((ins->gitignore_setting) && (ins->prototype_setting == NULL))
ins->prototype_setting = Filenames__from_text(TL_IS_141);
if ((ins->writeme_setting) && (ins->prototype_setting == NULL))
ins->prototype_setting = Filenames__from_text(TL_IS_142);
if (ins->makefile_setting)
Makefiles__write(W, ins->prototype_setting, ins->makefile_setting,
WebModules__make_search_path(ins->import_setting), ins->platform_setting);
else if (ins->gitignore_setting)
Git__write_gitignore(W, ins->prototype_setting, ins->gitignore_setting);
else if (ins->advance_setting)
BuildFiles__advance(ins->advance_setting);
else if (ins->writeme_setting)
Readme__write(ins->prototype_setting, ins->writeme_setting);
}
#line 105 "inweb/Chapter 1/Program Control.w"
else if (ins->show_languages_switch)
{
#line 134 "inweb/Chapter 1/Program Control.w"
Languages__read_definitions(NULL);
Languages__show(STDOUT);
}
#line 106 "inweb/Chapter 1/Program Control.w"
else if ((ins->test_language_setting) || (ins->test_language_on_setting))
{
#line 140 "inweb/Chapter 1/Program Control.w"
if ((ins->test_language_setting) && (ins->test_language_on_setting)) {
TEMPORARY_TEXT(matter)
TEMPORARY_TEXT(coloured)
Painter__colour_file(ins->test_language_setting, ins->test_language_on_setting,
matter, coloured);
PRINT("Test of colouring for language %S:\n%S\n%S\n",
ins->test_language_setting->language_name, matter, coloured);
DISCARD_TEXT(matter)
DISCARD_TEXT(coloured)
} else {
Errors__fatal("-test-language and -test-language-on must both be given");
}
}
#line 107 "inweb/Chapter 1/Program Control.w"
else if (ins->inweb_mode != NO_MODE)
{
#line 156 "inweb/Chapter 1/Program Control.w"
if (ins->inweb_mode != ANALYSE_MODE) Reader__print_web_statistics(W);
if (ins->inweb_mode == ANALYSE_MODE)
{
#line 164 "inweb/Chapter 1/Program Control.w"
if (ins->swarm_mode != SWARM_OFF_SWM)
Errors__fatal("only specific parts of the web can be analysed");
if (ins->catalogue_switch)
Analyser__catalogue_the_sections(W, ins->chosen_range, BASIC_SECTIONCAT);
if (ins->functions_switch)
Analyser__catalogue_the_sections(W, ins->chosen_range, FUNCTIONS_SECTIONCAT);
if (ins->structures_switch)
Analyser__catalogue_the_sections(W, ins->chosen_range, STRUCTURES_SECTIONCAT);
if (ins->makefile_setting)
Analyser__write_makefile(W, ins->makefile_setting,
WebModules__make_search_path(ins->import_setting), ins->platform_setting);
if (ins->gitignore_setting)
Analyser__write_gitignore(W, ins->gitignore_setting);
if (ins->advance_switch)
BuildFiles__advance_for_web(W->md);
if (ins->scan_switch)
Analyser__scan_line_categories(W, ins->chosen_range);
}
#line 157 "inweb/Chapter 1/Program Control.w"
;
if (ins->inweb_mode == TANGLE_MODE)
{
#line 197 "inweb/Chapter 1/Program Control.w"
TEMPORARY_TEXT(tangle_leaf)
tangle_target *tn = NULL;
if (Str__eq_wide_string(ins->chosen_range, L"0")) {
{
#line 221 "inweb/Chapter 1/Program Control.w"
tn = NULL;
if (Bibliographic__data_exists(W->md, TL_IS_143))
Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_144));
else
Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_145));
Str__concatenate(tangle_leaf, W->main_language->file_extension);
}
#line 200 "inweb/Chapter 1/Program Control.w"
;
} else if (Reader__get_section_for_range(W, ins->chosen_range)) {
{
#line 231 "inweb/Chapter 1/Program Control.w"
section *S = Reader__get_section_for_range(W, ins->chosen_range);
tn = S->sect_target;
if (tn == NULL) Errors__fatal("section cannot be independently tangled");
Str__copy(tangle_leaf, Filenames__get_leafname(S->md->source_file_for_section));
}
#line 202 "inweb/Chapter 1/Program Control.w"
;
}
if (Str__len(tangle_leaf) == 0) { Errors__fatal("no tangle destination known"); }
filename *tangle_to = ins->tangle_setting;
if (tangle_to == NULL) {
pathname *P = Reader__tangled_folder(W);
if (W->md->single_file) P = Filenames__up(W->md->single_file);
tangle_to = Filenames__in(P, tangle_leaf);
}
if (tn == NULL) tn = Tangler__primary_target(W);
Tangler__tangle(W, tn, tangle_to);
if (ins->ctags_switch) Ctags__write(W, ins->ctags_setting);
DISCARD_TEXT(tangle_leaf)
}
#line 158 "inweb/Chapter 1/Program Control.w"
;
if (ins->inweb_mode == WEAVE_MODE)
{
#line 239 "inweb/Chapter 1/Program Control.w"
Numbering__number_web(W);
theme_tag *tag = Tags__find_by_name(ins->tag_setting, FALSE);
if ((Str__len(ins->tag_setting) > 0) && (tag == NULL))
Errors__fatal_with_text("no such theme as '%S'", ins->tag_setting);
weave_pattern *pattern = Patterns__find(W, ins->weave_pattern);
if ((ins->chosen_range_actually_chosen == FALSE) && (ins->chosen_file == NULL))
Configuration__set_range(ins, pattern->default_range);
int r = Formats__begin_weaving(W, pattern);
if (r != SWARM_OFF_SWM) ins->swarm_mode = r;
{
#line 264 "inweb/Chapter 1/Program Control.w"
section *S; int k = 1;
LOOP_OVER(S, section)
if (Reader__range_within(S->md->sect_range, ins->chosen_range))
S->printed_number = k++;
}
#line 251 "inweb/Chapter 1/Program Control.w"
;
if (ins->swarm_mode == SWARM_OFF_SWM) {
Swarm__weave_subset(W, ins->chosen_range, FALSE, tag, pattern,
ins->weave_to_setting, ins->weave_into_setting,
ins->breadcrumb_setting, ins->navigation_setting);
} else {
Swarm__weave(W, ins->chosen_range, ins->swarm_mode, tag, pattern,
ins->weave_to_setting, ins->weave_into_setting,
ins->breadcrumb_setting, ins->navigation_setting);
}
Formats__end_weaving(W, pattern);
}
#line 159 "inweb/Chapter 1/Program Control.w"
;
}
#line 108 "inweb/Chapter 1/Program Control.w"
;
}
}
#line 275 "inweb/Chapter 1/Program Control.w"
void Main__error_in_web(text_stream *message, source_line *sl) {
if (sl) {
Errors__in_text_file_S(message, &(sl->source));
WRITE_TO(STDERR, "%07d %S\n", sl->source.line_count, sl->text);
} else {
Errors__in_text_file_S(message, NULL);
}
no_inweb_errors++;
}
#line 52 "inweb/Chapter 1/Configuration.w"
#line 59 "inweb/Chapter 1/Configuration.w"
inweb_instructions Configuration__read(int argc, char **argv) {
inweb_instructions args;
{
#line 79 "inweb/Chapter 1/Configuration.w"
args.inweb_mode = NO_MODE;
args.swarm_mode = SWARM_OFF_SWM;
args.show_languages_switch = FALSE;
args.catalogue_switch = FALSE;
args.functions_switch = FALSE;
args.structures_switch = FALSE;
args.advance_switch = FALSE;
args.scan_switch = FALSE;
args.verbose_switch = FALSE;
args.ctags_switch = TRUE;
args.chosen_web = NULL;
args.chosen_file = NULL;
args.chosen_range = Str__new();
args.chosen_range_actually_chosen = FALSE;
args.tangle_setting = NULL;
args.ctags_setting = NULL;
args.weave_to_setting = NULL;
args.weave_into_setting = NULL;
args.makefile_setting = NULL;
args.gitignore_setting = NULL;
args.advance_setting = NULL;
args.writeme_setting = NULL;
args.prototype_setting = NULL;
args.navigation_setting = NULL;
args.colony_setting = NULL;
args.member_setting = NULL;
args.breadcrumb_setting = NEW_LINKED_LIST(breadcrumb_request);
args.platform_setting = NULL;
args.tag_setting = Str__new();
args.weave_pattern = Str__new();
args.import_setting = NULL;
args.targets = 0;
args.test_language_setting = NULL;
args.test_language_on_setting = NULL;
}
#line 61 "inweb/Chapter 1/Configuration.w"
;
{
#line 167 "inweb/Chapter 1/Configuration.w"
CommandLine__declare_heading(L"inweb: a tool for literate programming\n\n"
L"Usage: inweb WEB OPTIONS RANGE\n\n"
L"WEB must be a directory holding a literate program (a 'web')\n\n"
L"The legal RANGEs are:\n"
L" all: complete web (the default if no TARGETS set)\n"
L" P: all preliminaries\n"
L" 1: Chapter 1 (and so on)\n"
L" A: Appendix A (and so on, up to Appendix O)\n"
L" 3/eg: section with abbreviated name \"3/eg\" (and so on)\n"
L"You can also, or instead, specify:\n"
L" index: to weave an HTML page indexing the project\n"
L" chapters: to weave all chapters as individual documents\n"
L" sections: ditto with sections\n");
CommandLine__begin_group(LANGUAGES_CLSG,
TL_IS_147);
CommandLine__declare_switch(LANGUAGE_CLSW, L"read-language", 2,
L"read language definition from file X");
CommandLine__declare_switch(LANGUAGES_CLSW, L"read-languages", 2,
L"read all language definitions in path X");
CommandLine__declare_switch(SHOW_LANGUAGES_CLSW, L"show-languages", 1,
L"list programming languages supported by Inweb");
CommandLine__declare_switch(TEST_LANGUAGE_CLSW, L"test-language", 2,
L"test language X on...");
CommandLine__declare_switch(TEST_LANGUAGE_ON_CLSW, L"test-language-on", 2,
L"...the code in the file X");
CommandLine__end_group();
CommandLine__begin_group(ANALYSIS_CLSG,
TL_IS_148);
CommandLine__declare_switch(CATALOGUE_CLSW, L"catalogue", 1,
L"list the sections in the web");
CommandLine__declare_switch(CATALOGUE_CLSW, L"catalog", 1,
L"same as '-catalogue'");
CommandLine__declare_switch(MAKEFILE_CLSW, L"makefile", 2,
L"write a makefile for this web and store it in X");
CommandLine__declare_switch(GITIGNORE_CLSW, L"gitignore", 2,
L"write a .gitignore file for this web and store it in X");
CommandLine__declare_switch(ADVANCE_FILE_CLSW, L"advance-build-file", 2,
L"increment daily build code in file X");
CommandLine__declare_switch(WRITEME_CLSW, L"write-me", 2,
L"write a read-me file following instructions in file X");
CommandLine__declare_switch(PLATFORM_CLSW, L"platform", 2,
L"use platform X (e.g. 'windows') when making e.g. makefiles");
CommandLine__declare_switch(PROTOTYPE_CLSW, L"prototype", 2,
L"translate makefile from prototype X");
CommandLine__declare_switch(FUNCTIONS_CLSW, L"functions", 1,
L"catalogue the functions in the web");
CommandLine__declare_switch(STRUCTURES_CLSW, L"structures", 1,
L"catalogue the structures in the web");
CommandLine__declare_switch(ADVANCE_CLSW, L"advance-build", 1,
L"increment daily build code for the web");
CommandLine__declare_switch(SCAN_CLSW, L"scan", 1,
L"scan the web");
CommandLine__end_group();
CommandLine__begin_group(WEAVING_CLSG,
TL_IS_149);
CommandLine__declare_switch(WEAVE_CLSW, L"weave", 1,
L"weave the web into human-readable form");
CommandLine__declare_switch(WEAVE_INTO_CLSW, L"weave-into", 2,
L"weave, but into directory X");
CommandLine__declare_switch(WEAVE_TO_CLSW, L"weave-to", 2,
L"weave, but to filename X (for single files only)");
CommandLine__declare_switch(OPEN_CLSW, L"open", 1,
L"weave then open woven file");
CommandLine__declare_switch(WEAVE_AS_CLSW, L"weave-as", 2,
L"set weave pattern to X (default is 'HTML')");
CommandLine__declare_switch(WEAVE_TAG_CLSW, L"weave-tag", 2,
L"weave, but only using material tagged as X");
CommandLine__declare_switch(BREADCRUMB_CLSW, L"breadcrumb", 2,
L"use the text X as a breadcrumb in overhead navigation");
CommandLine__declare_switch(NAVIGATION_CLSW, L"navigation", 2,
L"use the file X as a column of navigation links");
CommandLine__end_group();
CommandLine__begin_group(TANGLING_CLSG,
TL_IS_150);
CommandLine__declare_switch(TANGLE_CLSW, L"tangle", 1,
L"tangle the web into machine-compilable form");
CommandLine__declare_switch(TANGLE_TO_CLSW, L"tangle-to", 2,
L"tangle, but to filename X");
CommandLine__declare_switch(CTAGS_TO_CLSW, L"ctags-to", 2,
L"tangle, but write Universal Ctags file to X not to 'tags'");
CommandLine__declare_boolean_switch(CTAGS_CLSW, L"ctags", 1,
L"write a Universal Ctags file when tangling", TRUE);
CommandLine__end_group();
CommandLine__begin_group(COLONIAL_CLSG,
TL_IS_151);
CommandLine__declare_switch(COLONY_CLSW, L"colony", 2,
L"use the file X as a list of webs in this colony");
CommandLine__declare_switch(MEMBER_CLSW, L"member", 2,
L"use member X from the colony as our web");
CommandLine__end_group();
CommandLine__declare_boolean_switch(VERBOSE_CLSW, L"verbose", 1,
L"explain what inweb is doing", FALSE);
CommandLine__declare_switch(IMPORT_FROM_CLSW, L"import-from", 2,
L"specify that imported modules are at pathname X");
}
#line 62 "inweb/Chapter 1/Configuration.w"
;
CommandLine__read(argc, argv, &args, &Configuration__switch, &Configuration__bareword);
Configuration__member_and_colony(&args);
if (Str__len(args.weave_pattern) == 0) WRITE_TO(args.weave_pattern, "HTML");
if ((args.chosen_web == NULL) && (args.chosen_file == NULL)) {
if ((args.makefile_setting) || (args.gitignore_setting))
args.inweb_mode = TRANSLATE_MODE;
if (args.inweb_mode != TRANSLATE_MODE)
args.inweb_mode = NO_MODE;
}
if (Str__len(args.chosen_range) == 0) {
Str__copy(args.chosen_range, TL_IS_146);
}
return args;
}
#line 120 "inweb/Chapter 1/Configuration.w"
#line 122 "inweb/Chapter 1/Configuration.w"
#line 128 "inweb/Chapter 1/Configuration.w"
#line 130 "inweb/Chapter 1/Configuration.w"
#line 142 "inweb/Chapter 1/Configuration.w"
#line 144 "inweb/Chapter 1/Configuration.w"
#line 153 "inweb/Chapter 1/Configuration.w"
#line 155 "inweb/Chapter 1/Configuration.w"
#line 160 "inweb/Chapter 1/Configuration.w"
#line 162 "inweb/Chapter 1/Configuration.w"
#line 165 "inweb/Chapter 1/Configuration.w"
#line 271 "inweb/Chapter 1/Configuration.w"
void Configuration__switch(int id, int val, text_stream *arg, void *state) {
inweb_instructions *args = (inweb_instructions *) state;
switch (id) {
/* Miscellaneous */
case VERBOSE_CLSW: args->verbose_switch = TRUE; break;
case IMPORT_FROM_CLSW: args->import_setting = Pathnames__from_text(arg); break;
/* Analysis */
case LANGUAGE_CLSW:
Languages__read_definition(Filenames__from_text(arg)); break;
case LANGUAGES_CLSW:
Languages__read_definitions(Pathnames__from_text(arg)); break;
case SHOW_LANGUAGES_CLSW:
args->show_languages_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case TEST_LANGUAGE_CLSW:
args->test_language_setting =
Languages__read_definition(Filenames__from_text(arg));
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case TEST_LANGUAGE_ON_CLSW:
args->test_language_on_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case CATALOGUE_CLSW:
args->catalogue_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case FUNCTIONS_CLSW:
args->functions_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case STRUCTURES_CLSW:
args->structures_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case ADVANCE_CLSW:
args->advance_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case MAKEFILE_CLSW:
args->makefile_setting = Filenames__from_text(arg);
if (args->inweb_mode != TRANSLATE_MODE)
Configuration__set_fundamental_mode(args, ANALYSE_MODE);
break;
case GITIGNORE_CLSW:
args->gitignore_setting = Filenames__from_text(arg);
if (args->inweb_mode != TRANSLATE_MODE)
Configuration__set_fundamental_mode(args, ANALYSE_MODE);
break;
case PLATFORM_CLSW:
args->platform_setting = Str__duplicate(arg);
break;
case ADVANCE_FILE_CLSW:
args->advance_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TRANSLATE_MODE);
break;
case WRITEME_CLSW:
args->writeme_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TRANSLATE_MODE);
break;
case PROTOTYPE_CLSW:
args->prototype_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TRANSLATE_MODE); break;
case SCAN_CLSW:
args->scan_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
/* Weave-related */
case WEAVE_CLSW:
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case WEAVE_INTO_CLSW:
args->weave_into_setting = Pathnames__from_text(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case WEAVE_TO_CLSW:
args->weave_to_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case WEAVE_AS_CLSW:
args->weave_pattern = Str__duplicate(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case WEAVE_TAG_CLSW:
args->tag_setting = Str__duplicate(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case BREADCRUMB_CLSW:
ADD_TO_LINKED_LIST(Colonies__request_breadcrumb(arg),
breadcrumb_request, args->breadcrumb_setting);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case NAVIGATION_CLSW:
args->navigation_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
/* Colonial */
case COLONY_CLSW:
args->colony_setting = Filenames__from_text(arg); break;
case MEMBER_CLSW:
args->member_setting = Str__duplicate(arg); break;
/* Tangle-related */
case TANGLE_CLSW:
Configuration__set_fundamental_mode(args, TANGLE_MODE); break;
case TANGLE_TO_CLSW:
args->tangle_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TANGLE_MODE); break;
case CTAGS_TO_CLSW:
args->ctags_setting = Filenames__from_text(arg);
break;
case CTAGS_CLSW:
args->ctags_switch = val;
break;
default: internal_error("unimplemented switch");
}
}
#line 383 "inweb/Chapter 1/Configuration.w"
void Configuration__member_and_colony(inweb_instructions *args) {
if (args->colony_setting) Colonies__load(args->colony_setting);
if (Str__len(args->member_setting) > 0) {
if ((args->chosen_web == NULL) && (args->chosen_file == NULL)) {
colony_member *CM = Colonies__find(args->member_setting);
if (CM == NULL) Errors__fatal("the colony has no member of that name");
Configuration__bareword(0, CM->path, args);
if (Str__len(args->weave_pattern) == 0)
args->weave_pattern = CM->default_weave_pattern;
if (LinkedLists__len(args->breadcrumb_setting) == 0)
args->breadcrumb_setting = CM->breadcrumb_tail;
if (args->navigation_setting == NULL)
args->navigation_setting = CM->navigation;
if (args->weave_into_setting == NULL)
args->weave_into_setting = CM->weave_path;
} else {
Errors__fatal("cannot specify a web and also use -member");
}
}
}
#line 409 "inweb/Chapter 1/Configuration.w"
void Configuration__bareword(int id, text_stream *opt, void *state) {
inweb_instructions *args = (inweb_instructions *) state;
if ((args->chosen_web == NULL) && (args->chosen_file == NULL)) {
if (Str__suffix_eq(opt, TL_IS_152, 6))
args->chosen_file = Filenames__from_text(opt);
else
args->chosen_web = Pathnames__from_text(opt);
} else Configuration__set_range(args, opt);
}
#line 424 "inweb/Chapter 1/Configuration.w"
void Configuration__set_range(inweb_instructions *args, text_stream *opt) {
match_results mr = Regexp__create_mr();
if (Str__eq_wide_string(opt, L"index")) {
args->swarm_mode = SWARM_INDEX_SWM;
} else if (Str__eq_wide_string(opt, L"chapters")) {
args->swarm_mode = SWARM_CHAPTERS_SWM;
} else if (Str__eq_wide_string(opt, L"sections")) {
args->swarm_mode = SWARM_SECTIONS_SWM;
} else {
if (++args->targets > 1) Errors__fatal("at most one target may be given");
if (Str__eq_wide_string(opt, L"all")) {
Str__copy(args->chosen_range, TL_IS_153);
} else if (((isalnum(Str__get_first_char(opt))) && (Str__len(opt) == 1))
|| (Regexp__match(&mr, opt, L"%i+/%i+"))) {
Str__copy(args->chosen_range, opt);
string_position P = Str__start(args->chosen_range);
Str__put(P, Characters__toupper(Str__get(P)));
} else {
TEMPORARY_TEXT(ERM)
WRITE_TO(ERM, "target not recognised (see -help for more): %S", opt);
Main__error_in_web(ERM, NULL);
DISCARD_TEXT(ERM)
exit(1);
}
}
args->chosen_range_actually_chosen = TRUE;
Regexp__dispose_of(&mr);
}
#line 456 "inweb/Chapter 1/Configuration.w"
void Configuration__set_fundamental_mode(inweb_instructions *args, int new_material) {
if ((args->inweb_mode != NO_MODE) && (args->inweb_mode != new_material))
Errors__fatal("can only do one at a time - weaving, tangling or analysing");
args->inweb_mode = new_material;
}
#line 18 "inweb/Chapter 1/The Swarm.w"
weave_order *swarm_leader = NULL; /* the most inclusive one we weave */
void Swarm__weave(web *W, text_stream *range, int swarm_mode, theme_tag *tag,
weave_pattern *pattern, filename *to, pathname *into,
linked_list *breadcrumbs, filename *navigation) {
swarm_leader = NULL;
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
if (C->md->imported == FALSE) {
if (swarm_mode == SWARM_CHAPTERS_SWM)
if ((W->md->chaptered == TRUE) && (Reader__range_within(C->md->ch_range, range))) {
C->ch_weave = Swarm__weave_subset(W,
C->md->ch_range, FALSE, tag, pattern, to, into,
breadcrumbs, navigation);
if (Str__len(range) > 0) swarm_leader = C->ch_weave;
}
if (swarm_mode == SWARM_SECTIONS_SWM)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Reader__range_within(S->md->sect_range, range))
S->sect_weave = Swarm__weave_subset(W,
S->md->sect_range, FALSE, tag, pattern, to, into,
breadcrumbs, navigation);
}
Swarm__weave_index_templates(W, range, pattern, into, navigation, breadcrumbs);
}
#line 51 "inweb/Chapter 1/The Swarm.w"
weave_order *Swarm__weave_subset(web *W, text_stream *range, int open_afterwards,
theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into,
linked_list *breadcrumbs, filename *navigation) {
weave_order *wv = NULL;
if (no_inweb_errors == 0) {
Analyser__analyse_code(W);
{
#line 91 "inweb/Chapter 1/The Swarm.w"
wv = CREATE(weave_order);
wv->weave_web = W;
wv->weave_range = Str__duplicate(range);
wv->pattern = pattern;
wv->theme_match = tag;
wv->booklet_title = Str__new();
wv->format = pattern->pattern_format;
wv->post_processing_results = NULL;
wv->self_contained = FALSE;
wv->navigation = navigation;
wv->breadcrumbs = breadcrumbs;
wv->plugins = NEW_LINKED_LIST(weave_plugin);
wv->colour_schemes = NEW_LINKED_LIST(colour_scheme);
if (Reader__web_has_one_section(W)) wv->self_contained = TRUE;
wv->current_weave_line = NULL;
int has_content = FALSE;
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Reader__range_within(S->md->sect_range, wv->weave_range))
has_content = TRUE;
if (has_content == FALSE)
Errors__fatal("no sections match that range");
TEMPORARY_TEXT(leafname)
{
#line 140 "inweb/Chapter 1/The Swarm.w"
match_results mr = Regexp__create_mr();
if (Str__eq_wide_string(range, L"0")) {
if (W->md->single_file) {
wv->booklet_title = Str__duplicate(Bibliographic__get_datum(W->md, TL_IS_154));
Filenames__write_unextended_leafname(leafname, W->md->single_file);
} else {
wv->booklet_title = Str__new_from_wide_string(L"Complete Program");
WRITE_TO(leafname, "Complete");
}
if (wv->theme_match)
{
#line 178 "inweb/Chapter 1/The Swarm.w"
Str__clear(wv->booklet_title);
WRITE_TO(wv->booklet_title, "Extracts: %S", wv->theme_match->tag_name);
Str__copy(leafname, wv->theme_match->tag_name);
}
#line 149 "inweb/Chapter 1/The Swarm.w"
;
} else if (Regexp__match(&mr, range, L"%d+")) {
Str__clear(wv->booklet_title);
WRITE_TO(wv->booklet_title, "Chapter %S", range);
Str__copy(leafname, wv->booklet_title);
} else if (Regexp__match(&mr, range, L"%[A-O]")) {
Str__clear(wv->booklet_title);
WRITE_TO(wv->booklet_title, "Appendix %S", range);
Str__copy(leafname, wv->booklet_title);
} else if (Str__eq_wide_string(range, L"P")) {
wv->booklet_title = Str__new_from_wide_string(L"Preliminaries");
Str__copy(leafname, wv->booklet_title);
} else if (Str__eq_wide_string(range, L"M")) {
wv->booklet_title = Str__new_from_wide_string(L"Manual");
Str__copy(leafname, wv->booklet_title);
} else {
section *S = Reader__get_section_for_range(W, range);
if (S) Str__copy(wv->booklet_title, S->md->sect_title);
else Str__copy(wv->booklet_title, range);
Str__copy(leafname, range);
}
Bibliographic__set_datum(W->md, TL_IS_155, wv->booklet_title);
LOOP_THROUGH_TEXT(P, leafname)
if ((Str__get(P) == '/') || (Str__get(P) == ' '))
Str__put(P, '-');
WRITE_TO(leafname, "%S", Formats__file_extension(wv->format));
Regexp__dispose_of(&mr);
}
#line 119 "inweb/Chapter 1/The Swarm.w"
;
pathname *H = W->redirect_weaves_to;
if (H == NULL) H = into;
if (H == NULL) {
if (W->md->single_file == NULL)
H = Reader__woven_folder(W);
else
H = Filenames__up(W->md->single_file);
}
if (to) {
wv->weave_to = to;
wv->self_contained = TRUE;
} else wv->weave_to = Filenames__in(H, leafname);
if (Str__len(pattern->initial_extension) > 0)
wv->weave_to = Filenames__set_extension(wv->weave_to, pattern->initial_extension);
DISCARD_TEXT(leafname)
}
#line 57 "inweb/Chapter 1/The Swarm.w"
;
if (Weaver__weave(wv) == 0) /* i.e., the number of lines woven was zero */
Errors__fatal("empty weave request");
Patterns__post_process(wv->pattern, wv);
Formats__post_process_weave(wv, open_afterwards);
{
#line 185 "inweb/Chapter 1/The Swarm.w"
PRINT("[%S: %S -> %f", wv->booklet_title, wv->format->format_name, wv->weave_to);
Formats__report_on_post_processing(wv);
PRINT("]\n");
}
#line 62 "inweb/Chapter 1/The Swarm.w"
;
}
return wv;
}
#line 89 "inweb/Chapter 1/The Swarm.w"
#line 190 "inweb/Chapter 1/The Swarm.w"
void Swarm__ensure_plugin(weave_order *wv, text_stream *name) {
weave_plugin *existing;
LOOP_OVER_LINKED_LIST(existing, weave_plugin, wv->plugins)
if (Str__eq_insensitive(name, existing->plugin_name))
return;
weave_plugin *wp = Assets__new(name);
ADD_TO_LINKED_LIST(wp, weave_plugin, wv->plugins);
}
colour_scheme *Swarm__ensure_colour_scheme(weave_order *wv, text_stream *name,
text_stream *pre) {
colour_scheme *existing;
LOOP_OVER_LINKED_LIST(existing, colour_scheme, wv->colour_schemes)
if (Str__eq_insensitive(name, existing->scheme_name))
return existing;
colour_scheme *cs = Assets__find_colour_scheme(wv->pattern, name, pre);
if (cs == NULL) {
if (Str__eq(name, TL_IS_156)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "No CSS file for the colour scheme '%S' can be found", name);
Main__error_in_web(err, NULL);
} else {
return Swarm__ensure_colour_scheme(wv, TL_IS_157, TL_IS_158);
}
}
if (cs) ADD_TO_LINKED_LIST(cs, colour_scheme, wv->colour_schemes);
return cs;
}
void Swarm__include_plugins(OUTPUT_STREAM, web *W, weave_order *wv, filename *from) {
weave_plugin *wp;
LOOP_OVER_LINKED_LIST(wp, weave_plugin, wv->plugins)
Assets__include_plugin(OUT, W, wp, wv->pattern, from);
colour_scheme *cs;
LOOP_OVER_LINKED_LIST(cs, colour_scheme, wv->colour_schemes)
Assets__include_colour_scheme(OUT, W, cs, wv->pattern, from);
}
#line 231 "inweb/Chapter 1/The Swarm.w"
void Swarm__weave_index_templates(web *W, text_stream *range, weave_pattern *pattern,
pathname *into, filename *nav, linked_list *crumbs) {
if (!(Bibliographic__data_exists(W->md, TL_IS_159)))
Bibliographic__set_datum(W->md, TL_IS_160, TL_IS_161);
filename *INF = Patterns__find_template(pattern, TL_IS_162);
if (INF) {
pathname *H = W->redirect_weaves_to;
if (H == NULL) H = Reader__woven_folder(W);
filename *Contents = Filenames__in(H, TL_IS_163);
text_stream TO_struct; text_stream *OUT = &TO_struct;
if (STREAM_OPEN_TO_FILE(OUT, Contents, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to write contents file", Contents);
if (W->as_ebook)
Epub__note_page(W->as_ebook, Contents, TL_IS_164, TL_IS_165);
PRINT("[Index file: %f]\n", Contents);
Collater__collate(OUT, W, range, INF, pattern, nav, crumbs, NULL, Contents);
STREAM_CLOSE(OUT);
}
}
#line 38 "inweb/Chapter 1/Patterns.w"
#line 42 "inweb/Chapter 1/Patterns.w"
weave_pattern *Patterns__find(web *W, text_stream *name) {
filename *pattern_file = NULL;
weave_pattern *wp = CREATE(weave_pattern);
{
#line 52 "inweb/Chapter 1/Patterns.w"
wp->pattern_name = Str__duplicate(name);
wp->pattern_location = NULL;
wp->plugins = NEW_LINKED_LIST(weave_plugin);
wp->colour_schemes = NEW_LINKED_LIST(colour_scheme);
wp->based_on = NULL;
wp->asset_rules = Assets__new_asset_rules_list();
wp->patterned_for = W;
wp->number_sections = FALSE;
wp->footnotes_plugin = NULL;
wp->mathematics_plugin = NULL;
wp->default_range = Str__duplicate(TL_IS_166);
wp->initial_extension = NULL;
wp->post_commands = NEW_LINKED_LIST(text_stream);
wp->blocked_templates = NEW_LINKED_LIST(text_stream);
wp->commands = 0;
wp->name_command_given = FALSE;
}
#line 45 "inweb/Chapter 1/Patterns.w"
;
{
#line 70 "inweb/Chapter 1/Patterns.w"
wp->pattern_location = NULL;
pathname *CP = Colonies__patterns_path();
if (CP) {
wp->pattern_location = Pathnames__down(CP, name);
pattern_file = Filenames__in(wp->pattern_location, TL_IS_167);
if (TextFiles__exists(pattern_file) == FALSE) wp->pattern_location = NULL;
}
if (wp->pattern_location == NULL) {
wp->pattern_location = Pathnames__down(
Pathnames__down(W->md->path_to_web, TL_IS_168), name);
pattern_file = Filenames__in(wp->pattern_location, TL_IS_169);
if (TextFiles__exists(pattern_file) == FALSE) wp->pattern_location = NULL;
}
if (wp->pattern_location == NULL) {
wp->pattern_location = Pathnames__down(
path_to_inweb_patterns, name);
pattern_file = Filenames__in(wp->pattern_location, TL_IS_170);
if (TextFiles__exists(pattern_file) == FALSE) wp->pattern_location = NULL;
}
if (wp->pattern_location == NULL)
Errors__fatal_with_text("no such weave pattern as '%S'", name);
}
#line 46 "inweb/Chapter 1/Patterns.w"
;
{
#line 93 "inweb/Chapter 1/Patterns.w"
if (pattern_file)
TextFiles__read(pattern_file, FALSE, "can't open pattern.txt file",
TRUE, Patterns__scan_pattern_line, NULL, wp);
if (wp->pattern_format == NULL)
Errors__fatal_with_text("pattern did not specify a format", name);
if (wp->name_command_given == FALSE)
Errors__fatal_with_text("pattern did not name itself at the top", name);
}
#line 47 "inweb/Chapter 1/Patterns.w"
;
return wp;
}
#line 106 "inweb/Chapter 1/Patterns.w"
void Patterns__scan_pattern_line(text_stream *line, text_file_position *tfp, void *X) {
weave_pattern *wp = (weave_pattern *) X;
Str__trim_white_space(line); /* ignore trailing space */
if (Str__len(line) == 0) return; /* ignore blank lines */
if (Str__get_first_char(line) == '#') return; /* lines opening with |#| are comments */
wp->commands++;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+) *: *(%c+?)")) {
text_stream *key = mr.exp[0], *value = Str__duplicate(mr.exp[1]);
if ((Str__eq_insensitive(key, TL_IS_171)) && (wp->commands == 1)) {
match_results mr2 = Regexp__create_mr();
if (Regexp__match(&mr2, value, L"(%c+?) based on (%c+)")) {
if (Str__ne_insensitive(mr2.exp[0], wp->pattern_name)) {
Errors__in_text_file("wrong pattern name", tfp);
}
wp->based_on = Patterns__find(wp->patterned_for, mr2.exp[1]);
wp->pattern_format = wp->based_on->pattern_format;
wp->number_sections = wp->based_on->number_sections;
wp->default_range = Str__duplicate(wp->based_on->default_range);
wp->mathematics_plugin = Str__duplicate(wp->based_on->mathematics_plugin);
wp->footnotes_plugin = Str__duplicate(wp->based_on->footnotes_plugin);
} else {
if (Str__ne_insensitive(value, wp->pattern_name)) {
Errors__in_text_file("wrong pattern name", tfp);
}
}
Regexp__dispose_of(&mr2);
wp->name_command_given = TRUE;
} else if (Str__eq_insensitive(key, TL_IS_172)) {
text_stream *name = Patterns__plugin_name(value, tfp);
if (Str__len(name) > 0) {
weave_plugin *plugin = Assets__new(name);
ADD_TO_LINKED_LIST(plugin, weave_plugin, wp->plugins);
}
} else if (Str__eq_insensitive(key, TL_IS_173)) {
wp->pattern_format = Formats__find_by_name(value);
} else if (Str__eq_insensitive(key, TL_IS_174)) {
wp->number_sections = Patterns__yes_or_no(value, tfp);
} else if (Str__eq_insensitive(key, TL_IS_175)) {
wp->default_range = Str__duplicate(value);
} else if (Str__eq_insensitive(key, TL_IS_176)) {
wp->initial_extension = Str__duplicate(value);
} else if (Str__eq_insensitive(key, TL_IS_177)) {
wp->mathematics_plugin = Patterns__plugin_name(value, tfp);
} else if (Str__eq_insensitive(key, TL_IS_178)) {
wp->footnotes_plugin = Patterns__plugin_name(value, tfp);
} else if (Str__eq_insensitive(key, TL_IS_179)) {
ADD_TO_LINKED_LIST(Str__duplicate(value), text_stream, wp->blocked_templates);
} else if (Str__eq_insensitive(key, TL_IS_180)) {
ADD_TO_LINKED_LIST(Str__duplicate(value), text_stream, wp->post_commands);
} else if (Str__eq_insensitive(key, TL_IS_181)) {
match_results mr2 = Regexp__create_mr();
if (Regexp__match(&mr2, value, L"(%c+?) = (%c+)")) {
Bibliographic__set_datum(wp->patterned_for->md, mr2.exp[0], mr2.exp[1]);
} else {
Errors__in_text_file("syntax is 'bibliographic data: X = Y'", tfp);
}
Regexp__dispose_of(&mr2);
} else if (Str__eq_insensitive(key, TL_IS_182)) {
match_results mr2 = Regexp__create_mr();
if (Regexp__match(&mr2, value, L"(.%C+?) (%c+)")) {
Assets__add_asset_rule(wp->asset_rules, mr2.exp[0], mr2.exp[1], tfp);
} else {
Errors__in_text_file("syntax is 'assets: .EXT COMMAND'", tfp);
}
Regexp__dispose_of(&mr2);
} else {
Errors__in_text_file("unrecognised pattern command", tfp);
}
} else {
Errors__in_text_file("unrecognised pattern command", tfp);
}
Regexp__dispose_of(&mr);
}
#line 184 "inweb/Chapter 1/Patterns.w"
int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) {
if (Str__eq(arg, TL_IS_183)) return TRUE;
if (Str__eq(arg, TL_IS_184)) return FALSE;
Errors__in_text_file("setting must be 'yes' or 'no'", tfp);
return FALSE;
}
text_stream *Patterns__plugin_name(text_stream *arg, text_file_position *tfp) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, arg, L"(%i+)")) {
if (Str__eq_insensitive(arg, TL_IS_185)) return NULL;
} else {
Errors__in_text_file("plugin names must be single alphanumeric words", tfp);
arg = NULL;
}
Regexp__dispose_of(&mr);
return Str__duplicate(arg);
}
#line 208 "inweb/Chapter 1/Patterns.w"
void Patterns__post_process(weave_pattern *pattern, weave_order *wv) {
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, pattern->post_commands) {
filename *last_F = NULL;
TEMPORARY_TEXT(cmd)
for (int i=0; i<Str__len(T); i++) {
if (Str__includes_at(T, i, TL_IS_186)) {
Shell__quote_path(cmd, Filenames__up(wv->weave_to));
i += 8;
} else if (Str__includes_at(T, i, TL_IS_187)) {
filename *W = wv->weave_to;
i += 5;
if (Str__get_at(T, i) == '.') {
i++;
TEMPORARY_TEXT(ext)
while (Characters__isalpha(Str__get_at(T, i)))
PUT_TO(ext,Str__get_at(T, i++));
W = Filenames__set_extension(W, ext);
DISCARD_TEXT(ext)
}
Shell__quote_file(cmd, W);
last_F = W;
i--;
} else PUT_TO(cmd, Str__get_at(T, i));
}
if ((Str__includes_at(cmd, 0, TL_IS_188)) && (last_F)) {
TeXUtilities__post_process_weave(wv, last_F);
} else {
if (verbose_mode) PRINT("(%S)\n", cmd);
int rv = Shell__run(cmd);
if (rv != 0) Errors__fatal("post-processing command failed");
}
DISCARD_TEXT(cmd)
}
}
#line 252 "inweb/Chapter 1/Patterns.w"
filename *Patterns__find_template(weave_pattern *pattern, text_stream *leafname) {
for (weave_pattern *wp = pattern; wp; wp = wp->based_on) {
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, pattern->blocked_templates)
if (Str__eq_insensitive(T, leafname))
return NULL;
filename *F = Filenames__in(wp->pattern_location, leafname);
if (TextFiles__exists(F)) return F;
}
return NULL;
}
#line 267 "inweb/Chapter 1/Patterns.w"
filename *Patterns__find_file_in_subdirectory(weave_pattern *pattern,
text_stream *dirname, text_stream *leafname) {
for (weave_pattern *wp = pattern; wp; wp = wp->based_on) {
pathname *P = Pathnames__down(wp->pattern_location, dirname);
filename *F = Filenames__in(P, leafname);
if (TextFiles__exists(F)) return F;
}
return NULL;
}
#line 278 "inweb/Chapter 1/Patterns.w"
void Patterns__include_plugins(OUTPUT_STREAM, web *W, weave_pattern *pattern, filename *from) {
for (weave_pattern *p = pattern; p; p = p->based_on) {
weave_plugin *wp;
LOOP_OVER_LINKED_LIST(wp, weave_plugin, p->plugins)
Assets__include_plugin(OUT, W, wp, pattern, from);
colour_scheme *cs;
LOOP_OVER_LINKED_LIST(cs, colour_scheme, p->colour_schemes)
Assets__include_colour_scheme(OUT, W, cs, pattern, from);
}
}
#line 17 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
#line 19 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
weave_plugin *Assets__new(text_stream *name) {
weave_plugin *wp;
LOOP_OVER(wp, weave_plugin)
if (Str__eq_insensitive(wp->plugin_name, name))
return wp;
wp = CREATE(weave_plugin);
wp->plugin_name = Str__duplicate(name);
wp->last_included_in_round = 0;
return wp;
}
#line 41 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
#line 43 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
colour_scheme *Assets__find_colour_scheme(weave_pattern *pattern,
text_stream *name, text_stream *pre) {
colour_scheme *cs;
LOOP_OVER(cs, colour_scheme)
if (Str__eq_insensitive(cs->scheme_name, name))
return cs;
TEMPORARY_TEXT(css)
WRITE_TO(css, "%S.css", name);
filename *F = Patterns__find_file_in_subdirectory(pattern, TL_IS_189, css);
if (F == NULL) F = Patterns__find_file_in_subdirectory(pattern, TL_IS_190, css);
DISCARD_TEXT(css)
if (F == NULL) return NULL;
cs = CREATE(colour_scheme);
cs->scheme_name = Str__duplicate(name);
cs->at = F;
cs->prefix = Str__duplicate(pre);
cs->last_included_in_round = 0;
if (Str__len(pre) > 0) WRITE_TO(cs->prefix, "-");
return cs;
}
#line 70 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
int current_inclusion_round = 0;
void Assets__include_relevant_plugins(text_stream *OUT, weave_pattern *pattern,
web *W, weave_order *wv, filename *from) {
current_inclusion_round++;
STREAM_INDENT(STDOUT);
Patterns__include_plugins(OUT, W, pattern, from);
if (wv) Swarm__include_plugins(OUT, W, wv, from);
STREAM_OUTDENT(STDOUT);
}
#line 94 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__include_plugin(OUTPUT_STREAM, web *W, weave_plugin *wp,
weave_pattern *pattern, filename *from) {
if (wp->last_included_in_round == current_inclusion_round) return;
wp->last_included_in_round = current_inclusion_round;
if (verbose_mode) PRINT("Include plugin '%S'\n", wp->plugin_name);
int finds = 0;
dictionary *leaves_gathered = Dictionaries__new(128, TRUE);
for (weave_pattern *p = pattern; p; p = p->based_on) {
pathname *P = Pathnames__down(p->pattern_location, wp->plugin_name);
scan_directory *D = Directories__open(P);
if (D) {
TEMPORARY_TEXT(leafname)
while (Directories__next(D, leafname)) {
if ((Platform__is_folder_separator(Str__get_last_char(leafname)) == FALSE) &&
(Str__get_first_char(leafname) != '.')) {
if (Dictionaries__find(leaves_gathered, leafname) == NULL) {
WRITE_TO(Dictionaries__create_text(leaves_gathered, leafname), "y");
filename *F = Filenames__in(P, leafname);
Assets__include_asset(OUT, NULL, W, F, NULL, pattern, from);
finds++;
}
}
}
DISCARD_TEXT(leafname)
Directories__close(D);
}
}
if (finds == 0) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "The plugin '%S' is not supported", wp->plugin_name);
Main__error_in_web(err, NULL);
}
}
#line 135 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__include_colour_scheme(OUTPUT_STREAM, web *W, colour_scheme *cs,
weave_pattern *pattern, filename *from) {
if (cs->last_included_in_round == current_inclusion_round) return;
cs->last_included_in_round = current_inclusion_round;
if (verbose_mode) PRINT("Include colour scheme '%S'\n", cs->scheme_name);
TEMPORARY_TEXT(css)
WRITE_TO(css, "%S.css", cs->scheme_name);
filename *F = Patterns__find_file_in_subdirectory(pattern, TL_IS_191, css);
if (F == NULL) F = Patterns__find_file_in_subdirectory(pattern, TL_IS_192, css);
if (F == NULL) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "No CSS file for the colour scheme '%S' can be found",
cs->scheme_name);
Main__error_in_web(err, NULL);
DISCARD_TEXT(err)
} else {
Assets__include_asset(OUT, NULL, W, F, cs->prefix, pattern, from);
}
DISCARD_TEXT(css)
}
#line 166 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
#line 176 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
#line 184 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
linked_list *Assets__new_asset_rules_list(void) {
linked_list *L = NEW_LINKED_LIST(asset_rule);
Assets__add_asset_rule(L, TL_IS_193, TL_IS_194, NULL);
return L;
}
#line 194 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__add_asset_rule(linked_list *L, text_stream *ext, text_stream *line,
text_file_position *tfp) {
asset_rule *R = Assets__new_rule(L, ext, line, tfp);
ADD_TO_LINKED_LIST(R, asset_rule, L);
}
asset_rule *Assets__new_rule(linked_list *L, text_stream *ext, text_stream *line,
text_file_position *tfp) {
asset_rule *R;
if (L)
LOOP_OVER_LINKED_LIST(R, asset_rule, L)
if (Str__eq_insensitive(R->applies_to, ext)) {
{
#line 223 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
text_stream *cmd = line;
text_stream *detail = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+?) *= *(%c*)")) {
cmd = mr.exp[0];
detail = mr.exp[1];
}
if (Str__eq(cmd, TL_IS_195)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 231 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = COPY_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_196)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 233 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = PRIVATE_COPY_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_197)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 235 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = EMBED_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_198)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 237 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = COLLATE_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_199)) {
R->pre = Str__duplicate(detail);
} else if (Str__eq(cmd, TL_IS_200)) {
R->post = Str__duplicate(detail);
} else if (Str__eq(cmd, TL_IS_201)) {
R->transform_names = TRUE;
} else Errors__in_text_file("no such asset command", tfp);
Regexp__dispose_of(&mr);
}
#line 206 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
;
return R;
}
R = CREATE(asset_rule);
R->applies_to = Str__duplicate(ext);
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 211 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
;
{
#line 223 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
text_stream *cmd = line;
text_stream *detail = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+?) *= *(%c*)")) {
cmd = mr.exp[0];
detail = mr.exp[1];
}
if (Str__eq(cmd, TL_IS_195)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 231 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = COPY_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_196)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 233 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = PRIVATE_COPY_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_197)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 235 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = EMBED_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_198)) {
{
#line 217 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
R->method = COPY_ASSET_METHOD;
R->pre = Str__new();
R->post = Str__new();
R->transform_names = FALSE;
}
#line 237 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; R->method = COLLATE_ASSET_METHOD;
} else if (Str__eq(cmd, TL_IS_199)) {
R->pre = Str__duplicate(detail);
} else if (Str__eq(cmd, TL_IS_200)) {
R->post = Str__duplicate(detail);
} else if (Str__eq(cmd, TL_IS_201)) {
R->transform_names = TRUE;
} else Errors__in_text_file("no such asset command", tfp);
Regexp__dispose_of(&mr);
}
#line 212 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
;
return R;
}
#line 252 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
asset_rule *Assets__applicable_rule(weave_pattern *pattern, filename *F) {
TEMPORARY_TEXT(ext)
Filenames__write_extension(ext, F);
for (weave_pattern *p = pattern; p; p = p->based_on) {
asset_rule *R;
LOOP_OVER_LINKED_LIST(R, asset_rule, p->asset_rules)
if (Str__eq_insensitive(R->applies_to, ext))
return R;
}
asset_rule *R;
LOOP_OVER_LINKED_LIST(R, asset_rule, pattern->asset_rules)
if (Str__eq_insensitive(R->applies_to, TL_IS_202))
return R;
internal_error("no default asset rule");
return NULL;
}
#line 274 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
pathname *Assets__include_asset(OUTPUT_STREAM, asset_rule *R, web *W, filename *F,
text_stream *trans, weave_pattern *pattern, filename *from) {
if (R == NULL) R = Assets__applicable_rule(pattern, F);
TEMPORARY_TEXT(url)
pathname *AP = Colonies__assets_path();
if (AP) Pathnames__relative_URL(url, Filenames__up(from), AP);
WRITE_TO(url, "%S", Filenames__get_leafname(F));
if (R->transform_names == FALSE) trans = NULL;
pathname *result = NULL;
if (Str__len(R->pre) > 0)
{
#line 296 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
for (int i=0; i<Str__len(R->pre); i++) {
if (Str__includes_at(R->pre, i, TL_IS_203)) {
WRITE("%S", url);
i += 2;
} else PUT(Str__get_at(R->pre, i));
}
WRITE("\n");
}
#line 283 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
;
switch (R->method) {
case EMBED_ASSET_METHOD:
{
#line 305 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
if (verbose_mode) PRINT("Embed asset %f\n", F);
Assets__transform(OUT, F, trans);
}
#line 285 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; break;
case COPY_ASSET_METHOD:
{
#line 309 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
pathname *H = W->redirect_weaves_to;
if (H == NULL) H = Reader__woven_folder(W);
if ((AP) && (R->method != PRIVATE_COPY_ASSET_METHOD)) H = AP;
if (verbose_mode) PRINT("Copy asset %f -> %p\n", F, H);
if (Str__len(trans) > 0) {
text_stream css_S;
filename *G = Filenames__in(H, Filenames__get_leafname(F));
if (STREAM_OPEN_TO_FILE(&css_S, G, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to write tangled file", F);
Assets__transform(&css_S, F, trans);
STREAM_CLOSE(&css_S);
} else {
Shell__copy(F, H, "");
result = H;
}
if (W->as_ebook) {
filename *rel = Filenames__in(NULL, Filenames__get_leafname(F));
Epub__note_image(W->as_ebook, rel);
}
}
#line 286 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; break;
case PRIVATE_COPY_ASSET_METHOD:
{
#line 309 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
pathname *H = W->redirect_weaves_to;
if (H == NULL) H = Reader__woven_folder(W);
if ((AP) && (R->method != PRIVATE_COPY_ASSET_METHOD)) H = AP;
if (verbose_mode) PRINT("Copy asset %f -> %p\n", F, H);
if (Str__len(trans) > 0) {
text_stream css_S;
filename *G = Filenames__in(H, Filenames__get_leafname(F));
if (STREAM_OPEN_TO_FILE(&css_S, G, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to write tangled file", F);
Assets__transform(&css_S, F, trans);
STREAM_CLOSE(&css_S);
} else {
Shell__copy(F, H, "");
result = H;
}
if (W->as_ebook) {
filename *rel = Filenames__in(NULL, Filenames__get_leafname(F));
Epub__note_image(W->as_ebook, rel);
}
}
#line 287 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; break;
case COLLATE_ASSET_METHOD:
{
#line 330 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
if (verbose_mode) PRINT("Collate asset %f\n", F);
Collater__for_web_and_pattern(OUT, W, pattern, F, from);
}
#line 288 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
; break;
}
if (Str__len(R->post) > 0)
{
#line 334 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
for (int i=0; i<Str__len(R->post); i++) {
if (Str__includes_at(R->post, i, TL_IS_204)) {
WRITE("%S", url);
i += 2;
} else PUT(Str__get_at(R->post, i));
}
WRITE("\n");
}
#line 290 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
;
DISCARD_TEXT(url)
return result;
}
#line 352 "inweb/Chapter 1/Assets, Plugins and Colour Schemes.w"
void Assets__transform(text_stream *OUT, filename *F, text_stream *trans) {
css_file_transformation cft;
cft.OUT = OUT;
cft.trans = trans;
TextFiles__read(F, FALSE, "can't open file", TRUE,
Assets__transformer, NULL, (void *) &cft);
}
void Assets__transformer(text_stream *line, text_file_position *tfp, void *X) {
css_file_transformation *cft = (css_file_transformation *) X;
text_stream *OUT = cft->OUT;
match_results mr = Regexp__create_mr();
TEMPORARY_TEXT(spanned)
while (Regexp__match(&mr, line, L"(%c*?span.)(%i+)(%c*?)")) {
WRITE_TO(spanned, "%S%S%S", mr.exp[0], cft->trans, mr.exp[1]);
Str__clear(line); Str__copy(line, mr.exp[2]);
}
WRITE_TO(spanned, "%S\n", line);
while (Regexp__match(&mr, spanned, L"(%c*?pre.)(%i+)(%c*?)")) {
WRITE("%S%S%S", mr.exp[0], cft->trans, mr.exp[1]);
Str__clear(spanned); Str__copy(spanned, mr.exp[2]);
}
WRITE("%S", spanned);
DISCARD_TEXT(spanned)
Regexp__dispose_of(&mr);
}
#line 47 "inweb/Chapter 2/The Reader.w"
#line 61 "inweb/Chapter 2/The Reader.w"
#line 92 "inweb/Chapter 2/The Reader.w"
#line 97 "inweb/Chapter 2/The Reader.w"
web_md *Reader__load_web_md(pathname *P, filename *alt_F, module_search *I,
int including_modules) {
return WebMetadata__get(P, alt_F, default_inweb_syntax, I, verbose_mode,
including_modules, path_to_inweb);
}
web *Reader__load_web(pathname *P, filename *alt_F, module_search *I,
int including_modules) {
web *W = CREATE(web);
W->md = Reader__load_web_md(P, alt_F, I, including_modules);
tangle_target *main_target = NULL;
{
#line 134 "inweb/Chapter 2/The Reader.w"
TEMPORARY_TEXT(IB)
WRITE_TO(IB, "7.2.0");
web_bibliographic_datum *bd = Bibliographic__set_datum(W->md, TL_IS_205, IB);
bd->declaration_permitted = FALSE;
DISCARD_TEXT(IB)
}
#line 110 "inweb/Chapter 2/The Reader.w"
;
{
#line 141 "inweb/Chapter 2/The Reader.w"
W->chapters = NEW_LINKED_LIST(chapter);
W->headers = NEW_LINKED_LIST(filename);
W->language_types = NEW_LINKED_LIST(language_type);
W->tangle_targets = NEW_LINKED_LIST(tangle_target);
W->analysed = FALSE;
W->as_ebook = NULL;
W->redirect_weaves_to = NULL;
W->main_language = Languages__default(W);
W->web_extent = 0; W->no_paragraphs = 0;
text_stream *language_name = Bibliographic__get_datum(W->md, TL_IS_206);
if (Str__len(language_name) > 0)
W->main_language = Languages__find_by_name(language_name, W, TRUE);
main_target = Reader__add_tangle_target(W, W->main_language);
}
#line 111 "inweb/Chapter 2/The Reader.w"
;
chapter_md *Cm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, W->md->chapters_md) {
chapter *C = CREATE(chapter);
C->md = Cm;
C->owning_web = W;
{
#line 156 "inweb/Chapter 2/The Reader.w"
C->ch_weave = NULL;
C->titling_line_inserted = FALSE;
C->sections = NEW_LINKED_LIST(section);
C->ch_language = W->main_language;
if (Str__len(Cm->ch_language_name) > 0)
C->ch_language = Languages__find_by_name(Cm->ch_language_name, W, TRUE);
}
#line 117 "inweb/Chapter 2/The Reader.w"
;
ADD_TO_LINKED_LIST(C, chapter, W->chapters);
section_md *Sm;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) {
section *S = CREATE(section);
S->md = Sm;
S->owning_chapter = C;
S->owning_web = W;
{
#line 164 "inweb/Chapter 2/The Reader.w"
S->sect_extent = 0;
S->first_line = NULL; S->last_line = NULL;
S->sect_paragraphs = 0;
S->paragraphs = NEW_LINKED_LIST(paragraph);
S->macros = NEW_LINKED_LIST(para_macro);
S->scratch_flag = FALSE;
S->barred = FALSE;
S->printed_number = -1;
S->sect_weave = NULL;
S->sect_namespace = Str__new();
S->owning_web = W;
S->sect_language = C->ch_language;
if (Str__len(S->md->sect_language_name) > 0)
S->sect_language = Languages__find_by_name(S->md->sect_language_name, W, TRUE);
if (Str__len(S->md->sect_independent_language) > 0) {
programming_language *pl =
Languages__find_by_name(S->md->sect_independent_language, W, TRUE);
S->sect_language = pl;
S->sect_target = Reader__add_tangle_target(W, pl);
} else {
S->sect_target = main_target;
}
S->tag_with = NULL;
if (Str__len(Sm->tag_name) > 0)
S->tag_with = Tags__add_by_name(NULL, Sm->tag_name);
}
#line 125 "inweb/Chapter 2/The Reader.w"
;
ADD_TO_LINKED_LIST(S, section, C->sections);
}
}
{
#line 192 "inweb/Chapter 2/The Reader.w"
filename *HF;
LOOP_OVER_LINKED_LIST(HF, filename, W->md->header_filenames)
Reader__add_imported_header(W, HF);
}
#line 129 "inweb/Chapter 2/The Reader.w"
;
return W;
}
#line 205 "inweb/Chapter 2/The Reader.w"
void Reader__read_web(web *W) {
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
Reader__read_file(W, C,
S->md->source_file_for_section,
S->md->titling_line_to_insert, S,
(W->md->single_file)?TRUE:FALSE);
}
#line 219 "inweb/Chapter 2/The Reader.w"
void Reader__read_file(web *W, chapter *C, filename *F, text_stream *titling_line,
section *S, int disregard_top) {
S->owning_chapter = C;
if (disregard_top)
S->paused_until_at = TRUE;
else
S->paused_until_at = FALSE;
if ((titling_line) && (Str__len(titling_line) > 0) &&
(S->owning_chapter->titling_line_inserted == FALSE))
{
#line 240 "inweb/Chapter 2/The Reader.w"
S->owning_chapter->titling_line_inserted = TRUE;
TEMPORARY_TEXT(line)
text_file_position *tfp = NULL;
WRITE_TO(line, "Chapter Heading");
{
#line 282 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 244 "inweb/Chapter 2/The Reader.w"
;
DISCARD_TEXT(line)
}
#line 229 "inweb/Chapter 2/The Reader.w"
;
if (disregard_top)
{
#line 248 "inweb/Chapter 2/The Reader.w"
TEMPORARY_TEXT(line)
text_file_position *tfp = NULL;
WRITE_TO(line, "Main.");
{
#line 282 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 251 "inweb/Chapter 2/The Reader.w"
;
Str__clear(line);
{
#line 282 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 253 "inweb/Chapter 2/The Reader.w"
;
text_stream *purpose = Bibliographic__get_datum(W->md, TL_IS_207);
if (Str__len(purpose) > 0) {
Str__clear(line);
WRITE_TO(line, "Implied Purpose: %S", purpose);
{
#line 282 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 258 "inweb/Chapter 2/The Reader.w"
;
Str__clear(line);
{
#line 282 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 260 "inweb/Chapter 2/The Reader.w"
;
}
DISCARD_TEXT(line)
}
#line 232 "inweb/Chapter 2/The Reader.w"
;
int cl = TextFiles__read(F, FALSE, "can't open section file", TRUE,
Reader__scan_source_line, NULL, (void *) S);
if (verbose_mode) PRINT("Read section: '%S' (%d lines)\n", S->md->sect_title, cl);
}
#line 269 "inweb/Chapter 2/The Reader.w"
void Reader__scan_source_line(text_stream *line, text_file_position *tfp, void *state) {
section *S = (section *) state;
int l = Str__len(line) - 1;
while ((l>=0) && (Characters__is_space_or_tab(Str__get_at(line, l))))
Str__truncate(line, l--);
if (S->paused_until_at) {
if (Str__get_at(line, 0) == '@') S->paused_until_at = FALSE;
else return;
}
{
#line 282 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 278 "inweb/Chapter 2/The Reader.w"
;
}
#line 296 "inweb/Chapter 2/The Reader.w"
pathname *Reader__woven_folder(web *W) {
pathname *P = Pathnames__down(W->md->path_to_web, TL_IS_208);
if (Pathnames__create_in_file_system(P) == FALSE)
Errors__fatal_with_path("unable to create Woven subdirectory", P);
return P;
}
pathname *Reader__tangled_folder(web *W) {
pathname *P = Pathnames__down(W->md->path_to_web, TL_IS_209);
if (Pathnames__create_in_file_system(P) == FALSE)
Errors__fatal_with_path("unable to create Tangled subdirectory", P);
return P;
}
#line 317 "inweb/Chapter 2/The Reader.w"
chapter *Reader__get_chapter_for_range(web *W, text_stream *range) {
chapter *C;
if (W)
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
if (Str__eq(C->md->ch_range, range))
return C;
return NULL;
}
section *Reader__get_section_for_range(web *W, text_stream *range) {
chapter *C;
section *S;
if (W)
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Str__eq(S->md->sect_range, range))
return S;
return NULL;
}
#line 340 "inweb/Chapter 2/The Reader.w"
section *Reader__section_by_filename(web *W, text_stream *filename) {
chapter *C;
section *S;
if (W)
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
TEMPORARY_TEXT(SFN)
WRITE_TO(SFN, "%f", S->md->source_file_for_section);
int rv = Str__eq(SFN, filename);
DISCARD_TEXT(SFN)
if (rv) return S;
}
return NULL;
}
#line 362 "inweb/Chapter 2/The Reader.w"
int Reader__range_within(text_stream *range1, text_stream *range2) {
if (Str__eq_wide_string(range2, L"0")) return TRUE;
if (Str__eq(range1, range2)) return TRUE;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, range2, L"%c+/%c+")) { Regexp__dispose_of(&mr); return FALSE; }
if (Regexp__match(&mr, range1, L"(%c+)/%c+")) {
if (Str__eq(mr.exp[0], range2)) { Regexp__dispose_of(&mr); return TRUE; }
}
return FALSE;
}
#line 389 "inweb/Chapter 2/The Reader.w"
#line 391 "inweb/Chapter 2/The Reader.w"
tangle_target *Reader__add_tangle_target(web *W, programming_language *language) {
tangle_target *tt = CREATE(tangle_target);
tt->tangle_language = language;
Analyser__initialise_hash_table(&(tt->symbols));
ADD_TO_LINKED_LIST(tt, tangle_target, W->tangle_targets);
return tt;
}
#line 415 "inweb/Chapter 2/The Reader.w"
void Reader__add_imported_header(web *W, filename *HF) {
ADD_TO_LINKED_LIST(HF, filename, W->headers);
}
#line 422 "inweb/Chapter 2/The Reader.w"
int Reader__web_has_one_section(web *W) {
if (WebMetadata__section_count(W->md) == 1) return TRUE;
return FALSE;
}
#line 430 "inweb/Chapter 2/The Reader.w"
void Reader__print_web_statistics(web *W) {
PRINT("web \"%S\": ", Bibliographic__get_datum(W->md, TL_IS_210));
int c = WebMetadata__chapter_count(W->md);
int s = WebMetadata__section_count(W->md);
if (W->md->chaptered) PRINT("%d chapter%s : ",
c, (c == 1)?"":"s");
PRINT("%d section%s : %d paragraph%s : %d line%s\n",
s, (s == 1)?"":"s",
W->no_paragraphs, (W->no_paragraphs == 1)?"":"s",
W->web_extent, (W->web_extent == 1)?"":"s");
}
#line 45 "inweb/Chapter 2/Line Categories.w"
#line 47 "inweb/Chapter 2/Line Categories.w"
source_line *Lines__new_source_line_in(text_stream *line, text_file_position *tfp,
section *S) {
source_line *sl = CREATE(source_line);
sl->text = Str__duplicate(line);
sl->text_operand = Str__new();
sl->text_operand2 = Str__new();
sl->category = NO_LCAT; /* that is, unknown category as yet */
sl->command_code = NO_CMD;
sl->default_defn = FALSE;
sl->plainer = FALSE;
sl->enable_hyperlinks = FALSE;
sl->colour_as = NULL;
sl->extract_to = NULL;
sl->is_commentary = FALSE;
sl->function_defined = NULL;
sl->preform_nonterminal_defined = NULL;
sl->suppress_tangling = FALSE;
sl->interface_line_identified = FALSE;
sl->footnote_text = NULL;
if (tfp) sl->source = *tfp; else sl->source = TextFiles__nowhere();
sl->owning_section = S;
sl->owning_section->sect_extent++;
sl->owning_section->owning_chapter->owning_web->web_extent++;
sl->next_line = NULL;
sl->owning_paragraph = NULL;
return sl;
}
#line 87 "inweb/Chapter 2/Line Categories.w"
#line 113 "inweb/Chapter 2/Line Categories.w"
#line 118 "inweb/Chapter 2/Line Categories.w"
char *Lines__category_name(int cat) {
switch (cat) {
case NO_LCAT: return "(uncategorised)";
case BAR_LCAT: return "BAR";
case BEGIN_CODE_LCAT: return "BEGIN_CODE";
case BEGIN_DEFINITION_LCAT: return "BEGIN_DEFINITION";
case C_LIBRARY_INCLUDE_LCAT: return "C_LIBRARY_INCLUDE";
case CHAPTER_HEADING_LCAT: return "CHAPTER_HEADING";
case CODE_BODY_LCAT: return "CODE_BODY";
case COMMAND_LCAT: return "COMMAND";
case COMMENT_BODY_LCAT: return "COMMENT_BODY";
case CONT_DEFINITION_LCAT: return "CONT_DEFINITION";
case DEFINITIONS_LCAT: return "DEFINITIONS";
case END_EXTRACT_LCAT: return "END_EXTRACT";
case FOOTNOTE_TEXT_LCAT: return "FOOTNOTE_TEXT";
case HEADING_START_LCAT: return "HEADING_START";
case INTERFACE_BODY_LCAT: return "INTERFACE_BODY";
case INTERFACE_LCAT: return "INTERFACE";
case MACRO_DEFINITION_LCAT: return "MACRO_DEFINITION";
case PARAGRAPH_START_LCAT: return "PARAGRAPH_START";
case PREFORM_GRAMMAR_LCAT: return "PREFORM_GRAMMAR";
case PREFORM_LCAT: return "PREFORM";
case PURPOSE_BODY_LCAT: return "PURPOSE_BODY";
case PURPOSE_LCAT: return "PURPOSE";
case SECTION_HEADING_LCAT: return "SECTION_HEADING";
case SOURCE_DISPLAY_LCAT: return "SOURCE_DISPLAY";
case TEXT_EXTRACT_LCAT: return "TEXT_EXTRACT";
case TYPEDEF_LCAT: return "TYPEDEF";
}
return "(?unknown)";
}
#line 170 "inweb/Chapter 2/Line Categories.w"
#line 17 "inweb/Chapter 2/The Parser.w"
void Parser__parse_web(web *W, int inweb_mode) {
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
{
#line 34 "inweb/Chapter 2/The Parser.w"
int comment_mode = TRUE, extract_mode = FALSE;
int code_lcat_for_body = NO_LCAT,
code_plainness_for_body = FALSE,
hyperlink_body = FALSE;
programming_language *code_pl_for_body = NULL;
text_stream *code_destination = NULL;
int before_bar = TRUE;
int next_par_number = 1;
paragraph *current_paragraph = NULL;
TEMPORARY_TEXT(tag_list)
for (source_line *L = S->first_line, *PL = NULL; L; PL = L, L = L->next_line) {
{
#line 80 "inweb/Chapter 2/The Parser.w"
match_results mr = Regexp__create_mr();
while (Regexp__match(&mr, tag_list, L" *%^\"(%c+?)\" *(%c*)")) {
Tags__add_by_name(current_paragraph, mr.exp[0]);
Str__copy(tag_list, mr.exp[1]);
}
Regexp__dispose_of(&mr);
Str__clear(tag_list);
}
#line 45 "inweb/Chapter 2/The Parser.w"
;
{
#line 64 "inweb/Chapter 2/The Parser.w"
if (Str__get_first_char(L->text) == '@') {
match_results mr = Regexp__create_mr();
while (Regexp__match(&mr, L->text, L"(%c*?)( *%^\"%c+?\")(%c*)")) {
if (S->md->using_syntax < V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "tags written ^\"thus\"", V2_SYNTAX);
Str__clear(L->text);
WRITE_TO(tag_list, "%S", mr.exp[1]);
Str__copy(L->text, mr.exp[0]); WRITE_TO(L->text, " %S", mr.exp[2]);
}
Regexp__dispose_of(&mr);
}
}
#line 46 "inweb/Chapter 2/The Parser.w"
;
{
#line 121 "inweb/Chapter 2/The Parser.w"
match_results mr = Regexp__create_mr();
if ((PL) && (PL->category == CODE_BODY_LCAT) &&
(Str__get_first_char(L->text) == '@') && (Str__get_at(L->text, 1) == '<') &&
(Regexp__match(&mr, L->text, L"%c<(%c+)@> *= *")) &&
(S->md->using_syntax >= V2_SYNTAX)) {
{
#line 141 "inweb/Chapter 2/The Parser.w"
source_line *NL = Lines__new_source_line_in(TL_IS_213, &(L->source), S);
PL->next_line = NL;
NL->next_line = L;
L = PL;
Regexp__dispose_of(&mr);
continue;
}
#line 126 "inweb/Chapter 2/The Parser.w"
;
}
if ((PL) && (Regexp__match(&mr, L->text, L"@ *= *"))) {
Str__clear(L->text);
Str__copy(L->text, TL_IS_212);
if (S->md->using_syntax < V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "implied paragraph breaks", V2_SYNTAX);
{
#line 141 "inweb/Chapter 2/The Parser.w"
source_line *NL = Lines__new_source_line_in(TL_IS_213, &(L->source), S);
PL->next_line = NL;
NL->next_line = L;
L = PL;
Regexp__dispose_of(&mr);
continue;
}
#line 133 "inweb/Chapter 2/The Parser.w"
;
}
Regexp__dispose_of(&mr);
}
#line 47 "inweb/Chapter 2/The Parser.w"
;
{
#line 153 "inweb/Chapter 2/The Parser.w"
L->is_commentary = comment_mode;
L->category = COMMENT_BODY_LCAT; /* until set otherwise down below */
L->owning_paragraph = current_paragraph;
if (L->source.line_count == 0)
{
#line 180 "inweb/Chapter 2/The Parser.w"
if (Str__eq_wide_string(L->text, L"Chapter Heading")) {
comment_mode = TRUE;
extract_mode = FALSE;
L->is_commentary = TRUE;
L->category = CHAPTER_HEADING_LCAT;
L->owning_paragraph = NULL;
}
}
#line 157 "inweb/Chapter 2/The Parser.w"
;
if (L->source.line_count <= 1)
{
#line 192 "inweb/Chapter 2/The Parser.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"Implied Purpose: (%c+)")) {
S->sect_purpose = Str__duplicate(mr.exp[0]);
if (Str__len(S->sect_purpose) > 0) {
L->category = PURPOSE_LCAT;
L->is_commentary = TRUE;
}
} else if (Regexp__match(&mr, L->text, L"%[(%C+)%] (%C+/%C+): (%c+).")) {
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L,
"section range in header line", V1_SYNTAX);
S->sect_namespace = Str__duplicate(mr.exp[0]);
S->md->sect_range = Str__duplicate(mr.exp[1]);
S->md->sect_title = Str__duplicate(mr.exp[2]);
L->text_operand = Str__duplicate(mr.exp[2]);
L->category = SECTION_HEADING_LCAT;
L->owning_paragraph = NULL;
} else if (Regexp__match(&mr, L->text, L"(%C+/%C+): (%c+).")) {
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L,
"section range in header line", V1_SYNTAX);
S->md->sect_range = Str__duplicate(mr.exp[0]);
S->md->sect_title = Str__duplicate(mr.exp[1]);
L->text_operand = Str__duplicate(mr.exp[1]);
L->category = SECTION_HEADING_LCAT;
L->owning_paragraph = NULL;
} else if (Regexp__match(&mr, L->text, L"%[(%C+::)%] (%c+).")) {
S->sect_namespace = Str__duplicate(mr.exp[0]);
S->md->sect_title = Str__duplicate(mr.exp[1]);
L->text_operand = Str__duplicate(mr.exp[1]);
L->category = SECTION_HEADING_LCAT;
L->owning_paragraph = NULL;
} else if (Regexp__match(&mr, L->text, L"(%c+).")) {
S->md->sect_title = Str__duplicate(mr.exp[0]);
L->text_operand = Str__duplicate(mr.exp[0]);
L->category = SECTION_HEADING_LCAT;
L->owning_paragraph = NULL;
}
Regexp__dispose_of(&mr);
}
#line 158 "inweb/Chapter 2/The Parser.w"
;
if (extract_mode == FALSE) {
{
#line 237 "inweb/Chapter 2/The Parser.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"%[%[(%c+)%]%]")) {
TEMPORARY_TEXT(full_command)
TEMPORARY_TEXT(command_text)
Str__copy(full_command, mr.exp[0]);
Str__copy(command_text, mr.exp[0]);
L->category = COMMAND_LCAT;
if (Regexp__match(&mr, command_text, L"(%c+?): *(%c+)")) {
Str__copy(command_text, mr.exp[0]);
L->text_operand = Str__duplicate(mr.exp[1]);
}
if (Str__eq_wide_string(command_text, L"Page Break")) {
if (S->md->using_syntax > V1_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "[[Page Break]]", V1_SYNTAX);
L->command_code = PAGEBREAK_CMD;
} else if (Str__eq_wide_string(command_text, L"Grammar Index"))
L->command_code = GRAMMAR_INDEX_CMD;
else if (Str__eq_wide_string(command_text, L"Tag")) {
if (S->md->using_syntax > V1_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "[[Tag...]]", V1_SYNTAX);
Tags__add_by_name(L->owning_paragraph, L->text_operand);
L->command_code = TAG_CMD;
} else if (Str__eq_wide_string(command_text, L"Figure")) {
if (S->md->using_syntax > V1_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "[[Figure...]]", V1_SYNTAX);
Tags__add_by_name(L->owning_paragraph, TL_IS_214);
L->command_code = FIGURE_CMD;
} else {
Main__error_in_web(TL_IS_215, L);
}
L->is_commentary = TRUE;
DISCARD_TEXT(command_text)
DISCARD_TEXT(full_command)
}
Regexp__dispose_of(&mr);
}
#line 160 "inweb/Chapter 2/The Parser.w"
;
{
#line 277 "inweb/Chapter 2/The Parser.w"
match_results mr = Regexp__create_mr();
if ((Str__get_first_char(L->text) == '@') && (Str__get_at(L->text, 1) == '<') &&
(Regexp__match(&mr, L->text, L"%c<(%c+)@> *= *"))) {
TEMPORARY_TEXT(para_macro_name)
Str__copy(para_macro_name, mr.exp[0]);
L->category = MACRO_DEFINITION_LCAT;
if (current_paragraph == NULL)
Main__error_in_web(TL_IS_216, L);
else Macros__create(S, current_paragraph, L, para_macro_name);
comment_mode = FALSE; extract_mode = FALSE;
L->is_commentary = FALSE;
code_lcat_for_body = CODE_BODY_LCAT; /* code follows on subsequent lines */
code_pl_for_body = NULL;
code_plainness_for_body = FALSE;
hyperlink_body = FALSE;
DISCARD_TEXT(para_macro_name)
continue;
}
Regexp__dispose_of(&mr);
}
#line 161 "inweb/Chapter 2/The Parser.w"
;
}
if (Str__get_first_char(L->text) == '=') {
if (S->md->using_syntax < V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "column-1 '=' as code divider", V2_SYNTAX);
if (extract_mode)
{
#line 319 "inweb/Chapter 2/The Parser.w"
L->category = END_EXTRACT_LCAT;
comment_mode = TRUE;
extract_mode = FALSE;
}
#line 166 "inweb/Chapter 2/The Parser.w"
else
{
#line 326 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
L->plainer = FALSE;
code_lcat_for_body = CODE_BODY_LCAT;
code_destination = NULL;
code_pl_for_body = NULL;
comment_mode = FALSE;
match_results mr = Regexp__create_mr();
match_results mr2 = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"= *(%c+) *")) {
if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_217))) {
current_paragraph->placed_very_early = TRUE;
} else if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_218))) {
current_paragraph->placed_early = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text%)"))) {
{
#line 494 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_234)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_235)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_236, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 341 "inweb/Chapter 2/The Parser.w"
;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
code_destination = NULL;
code_pl_for_body = NULL;
extract_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text to *(%c+)%)"))) {
{
#line 494 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_234)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_235)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_236, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 348 "inweb/Chapter 2/The Parser.w"
;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
code_destination = Str__duplicate(mr2.exp[1]);
code_pl_for_body = Languages__find_by_name(TL_IS_219, W, TRUE);
extract_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text as code%)"))) {
{
#line 494 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_234)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_235)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_236, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 355 "inweb/Chapter 2/The Parser.w"
;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
code_destination = NULL;
code_pl_for_body = S->sect_language;
extract_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text as (%c+)%)"))) {
{
#line 494 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_234)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_235)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_236, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 362 "inweb/Chapter 2/The Parser.w"
;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
code_destination = NULL;
code_pl_for_body = Languages__find_by_name(mr2.exp[1], W, TRUE);
extract_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text from (%c+) as code%)"))) {
{
#line 494 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_234)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_235)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_236, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 369 "inweb/Chapter 2/The Parser.w"
;
code_pl_for_body = S->sect_language;
{
#line 510 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
pathname *P = W->md->path_to_web;
if ((S->md->owning_module) && (S->md->owning_module->module_location))
P = S->md->owning_module->module_location; /* references are relative to module */
filename *F = Filenames__from_text_relative(P, mr2.exp[1]);
linked_list *lines = Painter__lines(F);
text_stream *T;
source_line *latest = L;
LOOP_OVER_LINKED_LIST(T, text_stream, lines) {
source_line *TL = Lines__new_source_line_in(T, &(L->source), S);
TL->next_line = latest->next_line;
TL->plainer = L->plainer;
latest->next_line = TL;
latest = TL;
}
source_line *EEL = Lines__new_source_line_in(TL_IS_237, &(L->source), S);
EEL->next_line = latest->next_line;
latest->next_line = EEL;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
extract_mode = TRUE;
}
#line 371 "inweb/Chapter 2/The Parser.w"
;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text from (%c+) as (%c+)%)"))) {
{
#line 494 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_234)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_235)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_236, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 374 "inweb/Chapter 2/The Parser.w"
;
code_pl_for_body = Languages__find_by_name(mr2.exp[2], W, TRUE);
{
#line 510 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
pathname *P = W->md->path_to_web;
if ((S->md->owning_module) && (S->md->owning_module->module_location))
P = S->md->owning_module->module_location; /* references are relative to module */
filename *F = Filenames__from_text_relative(P, mr2.exp[1]);
linked_list *lines = Painter__lines(F);
text_stream *T;
source_line *latest = L;
LOOP_OVER_LINKED_LIST(T, text_stream, lines) {
source_line *TL = Lines__new_source_line_in(T, &(L->source), S);
TL->next_line = latest->next_line;
TL->plainer = L->plainer;
latest->next_line = TL;
latest = TL;
}
source_line *EEL = Lines__new_source_line_in(TL_IS_237, &(L->source), S);
EEL->next_line = latest->next_line;
latest->next_line = EEL;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
extract_mode = TRUE;
}
#line 376 "inweb/Chapter 2/The Parser.w"
;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text from (%c+)%)"))) {
{
#line 494 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_234)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_235)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_236, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 379 "inweb/Chapter 2/The Parser.w"
;
code_pl_for_body = NULL;
{
#line 510 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
pathname *P = W->md->path_to_web;
if ((S->md->owning_module) && (S->md->owning_module->module_location))
P = S->md->owning_module->module_location; /* references are relative to module */
filename *F = Filenames__from_text_relative(P, mr2.exp[1]);
linked_list *lines = Painter__lines(F);
text_stream *T;
source_line *latest = L;
LOOP_OVER_LINKED_LIST(T, text_stream, lines) {
source_line *TL = Lines__new_source_line_in(T, &(L->source), S);
TL->next_line = latest->next_line;
TL->plainer = L->plainer;
latest->next_line = TL;
latest = TL;
}
source_line *EEL = Lines__new_source_line_in(TL_IS_237, &(L->source), S);
EEL->next_line = latest->next_line;
latest->next_line = EEL;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
extract_mode = TRUE;
}
#line 381 "inweb/Chapter 2/The Parser.w"
;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(figure (%c+)%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_220);
L->command_code = FIGURE_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(html (%c+)%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_221);
L->command_code = HTML_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(audio (%c+)%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_222);
L->command_code = AUDIO_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(video (%c+)%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_223);
L->command_code = VIDEO_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(download (%c+) \"(%c*)\"%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_224);
L->command_code = DOWNLOAD_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
L->text_operand2 = Str__duplicate(mr2.exp[1]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(download (%c+)%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_225);
L->command_code = DOWNLOAD_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
L->text_operand2 = Str__new();
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(carousel%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_226);
L->command_code = CAROUSEL_UNCAPTIONED_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__new();
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(carousel \"(%c+)\" below%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_227);
L->command_code = CAROUSEL_BELOW_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(carousel \"(%c+)\" above%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_228);
L->command_code = CAROUSEL_ABOVE_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(carousel \"(%c+)\"%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_229);
L->command_code = CAROUSEL_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(carousel end%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_230);
L->command_code = CAROUSEL_END_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
comment_mode = TRUE;
} else if ((current_paragraph) &&
((Regexp__match(&mr2, mr.exp[0], L"%(embedded (%C+) video (%c+)%)")) ||
(Regexp__match(&mr2, mr.exp[0], L"%(embedded (%C+) audio (%c+)%)")))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_231);
L->command_code = EMBED_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
L->text_operand2 = Str__duplicate(mr2.exp[1]);
comment_mode = TRUE;
} else {
Main__error_in_web(TL_IS_232, L);
}
} else if (Regexp__match(&mr, L->text, L"= *%C%c*")) {
Main__error_in_web(TL_IS_233, L);
}
code_plainness_for_body = L->plainer;
hyperlink_body = L->enable_hyperlinks;
Regexp__dispose_of(&mr);
Regexp__dispose_of(&mr2);
continue;
}
#line 167 "inweb/Chapter 2/The Parser.w"
;
}
if ((Str__get_first_char(L->text) == '@') &&
(Str__get_at(L->text, 1) != '<') &&
(L->category != MACRO_DEFINITION_LCAT))
{
#line 301 "inweb/Chapter 2/The Parser.w"
TEMPORARY_TEXT(command_text)
Str__copy(command_text, L->text);
Str__delete_first_character(command_text); /* i.e., strip the at-sign from the front */
TEMPORARY_TEXT(remainder)
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, command_text, L"(%C*) *(%c*?)")) {
Str__copy(command_text, mr.exp[0]);
Str__copy(remainder, mr.exp[1]);
}
{
#line 538 "inweb/Chapter 2/The Parser.w"
extract_mode = FALSE;
if (Str__eq_wide_string(command_text, L"Purpose:"))
{
#line 586 "inweb/Chapter 2/The Parser.w"
if (before_bar == FALSE) Main__error_in_web(TL_IS_239, L);
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@Purpose'", V1_SYNTAX);
L->category = PURPOSE_LCAT;
L->is_commentary = TRUE;
L->text_operand = Str__duplicate(remainder);
S->sect_purpose = Parser__extract_purpose(remainder, L->next_line, L->owning_section, &L);
}
#line 539 "inweb/Chapter 2/The Parser.w"
else if (Str__eq_wide_string(command_text, L"Interface:"))
{
#line 595 "inweb/Chapter 2/The Parser.w"
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@Interface'", V1_SYNTAX);
if (before_bar == FALSE) Main__error_in_web(TL_IS_240, L);
L->category = INTERFACE_LCAT;
L->owning_paragraph = NULL;
L->is_commentary = TRUE;
source_line *XL = L->next_line;
while ((XL) && (XL->next_line) && (XL->owning_section == L->owning_section)) {
if (Str__get_first_char(XL->text) == '@') break;
XL->category = INTERFACE_BODY_LCAT;
L = XL;
XL = XL->next_line;
}
}
#line 540 "inweb/Chapter 2/The Parser.w"
else if (Str__eq_wide_string(command_text, L"Definitions:"))
{
#line 610 "inweb/Chapter 2/The Parser.w"
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@Definitions' headings", V1_SYNTAX);
if (before_bar == FALSE) Main__error_in_web(TL_IS_241, L);
L->category = DEFINITIONS_LCAT;
L->owning_paragraph = NULL;
L->is_commentary = TRUE;
before_bar = TRUE;
next_par_number = 1;
}
#line 541 "inweb/Chapter 2/The Parser.w"
else if (Regexp__match(&mr, command_text, L"----+"))
{
#line 623 "inweb/Chapter 2/The Parser.w"
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "the bar '----...'", V1_SYNTAX);
if (before_bar == FALSE) Main__error_in_web(TL_IS_242, L);
L->category = BAR_LCAT;
L->owning_paragraph = NULL;
L->is_commentary = TRUE;
comment_mode = TRUE;
S->barred = TRUE;
before_bar = FALSE;
next_par_number = 1;
}
#line 542 "inweb/Chapter 2/The Parser.w"
else if ((Str__eq_wide_string(command_text, L"c")) ||
(Str__eq_wide_string(command_text, L"x")) ||
((S->md->using_syntax == V1_SYNTAX) && (Str__eq_wide_string(command_text, L"e"))))
{
#line 641 "inweb/Chapter 2/The Parser.w"
if (S->md->using_syntax > V1_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@c' and '@x'", V1_SYNTAX);
L->category = BEGIN_CODE_LCAT;
if ((Str__eq_wide_string(command_text, L"e")) && (current_paragraph))
current_paragraph->placed_early = TRUE;
if (Str__eq_wide_string(command_text, L"x")) code_lcat_for_body = TEXT_EXTRACT_LCAT;
else code_lcat_for_body = CODE_BODY_LCAT;
code_pl_for_body = NULL;
comment_mode = FALSE;
code_plainness_for_body = FALSE;
hyperlink_body = FALSE;
}
#line 546 "inweb/Chapter 2/The Parser.w"
else if (Str__eq_wide_string(command_text, L"d"))
{
#line 657 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
code_lcat_for_body = CONT_DEFINITION_LCAT;
code_pl_for_body = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
} else {
L->text_operand = Str__duplicate(remainder); /* name of term defined */
L->text_operand2 = Str__new(); /* no value given */
}
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
Ctags__note_defined_constant(L, L->text_operand);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 547 "inweb/Chapter 2/The Parser.w"
else if (Str__eq_wide_string(command_text, L"define")) {
if (S->md->using_syntax < V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@define' for definitions (use '@d' instead)", V2_SYNTAX);
{
#line 657 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
code_lcat_for_body = CONT_DEFINITION_LCAT;
code_pl_for_body = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
} else {
L->text_operand = Str__duplicate(remainder); /* name of term defined */
L->text_operand2 = Str__new(); /* no value given */
}
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
Ctags__note_defined_constant(L, L->text_operand);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 551 "inweb/Chapter 2/The Parser.w"
;
} else if (Str__eq_wide_string(command_text, L"default")) {
if (S->md->using_syntax < V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@default' for definitions", V2_SYNTAX);
L->default_defn = TRUE;
{
#line 657 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
code_lcat_for_body = CONT_DEFINITION_LCAT;
code_pl_for_body = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
} else {
L->text_operand = Str__duplicate(remainder); /* name of term defined */
L->text_operand2 = Str__new(); /* no value given */
}
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
Ctags__note_defined_constant(L, L->text_operand);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 556 "inweb/Chapter 2/The Parser.w"
;
} else if (Str__eq_wide_string(command_text, L"enum"))
{
#line 678 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
text_stream *from = NULL;
match_results mr = Regexp__create_mr();
L->text_operand = Str__duplicate(remainder); /* name of term defined */
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(after)
if (LanguageMethods__parse_comment(S->sect_language, L->text_operand,
before, after)) {
Str__copy(L->text_operand, before);
}
DISCARD_TEXT(before)
DISCARD_TEXT(after)
Str__trim_white_space(L->text_operand);
if (Regexp__match(&mr, L->text_operand, L"(%C+) from (%c+)")) {
from = mr.exp[1];
Str__copy(L->text_operand, mr.exp[0]);
} else if (Regexp__match(&mr, L->text_operand, L"(%C+) (%c+)")) {
Main__error_in_web(TL_IS_243, L);
}
L->text_operand2 = Str__new();
if (inweb_mode == TANGLE_MODE)
Enumerations__define(L->text_operand2, L->text_operand, from, L);
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
Ctags__note_defined_constant(L, L->text_operand);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 557 "inweb/Chapter 2/The Parser.w"
else if ((Str__eq_wide_string(command_text, L"e")) && (S->md->using_syntax >= V2_SYNTAX))
{
#line 678 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
text_stream *from = NULL;
match_results mr = Regexp__create_mr();
L->text_operand = Str__duplicate(remainder); /* name of term defined */
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(after)
if (LanguageMethods__parse_comment(S->sect_language, L->text_operand,
before, after)) {
Str__copy(L->text_operand, before);
}
DISCARD_TEXT(before)
DISCARD_TEXT(after)
Str__trim_white_space(L->text_operand);
if (Regexp__match(&mr, L->text_operand, L"(%C+) from (%c+)")) {
from = mr.exp[1];
Str__copy(L->text_operand, mr.exp[0]);
} else if (Regexp__match(&mr, L->text_operand, L"(%C+) (%c+)")) {
Main__error_in_web(TL_IS_243, L);
}
L->text_operand2 = Str__new();
if (inweb_mode == TANGLE_MODE)
Enumerations__define(L->text_operand2, L->text_operand, from, L);
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
Ctags__note_defined_constant(L, L->text_operand);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 559 "inweb/Chapter 2/The Parser.w"
else {
int weight = -1, new_page = FALSE;
if (Str__eq_wide_string(command_text, L"")) weight = ORDINARY_WEIGHT;
if ((Str__eq_wide_string(command_text, L"h")) || (Str__eq_wide_string(command_text, L"heading"))) {
if (S->md->using_syntax < V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@h' or '@heading' for headings (use '@p' instead)", V2_SYNTAX);
weight = SUBHEADING_WEIGHT;
}
if (Str__eq_wide_string(command_text, L"p")) {
if (S->md->using_syntax > V1_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@p' for headings (use '@h' instead)", V1_SYNTAX);
weight = SUBHEADING_WEIGHT;
}
if (Str__eq_wide_string(command_text, L"pp")) {
if (S->md->using_syntax > V1_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@pp' for super-headings", V1_SYNTAX);
weight = SUBHEADING_WEIGHT; new_page = TRUE;
}
if (weight >= 0)
{
#line 731 "inweb/Chapter 2/The Parser.w"
comment_mode = TRUE;
L->is_commentary = TRUE;
L->category = PARAGRAPH_START_LCAT;
if (weight == SUBHEADING_WEIGHT) L->category = HEADING_START_LCAT;
L->text_operand = Str__new(); /* title */
match_results mr = Regexp__create_mr();
if ((weight == SUBHEADING_WEIGHT) && (Regexp__match(&mr, remainder, L"(%c+). (%c+)"))) {
L->text_operand = Str__duplicate(mr.exp[0]);
L->text_operand2 = Str__duplicate(mr.exp[1]);
} else if ((weight == SUBHEADING_WEIGHT) && (Regexp__match(&mr, remainder, L"(%c+). *"))) {
L->text_operand = Str__duplicate(mr.exp[0]);
L->text_operand2 = Str__new();
} else {
L->text_operand = Str__new();
L->text_operand2 = Str__duplicate(remainder);
}
{
#line 781 "inweb/Chapter 2/The Parser.w"
paragraph *P = CREATE(paragraph);
if (S->md->using_syntax > V1_SYNTAX) {
P->above_bar = FALSE;
P->placed_early = FALSE;
P->placed_very_early = FALSE;
} else {
P->above_bar = before_bar;
P->placed_early = before_bar;
P->placed_very_early = FALSE;
}
P->invisible = FALSE;
if (Str__eq(Bibliographic__get_datum(W->md, TL_IS_244), TL_IS_245))
P->invisible = TRUE;
P->heading_text = Str__duplicate(L->text_operand);
if ((S->md->using_syntax == V1_SYNTAX) && (before_bar))
P->ornament = Str__duplicate(TL_IS_246);
else
P->ornament = Str__duplicate(TL_IS_247);
WRITE_TO(P->paragraph_number, "%d", next_par_number++);
P->parent_paragraph = NULL;
P->next_child_number = 1;
P->starts_on_new_page = FALSE;
P->weight = weight;
P->first_line_in_paragraph = L;
P->defines_macro = NULL;
P->functions = NEW_LINKED_LIST(function);
P->structures = NEW_LINKED_LIST(language_type);
P->taggings = NEW_LINKED_LIST(paragraph_tagging);
P->footnotes = NEW_LINKED_LIST(footnote);
P->under_section = S;
S->sect_paragraphs++;
ADD_TO_LINKED_LIST(P, paragraph, S->paragraphs);
current_paragraph = P;
}
#line 747 "inweb/Chapter 2/The Parser.w"
;
L->owning_paragraph = current_paragraph;
W->no_paragraphs++;
Regexp__dispose_of(&mr);
}
#line 578 "inweb/Chapter 2/The Parser.w"
else Main__error_in_web(TL_IS_238, L);
}
}
#line 310 "inweb/Chapter 2/The Parser.w"
;
DISCARD_TEXT(remainder)
DISCARD_TEXT(command_text)
Regexp__dispose_of(&mr);
continue;
}
#line 172 "inweb/Chapter 2/The Parser.w"
;
if (comment_mode)
{
#line 820 "inweb/Chapter 2/The Parser.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L">> (%c+)")) {
L->category = SOURCE_DISPLAY_LCAT;
L->text_operand = Str__duplicate(mr.exp[0]);
}
Regexp__dispose_of(&mr);
}
#line 173 "inweb/Chapter 2/The Parser.w"
;
if (comment_mode == FALSE)
{
#line 832 "inweb/Chapter 2/The Parser.w"
if ((L->category != BEGIN_DEFINITION_LCAT) && (L->category != COMMAND_LCAT)) {
L->category = code_lcat_for_body;
L->plainer = code_plainness_for_body;
L->enable_hyperlinks = hyperlink_body;
if (L->category == TEXT_EXTRACT_LCAT) {
L->colour_as = code_pl_for_body;
if (code_destination) L->extract_to = Str__duplicate(code_destination);
}
}
if ((L->category == CONT_DEFINITION_LCAT) && (Regexp__string_is_white_space(L->text))) {
L->category = COMMENT_BODY_LCAT;
L->is_commentary = TRUE;
code_lcat_for_body = COMMENT_BODY_LCAT;
comment_mode = TRUE;
}
LanguageMethods__subcategorise_line(S->sect_language, L);
}
#line 174 "inweb/Chapter 2/The Parser.w"
;
}
#line 48 "inweb/Chapter 2/The Parser.w"
;
}
DISCARD_TEXT(tag_list)
{
#line 107 "inweb/Chapter 2/The Parser.w"
if (S->md->using_syntax >= V2_SYNTAX) {
source_line *L = S->first_line;
if ((L) && (L->category == CHAPTER_HEADING_LCAT)) L = L->next_line;
if (Str__len(S->sect_purpose) == 0) {
S->sect_purpose = Parser__extract_purpose(TL_IS_211, L?L->next_line: NULL, S, NULL);
if (Str__len(S->sect_purpose) > 0) L->next_line->category = PURPOSE_LCAT;
}
}
}
#line 51 "inweb/Chapter 2/The Parser.w"
;
{
#line 89 "inweb/Chapter 2/The Parser.w"
paragraph *P;
if (S->tag_with)
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
Tags__add_to_paragraph(P, S->tag_with, NULL);
}
#line 52 "inweb/Chapter 2/The Parser.w"
;
{
#line 97 "inweb/Chapter 2/The Parser.w"
int next_footnote = 1;
paragraph *P;
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
{
#line 883 "inweb/Chapter 2/The Parser.w"
int next_footnote_in_para = 1;
footnote *current_text = NULL;
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(cue)
TEMPORARY_TEXT(after)
for (source_line *L = P->first_line_in_paragraph;
((L) && (L->owning_paragraph == P)); L = L->next_line)
if (L->is_commentary) {
Str__clear(before); Str__clear(cue); Str__clear(after);
if (Parser__detect_footnote(W, L->text, before, cue, after)) {
int this_is_a_cue = FALSE;
LOOP_THROUGH_TEXT(pos, before)
if (Characters__is_whitespace(Str__get(pos)) == FALSE)
this_is_a_cue = TRUE;
if (this_is_a_cue == FALSE)
{
#line 907 "inweb/Chapter 2/The Parser.w"
L->category = FOOTNOTE_TEXT_LCAT;
footnote *F = CREATE(footnote);
F->footnote_cue_number = Str__atoi(cue, 0);
if (F->footnote_cue_number != next_footnote_in_para) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "footnote should be numbered [%d], not [%d]",
next_footnote_in_para, F->footnote_cue_number);
Main__error_in_web(err, L);
DISCARD_TEXT(err)
}
next_footnote_in_para++;
F->footnote_text_number = next_footnote++;
F->cue_text = Str__new();
F->cued_already = FALSE;
WRITE_TO(F->cue_text, "%d", F->footnote_text_number);
ADD_TO_LINKED_LIST(F, footnote, P->footnotes);
current_text = F;
}
#line 898 "inweb/Chapter 2/The Parser.w"
;
}
L->footnote_text = current_text;
}
DISCARD_TEXT(before)
DISCARD_TEXT(cue)
DISCARD_TEXT(after)
}
#line 100 "inweb/Chapter 2/The Parser.w"
;
}
#line 53 "inweb/Chapter 2/The Parser.w"
;
}
#line 22 "inweb/Chapter 2/The Parser.w"
;
LanguageMethods__parse_types(W, W->main_language);
LanguageMethods__parse_functions(W, W->main_language);
LanguageMethods__further_parsing(W, W->main_language);
}
#line 779 "inweb/Chapter 2/The Parser.w"
#line 856 "inweb/Chapter 2/The Parser.w"
text_stream *Parser__extract_purpose(text_stream *prologue, source_line *XL, section *S, source_line **adjust) {
text_stream *P = Str__duplicate(prologue);
while ((XL) && (XL->next_line) && (XL->owning_section == S) &&
(((adjust) && (isalnum(Str__get_first_char(XL->text)))) ||
((!adjust) && (XL->category == COMMENT_BODY_LCAT)))) {
WRITE_TO(P, " %S", XL->text);
XL->category = PURPOSE_BODY_LCAT;
XL->is_commentary = TRUE;
if (adjust) *adjust = XL;
XL = XL->next_line;
}
Str__trim_white_space(P);
return P;
}
#line 881 "inweb/Chapter 2/The Parser.w"
#line 928 "inweb/Chapter 2/The Parser.w"
int Parser__detect_footnote(web *W, text_stream *matter, text_stream *before,
text_stream *cue, text_stream *after) {
text_stream *fn_on_notation =
Bibliographic__get_datum(W->md, TL_IS_248);
text_stream *fn_off_notation =
Bibliographic__get_datum(W->md, TL_IS_249);
if (Str__ne(fn_on_notation, TL_IS_250)) {
int N1 = Str__len(fn_on_notation);
int N2 = Str__len(fn_off_notation);
if ((N1 > 0) && (N2 > 0))
for (int i=0; i < Str__len(matter); i++) {
if (Str__includes_at(matter, i, fn_on_notation)) {
int j = i + N1 + 1;
while (j < Str__len(matter)) {
if (Str__includes_at(matter, j, fn_off_notation)) {
TEMPORARY_TEXT(b)
TEMPORARY_TEXT(c)
TEMPORARY_TEXT(a)
Str__substr(b, Str__start(matter), Str__at(matter, i));
Str__substr(c, Str__at(matter, i + N1), Str__at(matter, j));
Str__substr(a, Str__at(matter, j + N2), Str__end(matter));
int allow = TRUE;
LOOP_THROUGH_TEXT(pos, c)
if (Characters__isdigit(Str__get(pos)) == FALSE)
allow = FALSE;
if (allow) {
Str__clear(before); Str__copy(before, b);
Str__clear(cue); Str__copy(cue, c);
Str__clear(after); Str__copy(after, a);
}
DISCARD_TEXT(b)
DISCARD_TEXT(c)
DISCARD_TEXT(a)
if (allow) return TRUE;
}
j++;
}
}
}
}
return FALSE;
}
footnote *Parser__find_footnote_in_para(paragraph *P, text_stream *cue) {
int N = Str__atoi(cue, 0);
footnote *F;
if (P)
LOOP_OVER_LINKED_LIST(F, footnote, P->footnotes)
if (N == F->footnote_cue_number)
return F;
return NULL;
}
#line 988 "inweb/Chapter 2/The Parser.w"
text_stream *Parser__dimensions(text_stream *item, int *w, int *h, source_line *L) {
int sv = L->owning_section->md->using_syntax;
*w = -1; *h = -1;
text_stream *use = item;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, item, L"(%c+) at (%d+) by (%d+)")) {
if (sv < V2_SYNTAX)
Parser__wrong_version(sv, L, "at X by Y", V2_SYNTAX);
*w = Str__atoi(mr.exp[1], 0);
*h = Str__atoi(mr.exp[2], 0);
use = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, item, L"(%c+) at height (%d+)")) {
if (sv < V2_SYNTAX)
Parser__wrong_version(sv, L, "at height Y", V2_SYNTAX);
*h = Str__atoi(mr.exp[1], 0);
use = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, item, L"(%c+) at width (%d+)")) {
if (sv < V2_SYNTAX)
Parser__wrong_version(sv, L, "at width Y", V2_SYNTAX);
*w = Str__atoi(mr.exp[1], 0);
use = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, item, L"(%c+) at (%d+)cm by (%d+)cm")) {
if (sv < V2_SYNTAX)
Parser__wrong_version(sv, L, "at Xcm by Ycm", V2_SYNTAX);
*w = POINTS_PER_CM*Str__atoi(mr.exp[1], 0);
*h = POINTS_PER_CM*Str__atoi(mr.exp[2], 0);
use = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, item, L"(%c+) at height (%d+)cm")) {
if (sv < V2_SYNTAX)
Parser__wrong_version(sv, L, "at height Ycm", V2_SYNTAX);
*h = POINTS_PER_CM*Str__atoi(mr.exp[1], 0);
use = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, item, L"(%c+) at width (%d+)cm")) {
if (sv < V2_SYNTAX)
Parser__wrong_version(sv, L, "at width Ycm", V2_SYNTAX);
*w = POINTS_PER_CM*Str__atoi(mr.exp[1], 0);
use = Str__duplicate(mr.exp[0]);
}
Regexp__dispose_of(&mr);
return use;
}
#line 1036 "inweb/Chapter 2/The Parser.w"
void Parser__wrong_version(int using, source_line *L, char *feature, int need) {
TEMPORARY_TEXT(warning)
WRITE_TO(warning, "%s is a feature of version %d syntax (you're using v%d)",
feature, need, using);
Main__error_in_web(warning, L);
DISCARD_TEXT(warning)
}
#line 15 "inweb/Chapter 2/Paragraph Macros.w"
#line 20 "inweb/Chapter 2/Paragraph Macros.w"
para_macro *Macros__create(section *S, paragraph *P, source_line *L, text_stream *name) {
para_macro *pmac = CREATE(para_macro);
pmac->macro_name = Str__duplicate(name);
pmac->defining_paragraph = P;
P->defines_macro = pmac;
pmac->defn_start = L->next_line;
pmac->macro_usages = NEW_LINKED_LIST(macro_usage);
ADD_TO_LINKED_LIST(pmac, para_macro, S->macros);
return pmac;
}
#line 38 "inweb/Chapter 2/Paragraph Macros.w"
para_macro *Macros__find_by_name(text_stream *name, section *scope) {
para_macro *pmac;
LOOP_OVER_LINKED_LIST(pmac, para_macro, scope->macros)
if (Str__eq(name, pmac->macro_name))
return pmac;
return NULL;
}
#line 16 "inweb/Chapter 2/Tags.w"
#line 22 "inweb/Chapter 2/Tags.w"
theme_tag *Tags__find_by_name(text_stream *name, int creating_if_necessary) {
theme_tag *tag;
LOOP_OVER(tag, theme_tag)
if (Str__eq(name, tag->tag_name))
return tag;
if (creating_if_necessary) {
tag = CREATE(theme_tag);
tag->tag_name = Str__duplicate(name);
tag->ifdef_positive = NOT_APPLICABLE;
tag->ifdef_symbol = Str__new();
if (Str__prefix_eq(name, TL_IS_251, 6)) {
Str__substr(tag->ifdef_symbol, Str__at(name, 6), Str__end(name));
tag->ifdef_positive = TRUE;
} else if (Str__prefix_eq(name, TL_IS_252, 7)) {
Str__substr(tag->ifdef_symbol, Str__at(name, 7), Str__end(name));
tag->ifdef_positive = FALSE;
}
LanguageMethods__new_tag_declared(tag);
return tag;
}
return NULL;
}
#line 55 "inweb/Chapter 2/Tags.w"
void Tags__add_to_paragraph(paragraph *P, theme_tag *tag, text_stream *caption) {
if (P) {
paragraph_tagging *pt = CREATE(paragraph_tagging);
pt->the_tag = tag;
if (caption) pt->caption = Str__duplicate(caption);
else pt->caption = Str__new();
ADD_TO_LINKED_LIST(pt, paragraph_tagging, P->taggings);
}
}
#line 71 "inweb/Chapter 2/Tags.w"
theme_tag *Tags__add_by_name(paragraph *P, text_stream *text) {
if (Str__len(text) == 0) internal_error("empty tag name");
TEMPORARY_TEXT(name) Str__copy(name, text);
TEMPORARY_TEXT(caption)
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, name, L"(%c+?): (%c+)")) {
Str__copy(name, mr.exp[0]);
Str__copy(caption, mr.exp[1]);
}
theme_tag *tag = Tags__find_by_name(name, TRUE);
if (P) Tags__add_to_paragraph(P, tag, caption);
DISCARD_TEXT(name)
DISCARD_TEXT(caption)
Regexp__dispose_of(&mr);
return tag;
}
#line 91 "inweb/Chapter 2/Tags.w"
text_stream *Tags__retrieve_caption(paragraph *P, theme_tag *tag) {
if (tag == NULL) return NULL;
if (P) {
paragraph_tagging *pt;
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
if (tag == pt->the_tag)
return pt->caption;
}
return NULL;
}
#line 107 "inweb/Chapter 2/Tags.w"
int Tags__tagged_with(paragraph *P, theme_tag *tag) {
if (tag == NULL) return TRUE;
if (P) {
paragraph_tagging *pt;
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
if (tag == pt->the_tag)
return TRUE;
}
return FALSE;
}
#line 119 "inweb/Chapter 2/Tags.w"
void Tags__open_ifdefs(OUTPUT_STREAM, paragraph *P) {
paragraph_tagging *pt;
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
if (Str__len(pt->the_tag->ifdef_symbol) > 0)
LanguageMethods__open_ifdef(OUT,
P->under_section->sect_language, pt->the_tag->ifdef_symbol, pt->the_tag->ifdef_positive);
}
void Tags__close_ifdefs(OUTPUT_STREAM, paragraph *P) {
paragraph_tagging *pt;
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
if (Str__len(pt->the_tag->ifdef_symbol) > 0)
LanguageMethods__close_ifdef(OUT,
P->under_section->sect_language, pt->the_tag->ifdef_symbol, pt->the_tag->ifdef_positive);
}
void Tags__show_endnote_on_ifdefs(heterogeneous_tree *tree, tree_node *ap, paragraph *P) {
int d = 0, sense = TRUE;
{
#line 144 "inweb/Chapter 2/Tags.w"
int c = 0;
paragraph_tagging *pt;
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
if (pt->the_tag->ifdef_positive == sense)
if (Str__len(pt->the_tag->ifdef_symbol) > 0) {
if (c++ == 0) {
if (d++ == 0) {
tree_node *E = WeaveTree__endnote(tree);
Trees__make_child(E, ap); ap = E;
TextWeaver__commentary_text(tree, ap, TL_IS_254);
} else {
TextWeaver__commentary_text(tree, ap, TL_IS_255);
}
} else {
TextWeaver__commentary_text(tree, ap, TL_IS_256);
}
TextWeaver__commentary_text(tree, ap, pt->the_tag->ifdef_symbol);
}
if (c > 0) {
if (c == 1) TextWeaver__commentary_text(tree, ap, TL_IS_257);
else TextWeaver__commentary_text(tree, ap, TL_IS_258);
if (sense) TextWeaver__commentary_text(tree, ap, TL_IS_259);
else TextWeaver__commentary_text(tree, ap, TL_IS_260);
}
}
#line 137 "inweb/Chapter 2/Tags.w"
;
sense = FALSE;
{
#line 144 "inweb/Chapter 2/Tags.w"
int c = 0;
paragraph_tagging *pt;
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
if (pt->the_tag->ifdef_positive == sense)
if (Str__len(pt->the_tag->ifdef_symbol) > 0) {
if (c++ == 0) {
if (d++ == 0) {
tree_node *E = WeaveTree__endnote(tree);
Trees__make_child(E, ap); ap = E;
TextWeaver__commentary_text(tree, ap, TL_IS_254);
} else {
TextWeaver__commentary_text(tree, ap, TL_IS_255);
}
} else {
TextWeaver__commentary_text(tree, ap, TL_IS_256);
}
TextWeaver__commentary_text(tree, ap, pt->the_tag->ifdef_symbol);
}
if (c > 0) {
if (c == 1) TextWeaver__commentary_text(tree, ap, TL_IS_257);
else TextWeaver__commentary_text(tree, ap, TL_IS_258);
if (sense) TextWeaver__commentary_text(tree, ap, TL_IS_259);
else TextWeaver__commentary_text(tree, ap, TL_IS_260);
}
}
#line 139 "inweb/Chapter 2/Tags.w"
;
if (d > 0) TextWeaver__commentary_text(tree, ap, TL_IS_253);
}
#line 22 "inweb/Chapter 2/Enumerated Constants.w"
#line 27 "inweb/Chapter 2/Enumerated Constants.w"
enumeration_set *Enumerations__find(text_stream *post) {
enumeration_set *es = NULL;
LOOP_OVER(es, enumeration_set)
if (Str__eq(post, es->postfix))
return es;
return NULL;
}
#line 40 "inweb/Chapter 2/Enumerated Constants.w"
void Enumerations__define(OUTPUT_STREAM, text_stream *symbol,
text_stream *from, source_line *L) {
TEMPORARY_TEXT(pf)
{
#line 54 "inweb/Chapter 2/Enumerated Constants.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, symbol, L"%c*_(%C+?)")) Str__copy(pf, mr.exp[0]);
else {
Main__error_in_web(TL_IS_261, L);
WRITE_TO(pf, "BOGUS");
}
Regexp__dispose_of(&mr);
}
#line 43 "inweb/Chapter 2/Enumerated Constants.w"
;
enumeration_set *es = Enumerations__find(pf);
if (from == NULL)
{
#line 63 "inweb/Chapter 2/Enumerated Constants.w"
if (es) {
if (es->stub) WRITE("(%S+", es->stub);
WRITE("%d", es->next_free_value++);
if (es->stub) WRITE(")");
} else Main__error_in_web(TL_IS_262, L);
}
#line 45 "inweb/Chapter 2/Enumerated Constants.w"
else
{
#line 70 "inweb/Chapter 2/Enumerated Constants.w"
if (es) Main__error_in_web(TL_IS_263, L);
else {
es = CREATE(enumeration_set);
es->postfix = Str__duplicate(pf);
es->stub = NULL;
if ((Str__len(from) < 8) &&
((Regexp__match(NULL, from, L"%d+")) ||
(Regexp__match(NULL, from, L"-%d+")))) {
es->first_value = Str__atoi(from, 0);
es->next_free_value = es->first_value + 1;
} else {
es->stub = Str__duplicate(from);
es->first_value = 0;
es->next_free_value = 1;
}
}
if (es->stub) WRITE("(%S+", es->stub);
WRITE("%d", es->first_value);
if (es->stub) WRITE(")");
}
#line 46 "inweb/Chapter 2/Enumerated Constants.w"
;
DISCARD_TEXT(pf)
if (es) es->last_observed_at = L;
}
#line 95 "inweb/Chapter 2/Enumerated Constants.w"
void Enumerations__define_extents(OUTPUT_STREAM, tangle_target *target, programming_language *lang) {
enumeration_set *es;
LOOP_OVER(es, enumeration_set) {
TEMPORARY_TEXT(symbol)
TEMPORARY_TEXT(value)
WRITE_TO(symbol, "NO_DEFINED_%S_VALUES", es->postfix);
WRITE_TO(value, "%d", es->next_free_value - es->first_value);
LanguageMethods__start_definition(OUT, lang, symbol, value,
es->last_observed_at->owning_section, es->last_observed_at);
LanguageMethods__end_definition(OUT, lang,
es->last_observed_at->owning_section, es->last_observed_at);
DISCARD_TEXT(symbol)
DISCARD_TEXT(value)
}
}
#line 19 "inweb/Chapter 2/Paragraph Numbering.w"
void Numbering__number_web(web *W) {
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) {
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
{
#line 31 "inweb/Chapter 2/Paragraph Numbering.w"
for (source_line *L = S->first_line; L; L = L->next_line) {
TEMPORARY_TEXT(p)
Str__copy(p, L->text);
int mlen, mpos;
while ((mpos = Regexp__find_expansion(p, '@', '<', '@', '>', &mlen)) != -1) {
TEMPORARY_TEXT(found_macro)
Str__substr(found_macro, Str__at(p, mpos+2), Str__at(p, mpos+mlen-2));
TEMPORARY_TEXT(original_p)
Str__copy(original_p, p);
Str__clear(p);
Str__substr(p, Str__at(original_p, mpos + mlen), Str__end(original_p));
DISCARD_TEXT(original_p)
para_macro *pmac = Macros__find_by_name(found_macro, S);
if (pmac)
{
#line 68 "inweb/Chapter 2/Paragraph Numbering.w"
macro_usage *mu, *last = NULL;
LOOP_OVER_LINKED_LIST(mu, macro_usage, pmac->macro_usages) {
last = mu;
if (mu->used_in_paragraph == L->owning_paragraph)
break;
}
if (mu == NULL) {
mu = CREATE(macro_usage);
mu->used_in_paragraph = L->owning_paragraph;
mu->multiplicity = 0;
ADD_TO_LINKED_LIST(mu, macro_usage, pmac->macro_usages);
}
mu->multiplicity++;
}
#line 44 "inweb/Chapter 2/Paragraph Numbering.w"
;
DISCARD_TEXT(found_macro)
}
DISCARD_TEXT(p)
}
}
#line 24 "inweb/Chapter 2/Paragraph Numbering.w"
;
{
#line 88 "inweb/Chapter 2/Paragraph Numbering.w"
{
#line 95 "inweb/Chapter 2/Paragraph Numbering.w"
paragraph *P;
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
if (P->defines_macro) {
macro_usage *mu;
LOOP_OVER_LINKED_LIST(mu, macro_usage, P->defines_macro->macro_usages)
if (P != mu->used_in_paragraph) {
Numbering__set_parent(P, mu->used_in_paragraph);
break;
}
}
}
#line 88 "inweb/Chapter 2/Paragraph Numbering.w"
;
{
#line 107 "inweb/Chapter 2/Paragraph Numbering.w"
paragraph *P;
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
if (P->parent_paragraph == NULL)
for (linked_list_item *P2_item = P_item; P2_item; P2_item = NEXT_ITEM_IN_LINKED_LIST(P2_item, paragraph)) {
paragraph *P2 = CONTENT_IN_ITEM(P2_item, paragraph);
if (P2->parent_paragraph) {
if (P2->parent_paragraph->allocation_id < P->allocation_id)
Numbering__set_parent(P, P2->parent_paragraph);
break;
}
}
}
#line 89 "inweb/Chapter 2/Paragraph Numbering.w"
;
{
#line 120 "inweb/Chapter 2/Paragraph Numbering.w"
paragraph *P;
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
P->paragraph_number = Str__new();
}
#line 90 "inweb/Chapter 2/Paragraph Numbering.w"
;
{
#line 129 "inweb/Chapter 2/Paragraph Numbering.w"
int top_level = 1;
paragraph *P;
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
if (P->parent_paragraph == NULL) {
WRITE_TO(P->paragraph_number, "%d", top_level++);
P->next_child_number = 1;
} else
Str__clear(P->paragraph_number);
}
#line 91 "inweb/Chapter 2/Paragraph Numbering.w"
;
{
#line 139 "inweb/Chapter 2/Paragraph Numbering.w"
paragraph *P;
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
Numbering__settle_paragraph_number(P);
}
#line 92 "inweb/Chapter 2/Paragraph Numbering.w"
;
}
#line 25 "inweb/Chapter 2/Paragraph Numbering.w"
;
}
}
}
#line 66 "inweb/Chapter 2/Paragraph Numbering.w"
#line 149 "inweb/Chapter 2/Paragraph Numbering.w"
void Numbering__settle_paragraph_number(paragraph *P) {
if (Str__len(P->paragraph_number) > 0) return;
WRITE_TO(P->paragraph_number, "X"); /* to prevent malformed sections hanging this */
if (P->parent_paragraph) Numbering__settle_paragraph_number(P->parent_paragraph);
if (P == P->parent_paragraph) internal_error("paragraph is its own parent");
Str__clear(P->paragraph_number);
WRITE_TO(P->paragraph_number, "%S.%d", P->parent_paragraph->paragraph_number,
P->parent_paragraph->next_child_number++);
P->next_child_number = 1;
}
void Numbering__set_parent(paragraph *of, paragraph *to) {
if (of == NULL) internal_error("no paragraph");
if (to == of) internal_error("paragraph parent set to itself");
of->parent_paragraph = to;
}
#line 11 "inweb/Chapter 3/The Analyser.w"
void Analyser__scan_line_categories(web *W, text_stream *range) {
PRINT("Scan of source lines for '%S'\n", range);
int count = 1;
chapter *C = Reader__get_chapter_for_range(W, range);
if (C) {
section *S;
LOOP_OVER_LINKED_LIST(S, section, C->sections)
for (source_line *L = S->first_line; L; L = L->next_line)
{
#line 35 "inweb/Chapter 3/The Analyser.w"
TEMPORARY_TEXT(C)
WRITE_TO(C, "%s", Lines__category_name(L->category));
while (Str__len(C) < 20) PUT_TO(C, '.');
PRINT("%07d %S %S\n", count++, C, L->text);
DISCARD_TEXT(C)
}
#line 19 "inweb/Chapter 3/The Analyser.w"
;
} else {
section *S = Reader__get_section_for_range(W, range);
if (S) {
for (source_line *L = S->first_line; L; L = L->next_line)
{
#line 35 "inweb/Chapter 3/The Analyser.w"
TEMPORARY_TEXT(C)
WRITE_TO(C, "%s", Lines__category_name(L->category));
while (Str__len(C) < 20) PUT_TO(C, '.');
PRINT("%07d %S %S\n", count++, C, L->text);
DISCARD_TEXT(C)
}
#line 24 "inweb/Chapter 3/The Analyser.w"
} else {
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
for (source_line *L = S->first_line; L; L = L->next_line)
{
#line 35 "inweb/Chapter 3/The Analyser.w"
TEMPORARY_TEXT(C)
WRITE_TO(C, "%s", Lines__category_name(L->category));
while (Str__len(C) < 20) PUT_TO(C, '.');
PRINT("%07d %S %S\n", count++, C, L->text);
DISCARD_TEXT(C)
}
#line 29 "inweb/Chapter 3/The Analyser.w"
;
}
}
}
#line 50 "inweb/Chapter 3/The Analyser.w"
#line 52 "inweb/Chapter 3/The Analyser.w"
void Analyser__catalogue_the_sections(web *W, text_stream *range, int form) {
int max_width = 0, max_range_width = 0;
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
if (max_range_width < Str__len(S->md->sect_range)) max_range_width = Str__len(S->md->sect_range);
TEMPORARY_TEXT(main_title)
WRITE_TO(main_title, "%S/%S", C->md->ch_basic_title, S->md->sect_title);
if (max_width < Str__len(main_title)) max_width = Str__len(main_title);
DISCARD_TEXT(main_title)
}
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
if ((Str__eq_wide_string(range, L"0")) || (Str__eq(range, C->md->ch_range))) {
PRINT(" -----\n");
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
TEMPORARY_TEXT(main_title)
WRITE_TO(main_title, "%S/%S", C->md->ch_basic_title, S->md->sect_title);
PRINT("%4d %S", S->sect_extent, S->md->sect_range);
for (int i = Str__len(S->md->sect_range); i<max_range_width+2; i++) PRINT(" ");
PRINT("%S", main_title);
for (int i = Str__len(main_title); i<max_width+2; i++) PRINT(" ");
if (form != BASIC_SECTIONCAT)
Functions__catalogue(S, (form == FUNCTIONS_SECTIONCAT)?TRUE:FALSE);
PRINT("\n");
DISCARD_TEXT(main_title)
}
}
}
#line 106 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_code(web *W) {
if (W->analysed) return;
{
#line 141 "inweb/Chapter 3/The Analyser.w"
LanguageMethods__early_preweave_analysis(W->main_language, W);
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if ((L->category == INTERFACE_BODY_LCAT) &&
(L->interface_line_identified == FALSE) &&
(Regexp__string_is_white_space(L->text) == FALSE))
Main__error_in_web(TL_IS_264, L);
}
#line 109 "inweb/Chapter 3/The Analyser.w"
;
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
switch (L->category) {
case BEGIN_DEFINITION_LCAT:
{
#line 155 "inweb/Chapter 3/The Analyser.w"
Analyser__analyse_as_code(W, L, L->text_operand2, ANY_USAGE, 0);
while ((L->next_line) && (L->next_line->category == CONT_DEFINITION_LCAT)) {
L = L->next_line;
Analyser__analyse_as_code(W, L, L->text, ANY_USAGE, 0);
}
}
#line 116 "inweb/Chapter 3/The Analyser.w"
;
break;
case CODE_BODY_LCAT:
{
#line 152 "inweb/Chapter 3/The Analyser.w"
Analyser__analyse_as_code(W, L, L->text, ANY_USAGE, 0);
}
#line 119 "inweb/Chapter 3/The Analyser.w"
;
break;
case PREFORM_GRAMMAR_LCAT:
{
#line 167 "inweb/Chapter 3/The Analyser.w"
Analyser__analyse_as_code(W, L, L->text_operand2,
ANY_USAGE, 0);
Analyser__analyse_as_code(W, L, L->text_operand,
PREFORM_IN_CODE_USAGE, PREFORM_IN_GRAMMAR_USAGE);
}
#line 122 "inweb/Chapter 3/The Analyser.w"
;
break;
}
LanguageMethods__late_preweave_analysis(W->main_language, W);
W->analysed = TRUE;
}
#line 185 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_as_code(web *W, source_line *L, text_stream *text, int mask, int transf) {
int start_at = -1, element_follows = FALSE;
for (int i = 0; i < Str__len(text); i++) {
if ((Regexp__identifier_char(Str__get_at(text, i))) ||
((Str__get_at(text, i) == '-') && (Str__get_at(text, i+1) != '>'))) {
if (start_at == -1) start_at = i;
} else {
if (start_at != -1)
{
#line 206 "inweb/Chapter 3/The Analyser.w"
int u = MISC_USAGE;
if (element_follows) u = ELEMENT_ACCESS_USAGE;
else if (Str__get_at(text, i) == '(') u = FCALL_USAGE;
else if ((Str__get_at(text, i) == '>') && (start_at > 0) && (Str__get_at(text, start_at-1) == '<'))
u = PREFORM_IN_CODE_USAGE;
if (u & mask) {
if (transf) u = transf;
TEMPORARY_TEXT(identifier_found)
for (int j = 0; start_at + j < i; j++)
PUT_TO(identifier_found, Str__get_at(text, start_at + j));
Analyser__analyse_find(W, L, identifier_found, u);
DISCARD_TEXT(identifier_found)
}
start_at = -1; element_follows = FALSE;
}
#line 192 "inweb/Chapter 3/The Analyser.w"
;
if (Str__get_at(text, i) == '.') element_follows = TRUE;
else if ((Str__get_at(text, i) == '-') && (Str__get_at(text, i+1) == '>')) {
element_follows = TRUE; i++;
} else element_follows = FALSE;
}
}
if (start_at != -1) {
int i = Str__len(text);
{
#line 206 "inweb/Chapter 3/The Analyser.w"
int u = MISC_USAGE;
if (element_follows) u = ELEMENT_ACCESS_USAGE;
else if (Str__get_at(text, i) == '(') u = FCALL_USAGE;
else if ((Str__get_at(text, i) == '>') && (start_at > 0) && (Str__get_at(text, start_at-1) == '<'))
u = PREFORM_IN_CODE_USAGE;
if (u & mask) {
if (transf) u = transf;
TEMPORARY_TEXT(identifier_found)
for (int j = 0; start_at + j < i; j++)
PUT_TO(identifier_found, Str__get_at(text, start_at + j));
Analyser__analyse_find(W, L, identifier_found, u);
DISCARD_TEXT(identifier_found)
}
start_at = -1; element_follows = FALSE;
}
#line 201 "inweb/Chapter 3/The Analyser.w"
;
}
}
#line 232 "inweb/Chapter 3/The Analyser.w"
int Analyser__hash_code_from_word(text_stream *text) {
unsigned int hash_code = 0;
string_position p = Str__start(text);
switch(Str__get(p)) {
case '-': if (Str__len(text) == 1) break; /* an isolated minus sign is an ordinary word */
/* and otherwise fall through to... */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
int numeric = TRUE;
/* the first character may prove to be the start of a number: is this true? */
for (p = Str__forward(p); Str__in_range(p); p = Str__forward(p))
if (isdigit(Str__get(p)) == FALSE) numeric = FALSE;
if (numeric) return NUMBER_HASH;
}
}
for (p=Str__start(text); Str__in_range(p); p = Str__forward(p))
hash_code = (unsigned int) ((int) (hash_code*30011) + (Str__get(p)));
return (int) (1+(hash_code % (HASH_TAB_SIZE-1))); /* result of X 30011, plus 1 */
}
#line 261 "inweb/Chapter 3/The Analyser.w"
void Analyser__initialise_hash_table(hash_table *HT) {
HT->safety_code = HASH_SAFETY_CODE;
for (int i=0; i<HASH_TAB_SIZE; i++) HT->analysis_hash[i] = NULL;
}
#line 278 "inweb/Chapter 3/The Analyser.w"
#line 285 "inweb/Chapter 3/The Analyser.w"
hash_table_entry *Analyser__find_hash_entry(hash_table *HT, text_stream *text, int create) {
int h = Analyser__hash_code_from_word(text);
if (h == NUMBER_HASH) return NULL;
if ((h<0) || (h>=HASH_TAB_SIZE)) internal_error("hash code out of range");
if (HT->safety_code != HASH_SAFETY_CODE) internal_error("uninitialised HT");
if (HT->analysis_hash[h] != NULL) {
hash_table_entry *hte = NULL;
LOOP_OVER_LINKED_LIST(hte, hash_table_entry, HT->analysis_hash[h]) {
if (Str__eq(hte->hash_key, text))
return hte;
}
}
if (create) {
hash_table_entry *hte = CREATE(hash_table_entry);
hte->language_reserved_word = 0;
hte->hash_key = Str__duplicate(text);
hte->usages = NEW_LINKED_LIST(hash_table_entry_usage);
hte->definition_line = NULL;
hte->as_function = NULL;
if (HT->analysis_hash[h] == NULL)
HT->analysis_hash[h] = NEW_LINKED_LIST(hash_table_entry);
ADD_TO_LINKED_LIST(hte, hash_table_entry, HT->analysis_hash[h]);
return hte;
}
return NULL;
}
hash_table_entry *Analyser__find_hash_entry_for_section(section *S, text_stream *text,
int create) {
return Analyser__find_hash_entry(&(S->sect_target->symbols), text, create);
}
#line 320 "inweb/Chapter 3/The Analyser.w"
hash_table_entry *Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(HT, p, TRUE);
hte->language_reserved_word |= (1 << (e % 32));
hte->definition_line = NULL;
hte->as_function = NULL;
return hte;
}
void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) {
Analyser__mark_reserved_word(&(S->sect_target->symbols), p, e);
}
hash_table_entry *Analyser__mark_reserved_word_at_line(source_line *L, text_stream *p, int e) {
if (L == NULL) internal_error("no line for rw");
hash_table_entry *hte =
Analyser__mark_reserved_word(&(L->owning_section->sect_target->symbols), p, e);
hte->definition_line = L;
return hte;
}
int Analyser__is_reserved_word(hash_table *HT, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(HT, p, FALSE);
if ((hte) && (hte->language_reserved_word & (1 << (e % 32)))) return TRUE;
return FALSE;
}
int Analyser__is_reserved_word_for_section(section *S, text_stream *p, int e) {
return Analyser__is_reserved_word(&(S->sect_target->symbols), p, e);
}
source_line *Analyser__get_defn_line(section *S, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(&(S->sect_target->symbols), p, FALSE);
if ((hte) && (hte->language_reserved_word & (1 << (e % 32)))) return hte->definition_line;
return NULL;
}
language_function *Analyser__get_function(section *S, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(&(S->sect_target->symbols), p, FALSE);
if ((hte) && (hte->language_reserved_word & (1 << (e % 32)))) return hte->as_function;
return NULL;
}
#line 375 "inweb/Chapter 3/The Analyser.w"
#line 379 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_find(web *W, source_line *L, text_stream *identifier, int u) {
hash_table_entry *hte =
Analyser__find_hash_entry_for_section(L->owning_section, identifier, FALSE);
if (hte == NULL) return;
hash_table_entry_usage *hteu = NULL, *loop = NULL;
LOOP_OVER_LINKED_LIST(loop, hash_table_entry_usage, hte->usages)
if (L->owning_paragraph == loop->usage_recorded_at) {
hteu = loop; break;
}
if (hteu == NULL) {
hteu = CREATE(hash_table_entry_usage);
hteu->form_of_usage = 0;
hteu->usage_recorded_at = L->owning_paragraph;
ADD_TO_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages);
}
hteu->form_of_usage |= u;
}
#line 402 "inweb/Chapter 3/The Analyser.w"
void Analyser__write_makefile(web *W, filename *F, module_search *I, text_stream *platform) {
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, TL_IS_265)) || (Str__eq(short_name, TL_IS_266)))
short_name = TL_IS_267;
TEMPORARY_TEXT(leafname)
WRITE_TO(leafname, "%S.mkscript", short_name);
filename *prototype = Filenames__in(P, leafname);
DISCARD_TEXT(leafname)
if (!(TextFiles__exists(prototype)))
prototype = Filenames__in(path_to_inweb_materials, TL_IS_268);
Makefiles__write(W, prototype, F, I, platform);
}
void Analyser__write_gitignore(web *W, filename *F) {
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, TL_IS_269)) || (Str__eq(short_name, TL_IS_270)))
short_name = TL_IS_271;
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, TL_IS_272);
Git__write_gitignore(W, prototype, F);
}
#line 19 "inweb/Chapter 3/The Collater.w"
void Collater__for_web_and_pattern(text_stream *OUT, web *W,
weave_pattern *pattern, filename *F, filename *into) {
Collater__collate(OUT, W, TL_IS_273, F, pattern, NULL, NULL, NULL, into);
}
void Collater__for_order(text_stream *OUT, weave_order *wv,
filename *F, filename *into) {
Collater__collate(OUT, wv->weave_web, wv->weave_range, F, wv->pattern,
wv->navigation, wv->breadcrumbs, wv, into);
}
void Collater__collate(text_stream *OUT, web *W, text_stream *range,
filename *template_filename, weave_pattern *pattern, filename *nav_file,
linked_list *crumbs, weave_order *wv, filename *into) {
collater_state actual_ies =
Collater__initial_state(W, range, template_filename, pattern,
nav_file, crumbs, wv, into);
collater_state *ies = &actual_ies;
Collater__process(OUT, ies);
}
#line 67 "inweb/Chapter 3/The Collater.w"
#line 73 "inweb/Chapter 3/The Collater.w"
collater_state Collater__initial_state(web *W, text_stream *range,
filename *template_filename, weave_pattern *pattern, filename *nav_file,
linked_list *crumbs, weave_order *wv, filename *into) {
collater_state cls;
cls.no_tlines = 0;
cls.restrict_to_range = Str__duplicate(range);
cls.sp = 0;
cls.inside_navigation_submenu = FALSE;
cls.for_web = W;
cls.nav_pattern = pattern;
cls.nav_file = nav_file;
cls.crumbs = crumbs;
cls.errors_at = template_filename;
cls.wv = wv;
cls.into_file = into;
cls.modules = NEW_LINKED_LIST(module);
if (W) {
int c = LinkedLists__len(W->md->as_module->dependencies);
if (c > 0)
{
#line 98 "inweb/Chapter 3/The Collater.w"
module **module_array =
Memory__calloc(c, sizeof(module *), ARRAY_SORTING_MREASON);
module *M; int d=0;
LOOP_OVER_LINKED_LIST(M, module, W->md->as_module->dependencies)
module_array[d++] = M;
Collater__sort_web(W);
qsort(module_array, (size_t) c, sizeof(module *), Collater__sort_comparison);
for (int d=0; d<c; d++) ADD_TO_LINKED_LIST(module_array[d], module, cls.modules);
Memory__I7_free(module_array, ARRAY_SORTING_MREASON, c*((int) sizeof(module *)));
}
#line 91 "inweb/Chapter 3/The Collater.w"
;
}
{
#line 109 "inweb/Chapter 3/The Collater.w"
TextFiles__read(template_filename, FALSE,
"can't find contents template", TRUE, Collater__temp_line, NULL, &cls);
if (TRACE_COLLATER_EXECUTION)
PRINT("Read template <%f>: %d line(s)\n", template_filename, cls.no_tlines);
if (cls.no_tlines >= MAX_TEMPLATE_LINES)
PRINT("Warning: template <%f> truncated after %d line(s)\n",
template_filename, cls.no_tlines);
}
#line 93 "inweb/Chapter 3/The Collater.w"
;
return cls;
}
#line 118 "inweb/Chapter 3/The Collater.w"
void Collater__temp_line(text_stream *line, text_file_position *tfp, void *v_ies) {
collater_state *cls = (collater_state *) v_ies;
if (cls->no_tlines < MAX_TEMPLATE_LINES)
cls->tlines[cls->no_tlines++] = Str__duplicate(line);
}
#line 127 "inweb/Chapter 3/The Collater.w"
void Collater__process(text_stream *OUT, collater_state *cls) {
int lpos = 0; /* This is our program counter: a line number in the template */
while (lpos < cls->no_tlines) {
match_results mr = Regexp__create_mr();
TEMPORARY_TEXT(tl)
Str__copy(tl, cls->tlines[lpos++]); /* Fetch the line at the program counter and advance */
{
#line 144 "inweb/Chapter 3/The Collater.w"
if (Regexp__match(&mr, tl, L"(%c*?) ")) Str__copy(tl, mr.exp[0]); /* Strip trailing spaces */
if (TRACE_COLLATER_EXECUTION)
{
#line 166 "inweb/Chapter 3/The Collater.w"
PRINT("%04d: %S\nStack:", lpos-1, tl);
for (int j=0; j<cls->sp; j++) {
if (cls->repeat_stack_level[j] == CHAPTER_LEVEL)
PRINT(" %d: %S/%S",
j, ((chapter *)
CONTENT_IN_ITEM(cls->repeat_stack_variable[j], chapter))->md->ch_range,
((chapter *)
CONTENT_IN_ITEM(cls->repeat_stack_threshold[j], chapter))->md->ch_range);
else if (cls->repeat_stack_level[j] == SECTION_LEVEL)
PRINT(" %d: %S/%S",
j, ((section *)
CONTENT_IN_ITEM(cls->repeat_stack_variable[j], section))->md->sect_range,
((section *)
CONTENT_IN_ITEM(cls->repeat_stack_threshold[j], section))->md->sect_range);
}
PRINT("\n");
}
#line 146 "inweb/Chapter 3/The Collater.w"
;
if ((Regexp__match(&mr, tl, L"%[%[(%c+)%]%]")) ||
(Regexp__match(&mr, tl, L" %[%[(%c+)%]%]"))) {
TEMPORARY_TEXT(command)
Str__copy(command, mr.exp[0]);
{
#line 188 "inweb/Chapter 3/The Collater.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, command, L"Select (%c*)")) {
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, cls->for_web->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Str__eq(S->md->sect_range, mr.exp[0])) {
Collater__start_CI_loop(cls, SECTION_LEVEL, S_item, S_item, lpos);
Regexp__dispose_of(&mr);
goto CYCLE;
}
LOOP_OVER_LINKED_LIST(C, chapter, cls->for_web->chapters)
if (Str__eq(C->md->ch_range, mr.exp[0])) {
Collater__start_CI_loop(cls, CHAPTER_LEVEL, C_item, C_item, lpos);
Regexp__dispose_of(&mr);
goto CYCLE;
}
Errors__at_position("don't recognise the chapter or section abbreviation range",
cls->errors_at, lpos);
Regexp__dispose_of(&mr);
goto CYCLE;
}
}
#line 151 "inweb/Chapter 3/The Collater.w"
;
{
#line 214 "inweb/Chapter 3/The Collater.w"
if (Regexp__match(&mr, command, L"If (%c*)")) {
text_stream *condition = mr.exp[0];
int level = IF_FALSE_LEVEL;
if (Str__eq(condition, TL_IS_274)) {
if (cls->for_web->md->chaptered) level = IF_TRUE_LEVEL;
} else if (Str__eq(condition, TL_IS_275)) {
if (LinkedLists__len(cls->modules) > 0)
level = IF_TRUE_LEVEL;
} else if (Str__eq(condition, TL_IS_276)) {
module *M = CONTENT_IN_ITEM(
Collater__heading_topmost_on_stack(cls, MODULE_LEVEL), module);
if ((M) && (Colonies__find(M->module_name)))
level = IF_TRUE_LEVEL;
} else if (Str__eq(condition, TL_IS_277)) {
module *M = CONTENT_IN_ITEM(
Collater__heading_topmost_on_stack(cls, MODULE_LEVEL), module);
if (M) {
TEMPORARY_TEXT(url)
TEMPORARY_TEXT(purpose)
WRITE_TO(url, "%p", M->module_location);
Readme__write_var(purpose, url, TL_IS_278);
if (Str__len(purpose) > 0) level = IF_TRUE_LEVEL;
DISCARD_TEXT(url)
DISCARD_TEXT(purpose)
}
} else if (Str__eq(condition, TL_IS_279)) {
chapter *C = CONTENT_IN_ITEM(
Collater__heading_topmost_on_stack(cls, CHAPTER_LEVEL), chapter);
if ((C) && (Str__len(C->md->rubric) > 0)) level = IF_TRUE_LEVEL;
} else if (Str__eq(condition, TL_IS_280)) {
section *S = CONTENT_IN_ITEM(
Collater__heading_topmost_on_stack(cls, SECTION_LEVEL), section);
if ((S) && (Str__len(S->sect_purpose) > 0)) level = IF_TRUE_LEVEL;
} else {
Errors__at_position("don't recognise the condition",
cls->errors_at, lpos);
}
Collater__start_CI_loop(cls, level, NULL, NULL, lpos);
Regexp__dispose_of(&mr);
goto CYCLE;
}
}
#line 152 "inweb/Chapter 3/The Collater.w"
;
{
#line 257 "inweb/Chapter 3/The Collater.w"
if (Regexp__match(&mr, command, L"Else")) {
if (cls->sp <= 0) {
Errors__at_position("Else without If",
cls->errors_at, lpos);
goto CYCLE;
}
switch (cls->repeat_stack_level[cls->sp-1]) {
case SECTION_LEVEL:
case CHAPTER_LEVEL:
Errors__at_position("Else not matched with If",
cls->errors_at, lpos);
break;
case IF_TRUE_LEVEL: cls->repeat_stack_level[cls->sp-1] = IF_FALSE_LEVEL; break;
case IF_FALSE_LEVEL: cls->repeat_stack_level[cls->sp-1] = IF_TRUE_LEVEL; break;
}
Regexp__dispose_of(&mr);
goto CYCLE;
}
}
#line 153 "inweb/Chapter 3/The Collater.w"
;
{
#line 279 "inweb/Chapter 3/The Collater.w"
int loop_level = 0;
if (Regexp__match(&mr, command, L"Repeat Module")) loop_level = MODULE_LEVEL;
if (Regexp__match(&mr, command, L"Repeat Chapter")) loop_level = CHAPTER_LEVEL;
if (Regexp__match(&mr, command, L"Repeat Section")) loop_level = SECTION_LEVEL;
if (loop_level != 0) {
linked_list_item *from = NULL, *to = NULL;
linked_list_item *CI = FIRST_ITEM_IN_LINKED_LIST(chapter, cls->for_web->chapters);
while ((CI) && (CONTENT_IN_ITEM(CI, chapter)->md->imported))
CI = NEXT_ITEM_IN_LINKED_LIST(CI, chapter);
if (loop_level == MODULE_LEVEL)
{
#line 296 "inweb/Chapter 3/The Collater.w"
from = FIRST_ITEM_IN_LINKED_LIST(module, cls->modules);
to = LAST_ITEM_IN_LINKED_LIST(module, cls->modules);
}
#line 288 "inweb/Chapter 3/The Collater.w"
;
if (loop_level == CHAPTER_LEVEL)
{
#line 300 "inweb/Chapter 3/The Collater.w"
from = CI;
to = LAST_ITEM_IN_LINKED_LIST(chapter, cls->for_web->chapters);
if (Str__eq_wide_string(cls->restrict_to_range, L"0") == FALSE) {
chapter *C;
LOOP_OVER_LINKED_LIST(C, chapter, cls->for_web->chapters)
if (Str__eq(C->md->ch_range, cls->restrict_to_range)) {
from = C_item; to = from;
break;
}
}
}
#line 289 "inweb/Chapter 3/The Collater.w"
;
if (loop_level == SECTION_LEVEL)
{
#line 312 "inweb/Chapter 3/The Collater.w"
chapter *within_chapter =
CONTENT_IN_ITEM(Collater__heading_topmost_on_stack(cls, CHAPTER_LEVEL),
chapter);
if (within_chapter == NULL) {
if (CI) {
chapter *C = CONTENT_IN_ITEM(CI, chapter);
from = FIRST_ITEM_IN_LINKED_LIST(section, C->sections);
}
chapter *LC = LAST_IN_LINKED_LIST(chapter, cls->for_web->chapters);
if (LC) to = LAST_ITEM_IN_LINKED_LIST(section, LC->sections);
} else {
from = FIRST_ITEM_IN_LINKED_LIST(section, within_chapter->sections);
to = LAST_ITEM_IN_LINKED_LIST(section, within_chapter->sections);
}
}
#line 290 "inweb/Chapter 3/The Collater.w"
;
Collater__start_CI_loop(cls, loop_level, from, to, lpos);
goto CYCLE;
}
}
#line 154 "inweb/Chapter 3/The Collater.w"
;
{
#line 330 "inweb/Chapter 3/The Collater.w"
int end_form = -1;
if (Regexp__match(&mr, command, L"End Repeat")) end_form = 1;
if (Regexp__match(&mr, command, L"End Select")) end_form = 2;
if (Regexp__match(&mr, command, L"End If")) end_form = 3;
if (end_form > 0) {
if (cls->sp <= 0) {
Errors__at_position("stack underflow on contents template",
cls->errors_at, lpos);
goto CYCLE;
}
switch (cls->repeat_stack_level[cls->sp-1]) {
case MODULE_LEVEL:
case CHAPTER_LEVEL:
case SECTION_LEVEL:
if (end_form == 3) {
Errors__at_position("End If not matched with If",
cls->errors_at, lpos);
goto CYCLE;
}
break;
case IF_TRUE_LEVEL:
case IF_FALSE_LEVEL:
if (end_form != 3) {
Errors__at_position("If not matched with End If",
cls->errors_at, lpos);
goto CYCLE;
}
break;
}
switch (cls->repeat_stack_level[cls->sp-1]) {
case MODULE_LEVEL:
{
#line 370 "inweb/Chapter 3/The Collater.w"
linked_list_item *CI = cls->repeat_stack_variable[cls->sp-1];
if (CI == cls->repeat_stack_threshold[cls->sp-1])
Collater__end_CI_loop(cls);
else {
cls->repeat_stack_variable[cls->sp-1] =
NEXT_ITEM_IN_LINKED_LIST(CI, chapter);
lpos = cls->repeat_stack_startpos[cls->sp-1]; /* Back round loop */
}
}
#line 360 "inweb/Chapter 3/The Collater.w"
; break;
case CHAPTER_LEVEL:
{
#line 380 "inweb/Chapter 3/The Collater.w"
linked_list_item *CI = cls->repeat_stack_variable[cls->sp-1];
if (CI == cls->repeat_stack_threshold[cls->sp-1])
Collater__end_CI_loop(cls);
else {
cls->repeat_stack_variable[cls->sp-1] =
NEXT_ITEM_IN_LINKED_LIST(CI, chapter);
lpos = cls->repeat_stack_startpos[cls->sp-1]; /* Back round loop */
}
}
#line 361 "inweb/Chapter 3/The Collater.w"
; break;
case SECTION_LEVEL:
{
#line 390 "inweb/Chapter 3/The Collater.w"
linked_list_item *SI = cls->repeat_stack_variable[cls->sp-1];
if ((SI == cls->repeat_stack_threshold[cls->sp-1]) ||
(NEXT_ITEM_IN_LINKED_LIST(SI, section) == NULL))
Collater__end_CI_loop(cls);
else {
cls->repeat_stack_variable[cls->sp-1] =
NEXT_ITEM_IN_LINKED_LIST(SI, section);
lpos = cls->repeat_stack_startpos[cls->sp-1]; /* Back round loop */
}
}
#line 362 "inweb/Chapter 3/The Collater.w"
; break;
case IF_TRUE_LEVEL:
{
#line 401 "inweb/Chapter 3/The Collater.w"
Collater__end_CI_loop(cls);
}
#line 363 "inweb/Chapter 3/The Collater.w"
; break;
case IF_FALSE_LEVEL:
{
#line 401 "inweb/Chapter 3/The Collater.w"
Collater__end_CI_loop(cls);
}
#line 364 "inweb/Chapter 3/The Collater.w"
; break;
}
goto CYCLE;
}
}
#line 155 "inweb/Chapter 3/The Collater.w"
;
DISCARD_TEXT(command)
}
{
#line 415 "inweb/Chapter 3/The Collater.w"
for (int j=cls->sp-1; j>=0; j--)
if (cls->repeat_stack_level[j] == IF_FALSE_LEVEL)
goto CYCLE;
}
#line 158 "inweb/Chapter 3/The Collater.w"
;
{
#line 406 "inweb/Chapter 3/The Collater.w"
for (int rstl = cls->sp-1; rstl >= 0; rstl--)
if (cls->repeat_stack_level[cls->sp-1] == SECTION_LEVEL) {
linked_list_item *SI = cls->repeat_stack_threshold[cls->sp-1];
if (NEXT_ITEM_IN_LINKED_LIST(SI, section) ==
cls->repeat_stack_variable[cls->sp-1])
goto CYCLE;
}
}
#line 159 "inweb/Chapter 3/The Collater.w"
;
{
#line 465 "inweb/Chapter 3/The Collater.w"
TEMPORARY_TEXT(rewritten)
int slen, spos;
while ((spos = Regexp__find_expansion(tl, '[', '[', ']', ']', &slen)) >= 0) {
TEMPORARY_TEXT(varname)
TEMPORARY_TEXT(substituted)
TEMPORARY_TEXT(tail)
Str__substr(rewritten, Str__start(tl), Str__at(tl, spos));
Str__substr(varname, Str__at(tl, spos+2), Str__at(tl, spos+slen-2));
Str__substr(tail, Str__at(tl, spos+slen), Str__end(tl));
match_results mr = Regexp__create_mr();
if (Bibliographic__data_exists(cls->for_web->md, varname)) {
{
#line 541 "inweb/Chapter 3/The Collater.w"
WRITE_TO(substituted, "%S", Bibliographic__get_datum(cls->for_web->md, varname));
}
#line 477 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Navigation")) {
{
#line 547 "inweb/Chapter 3/The Collater.w"
if (cls->nav_file) {
if (TextFiles__exists(cls->nav_file))
Collater__collate(substituted, cls->for_web, cls->restrict_to_range,
cls->nav_file, cls->nav_pattern, NULL, NULL, cls->wv, cls->into_file);
else
Errors__fatal_with_file("unable to find navigation file", cls->nav_file);
} else {
PRINT("Warning: no sidebar links will be generated, as -navigation is unset");
}
}
#line 479 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Breadcrumbs")) {
{
#line 560 "inweb/Chapter 3/The Collater.w"
Colonies__drop_initial_breadcrumbs(substituted, cls->into_file,
cls->crumbs);
}
#line 481 "inweb/Chapter 3/The Collater.w"
;
} else if (Str__eq_wide_string(varname, L"Plugins")) {
{
#line 564 "inweb/Chapter 3/The Collater.w"
Assets__include_relevant_plugins(OUT, cls->nav_pattern, cls->for_web,
cls->wv, cls->into_file);
}
#line 483 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Complete (%c+)")) {
text_stream *detail = mr.exp[0];
{
#line 570 "inweb/Chapter 3/The Collater.w"
if (swarm_leader)
if (Formats__substitute_post_processing_data(substituted,
swarm_leader, detail, cls->nav_pattern) == FALSE)
WRITE_TO(substituted, "%S for complete web", detail);
}
#line 486 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Module (%c+)")) {
text_stream *detail = mr.exp[0];
{
#line 578 "inweb/Chapter 3/The Collater.w"
module *M = CONTENT_IN_ITEM(
Collater__heading_topmost_on_stack(cls, MODULE_LEVEL), module);
if (M == NULL)
Errors__at_position("no module is currently selected",
cls->errors_at, lpos);
else
{
#line 586 "inweb/Chapter 3/The Collater.w"
if (Str__eq_wide_string(detail, L"Title")) {
text_stream *owner = Collater__module_owner(M, cls->for_web);
if (Str__len(owner) > 0) WRITE_TO(substituted, "%S/", owner);
WRITE_TO(substituted, "%S", M->module_name);
} else if (Str__eq_wide_string(detail, L"Page")) {
if (Colonies__find(M->module_name))
Colonies__reference_URL(substituted, M->module_name, cls->into_file);
} else if (Str__eq_wide_string(detail, L"Purpose")) {
TEMPORARY_TEXT(url)
WRITE_TO(url, "%p", M->module_location);
Readme__write_var(substituted, url, TL_IS_281);
DISCARD_TEXT(url)
} else {
WRITE_TO(substituted, "%S for %S", varname, M->module_name);
}
}
#line 583 "inweb/Chapter 3/The Collater.w"
;
}
#line 489 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Chapter (%c+)")) {
text_stream *detail = mr.exp[0];
{
#line 605 "inweb/Chapter 3/The Collater.w"
chapter *C = CONTENT_IN_ITEM(
Collater__heading_topmost_on_stack(cls, CHAPTER_LEVEL), chapter);
if (C == NULL)
Errors__at_position("no chapter is currently selected",
cls->errors_at, lpos);
else
{
#line 613 "inweb/Chapter 3/The Collater.w"
if (Str__eq_wide_string(detail, L"Title")) {
Str__copy(substituted, C->md->ch_title);
} else if (Str__eq_wide_string(detail, L"Code")) {
Str__copy(substituted, C->md->ch_range);
} else if (Str__eq_wide_string(detail, L"Purpose")) {
Str__copy(substituted, C->md->rubric);
} else if (Formats__substitute_post_processing_data(substituted,
C->ch_weave, detail, cls->nav_pattern)) {
;
} else {
WRITE_TO(substituted, "%S for %S", varname, C->md->ch_title);
}
}
#line 610 "inweb/Chapter 3/The Collater.w"
;
}
#line 492 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Section (%c+)")) {
text_stream *detail = mr.exp[0];
{
#line 629 "inweb/Chapter 3/The Collater.w"
section *S = CONTENT_IN_ITEM(
Collater__heading_topmost_on_stack(cls, SECTION_LEVEL), section);
if (S == NULL)
Errors__at_position("no section is currently selected",
cls->errors_at, lpos);
else
{
#line 637 "inweb/Chapter 3/The Collater.w"
if (Str__eq_wide_string(detail, L"Title")) {
Str__copy(substituted, S->md->sect_title);
} else if (Str__eq_wide_string(detail, L"Purpose")) {
Str__copy(substituted, S->sect_purpose);
} else if (Str__eq_wide_string(detail, L"Code")) {
Str__copy(substituted, S->md->sect_range);
} else if (Str__eq_wide_string(detail, L"Lines")) {
WRITE_TO(substituted, "%d", S->sect_extent);
} else if (Str__eq_wide_string(detail, L"Source")) {
WRITE_TO(substituted, "%f", S->md->source_file_for_section);
} else if (Str__eq_wide_string(detail, L"Page")) {
Colonies__section_URL(substituted, S->md);
} else if (Str__eq_wide_string(detail, L"Paragraphs")) {
WRITE_TO(substituted, "%d", S->sect_paragraphs);
} else if (Str__eq_wide_string(detail, L"Mean")) {
int denom = S->sect_paragraphs;
if (denom == 0) denom = 1;
WRITE_TO(substituted, "%d", S->sect_extent/denom);
} else if (Formats__substitute_post_processing_data(substituted,
S->sect_weave, detail, cls->nav_pattern)) {
;
} else {
WRITE_TO(substituted, "%S for %S", varname, S->md->sect_title);
}
}
#line 634 "inweb/Chapter 3/The Collater.w"
;
}
#line 495 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Docs")) {
{
#line 666 "inweb/Chapter 3/The Collater.w"
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file),
Pathnames__from_text(Colonies__home()));
}
#line 497 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Assets")) {
{
#line 671 "inweb/Chapter 3/The Collater.w"
pathname *P = Colonies__assets_path();
if (P == NULL) P = Filenames__up(cls->into_file);
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file), P);
}
#line 499 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"URL \"(%c+)\"")) {
text_stream *link_text = mr.exp[0];
{
#line 677 "inweb/Chapter 3/The Collater.w"
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file),
Pathnames__from_text(link_text));
}
#line 502 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Link \"(%c+)\"")) {
text_stream *link_text = mr.exp[0];
{
#line 682 "inweb/Chapter 3/The Collater.w"
WRITE_TO(substituted, "<a href=\"");
Colonies__reference_URL(substituted, link_text, cls->into_file);
WRITE_TO(substituted, "\">");
}
#line 505 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Menu \"(%c+)\"")) {
text_stream *menu_name = mr.exp[0];
{
#line 687 "inweb/Chapter 3/The Collater.w"
if (cls->inside_navigation_submenu) WRITE_TO(substituted, "</ul>");
WRITE_TO(substituted, "<h2>%S</h2><ul>", menu_name);
cls->inside_navigation_submenu = TRUE;
}
#line 508 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Item \"(%c+)\"")) {
text_stream *item_name = mr.exp[0];
text_stream *icon_text = NULL;
{
#line 692 "inweb/Chapter 3/The Collater.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, item_name, L"<(%i+.%i+)> *(%c*)")) {
icon_text = Str__duplicate(mr.exp[0]);
item_name = Str__duplicate(mr.exp[1]);
} else if (Regexp__match(&mr, item_name, L"(%c*?) *<(%i+.%i+)>")) {
icon_text = Str__duplicate(mr.exp[1]);
item_name = Str__duplicate(mr.exp[0]);
}
Regexp__dispose_of(&mr);
}
#line 512 "inweb/Chapter 3/The Collater.w"
;
text_stream *link_text = item_name;
{
#line 703 "inweb/Chapter 3/The Collater.w"
TEMPORARY_TEXT(url)
Colonies__reference_URL(url, link_text, cls->into_file);
{
#line 715 "inweb/Chapter 3/The Collater.w"
if (cls->inside_navigation_submenu == FALSE) WRITE_TO(substituted, "<ul>");
cls->inside_navigation_submenu = TRUE;
WRITE_TO(substituted, "<li>");
if (Str__eq(url, Filenames__get_leafname(cls->into_file))) {
WRITE_TO(substituted, "<span class=\"unlink\">");
{
#line 736 "inweb/Chapter 3/The Collater.w"
if (Str__len(icon_text) > 0) {
WRITE_TO(substituted, "<img src=\"");
pathname *I = Colonies__assets_path();
if (I == NULL) I = Pathnames__from_text(Colonies__home());
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file), I);
WRITE_TO(substituted, "%S\" height=18> ", icon_text);
}
WRITE_TO(substituted, "%S", item_name);
}
#line 720 "inweb/Chapter 3/The Collater.w"
;
WRITE_TO(substituted, "</span>");
} else if (Str__eq(url, TL_IS_282)) {
WRITE_TO(substituted, "<a href=\"%S\">", url);
WRITE_TO(substituted, "<span class=\"selectedlink\">");
{
#line 736 "inweb/Chapter 3/The Collater.w"
if (Str__len(icon_text) > 0) {
WRITE_TO(substituted, "<img src=\"");
pathname *I = Colonies__assets_path();
if (I == NULL) I = Pathnames__from_text(Colonies__home());
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file), I);
WRITE_TO(substituted, "%S\" height=18> ", icon_text);
}
WRITE_TO(substituted, "%S", item_name);
}
#line 725 "inweb/Chapter 3/The Collater.w"
;
WRITE_TO(substituted, "</span>");
WRITE_TO(substituted, "</a>");
} else {
WRITE_TO(substituted, "<a href=\"%S\">", url);
{
#line 736 "inweb/Chapter 3/The Collater.w"
if (Str__len(icon_text) > 0) {
WRITE_TO(substituted, "<img src=\"");
pathname *I = Colonies__assets_path();
if (I == NULL) I = Pathnames__from_text(Colonies__home());
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file), I);
WRITE_TO(substituted, "%S\" height=18> ", icon_text);
}
WRITE_TO(substituted, "%S", item_name);
}
#line 730 "inweb/Chapter 3/The Collater.w"
;
WRITE_TO(substituted, "</a>");
}
WRITE_TO(substituted, "</li>");
}
#line 705 "inweb/Chapter 3/The Collater.w"
;
DISCARD_TEXT(url)
}
#line 514 "inweb/Chapter 3/The Collater.w"
;
} else if (Regexp__match(&mr, varname, L"Item \"(%c+)\" -> (%c+)")) {
text_stream *item_name = mr.exp[0];
text_stream *link_text = mr.exp[1];
text_stream *icon_text = NULL;
{
#line 692 "inweb/Chapter 3/The Collater.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, item_name, L"<(%i+.%i+)> *(%c*)")) {
icon_text = Str__duplicate(mr.exp[0]);
item_name = Str__duplicate(mr.exp[1]);
} else if (Regexp__match(&mr, item_name, L"(%c*?) *<(%i+.%i+)>")) {
icon_text = Str__duplicate(mr.exp[1]);
item_name = Str__duplicate(mr.exp[0]);
}
Regexp__dispose_of(&mr);
}
#line 519 "inweb/Chapter 3/The Collater.w"
;
{
#line 709 "inweb/Chapter 3/The Collater.w"
TEMPORARY_TEXT(url)
Colonies__link_URL(url, link_text, cls->into_file);
{
#line 715 "inweb/Chapter 3/The Collater.w"
if (cls->inside_navigation_submenu == FALSE) WRITE_TO(substituted, "<ul>");
cls->inside_navigation_submenu = TRUE;
WRITE_TO(substituted, "<li>");
if (Str__eq(url, Filenames__get_leafname(cls->into_file))) {
WRITE_TO(substituted, "<span class=\"unlink\">");
{
#line 736 "inweb/Chapter 3/The Collater.w"
if (Str__len(icon_text) > 0) {
WRITE_TO(substituted, "<img src=\"");
pathname *I = Colonies__assets_path();
if (I == NULL) I = Pathnames__from_text(Colonies__home());
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file), I);
WRITE_TO(substituted, "%S\" height=18> ", icon_text);
}
WRITE_TO(substituted, "%S", item_name);
}
#line 720 "inweb/Chapter 3/The Collater.w"
;
WRITE_TO(substituted, "</span>");
} else if (Str__eq(url, TL_IS_282)) {
WRITE_TO(substituted, "<a href=\"%S\">", url);
WRITE_TO(substituted, "<span class=\"selectedlink\">");
{
#line 736 "inweb/Chapter 3/The Collater.w"
if (Str__len(icon_text) > 0) {
WRITE_TO(substituted, "<img src=\"");
pathname *I = Colonies__assets_path();
if (I == NULL) I = Pathnames__from_text(Colonies__home());
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file), I);
WRITE_TO(substituted, "%S\" height=18> ", icon_text);
}
WRITE_TO(substituted, "%S", item_name);
}
#line 725 "inweb/Chapter 3/The Collater.w"
;
WRITE_TO(substituted, "</span>");
WRITE_TO(substituted, "</a>");
} else {
WRITE_TO(substituted, "<a href=\"%S\">", url);
{
#line 736 "inweb/Chapter 3/The Collater.w"
if (Str__len(icon_text) > 0) {
WRITE_TO(substituted, "<img src=\"");
pathname *I = Colonies__assets_path();
if (I == NULL) I = Pathnames__from_text(Colonies__home());
Pathnames__relative_URL(substituted,
Filenames__up(cls->into_file), I);
WRITE_TO(substituted, "%S\" height=18> ", icon_text);
}
WRITE_TO(substituted, "%S", item_name);
}
#line 730 "inweb/Chapter 3/The Collater.w"
;
WRITE_TO(substituted, "</a>");
}
WRITE_TO(substituted, "</li>");
}
#line 711 "inweb/Chapter 3/The Collater.w"
;
DISCARD_TEXT(url)
}
#line 520 "inweb/Chapter 3/The Collater.w"
;
} else {
WRITE_TO(substituted, "%S", varname);
if (Regexp__match(&mr, varname, L"%i+%c*"))
PRINT("Warning: unable to resolve command '%S'\n", varname);
}
Regexp__dispose_of(&mr);
Str__clear(tl);
WRITE_TO(rewritten, "%S", substituted);
WRITE_TO(tl, "%S", tail);
DISCARD_TEXT(tail)
DISCARD_TEXT(varname)
DISCARD_TEXT(substituted)
}
WRITE_TO(rewritten, "%S", tl);
Str__clear(tl); Str__copy(tl, rewritten);
DISCARD_TEXT(rewritten)
}
#line 160 "inweb/Chapter 3/The Collater.w"
;
}
#line 133 "inweb/Chapter 3/The Collater.w"
;
WRITE("%S\n", tl); /* Copy the now finished line to the output */
DISCARD_TEXT(tl)
CYCLE: ;
Regexp__dispose_of(&mr);
}
if (cls->inside_navigation_submenu) WRITE("</ul>");
cls->inside_navigation_submenu = FALSE;
}
#line 423 "inweb/Chapter 3/The Collater.w"
linked_list_item *Collater__heading_topmost_on_stack(collater_state *cls, int level) {
for (int rstl = cls->sp-1; rstl >= 0; rstl--)
if (cls->repeat_stack_level[rstl] == level)
return cls->repeat_stack_variable[rstl];
return NULL;
}
#line 440 "inweb/Chapter 3/The Collater.w"
void Collater__start_CI_loop(collater_state *cls, int level,
linked_list_item *from, linked_list_item *to, int pos) {
if (cls->sp < CI_STACK_CAPACITY) {
cls->repeat_stack_level[cls->sp] = level;
cls->repeat_stack_variable[cls->sp] = from;
cls->repeat_stack_threshold[cls->sp] = to;
cls->repeat_stack_startpos[cls->sp++] = pos;
}
}
void Collater__end_CI_loop(collater_state *cls) {
cls->sp--;
}
#line 750 "inweb/Chapter 3/The Collater.w"
text_stream *Collater__module_owner(const module *M, web *W) {
text_stream *owner =
Pathnames__directory_name(Pathnames__up(M->module_location));
text_stream *me = NULL;
if ((W) && (W->md->path_to_web))
me = Pathnames__directory_name(W->md->path_to_web);
if (Str__ne_insensitive(me, owner)) return owner;
return NULL;
}
#line 765 "inweb/Chapter 3/The Collater.w"
web *sorting_web = NULL;
void Collater__sort_web(web *W) {
sorting_web = W;
}
int Collater__sort_comparison(const void *ent1, const void *ent2) {
const module *M1 = *((const module **) ent1);
const module *M2 = *((const module **) ent2);
text_stream *O1 = Collater__module_owner(M1, sorting_web);
text_stream *O2 = Collater__module_owner(M2, sorting_web);
int r = Collater__cmp_owners(O1, O2);
if (r != 0) return r;
return Str__cmp_insensitive(M1->module_name, M2->module_name);
}
int Collater__cmp_owners(text_stream *O1, text_stream *O2) {
if (Str__len(O1) == 0) {
if (Str__len(O2) > 0) return -1;
return 0;
}
if (Str__len(O2) == 0) return 1;
if (Str__eq_insensitive(O1, TL_IS_283)) {
if (Str__eq_insensitive(O2, TL_IS_284) == FALSE) return 1;
return 0;
}
if (Str__eq_insensitive(O2, TL_IS_285)) return -1;
return Str__cmp_insensitive(O1, O2);
}
#line 16 "inweb/Chapter 3/The Weaver.w"
int Weaver__weave(weave_order *wv) {
heterogeneous_tree *tree = WeaveTree__new_tree(wv);
TEMPORARY_TEXT(banner)
WRITE_TO(banner, "Weave of '%S' generated by Inweb", wv->booklet_title);
tree_node *H = WeaveTree__head(tree, banner);
DISCARD_TEXT(banner)
tree_node *B = WeaveTree__body(tree);
tree_node *T = WeaveTree__tail(tree, TL_IS_286);
Trees__make_child(H, tree->root);
Trees__make_child(B, tree->root);
Trees__make_child(T, tree->root);
int lines = Weaver__weave_inner(wv, tree, B);
WeaveTree__prune(tree);
text_stream TO_struct;
text_stream *OUT = &TO_struct;
if (STREAM_OPEN_TO_FILE(OUT, wv->weave_to, UTF8_ENC) == FALSE)
Errors__fatal_with_file("unable to write woven file", wv->weave_to);
Formats__render(OUT, tree, wv->weave_to);
STREAM_CLOSE(OUT);
return lines;
}
#line 42 "inweb/Chapter 3/The Weaver.w"
int Weaver__weave_inner(weave_order *wv, heterogeneous_tree *tree, tree_node *body) {
web *W = wv->weave_web;
int lines_woven = 0;
weaver_state state_at; weaver_state *state = &state_at;
{
#line 129 "inweb/Chapter 3/The Weaver.w"
state->kind_of_material = COMMENTARY_MATERIAL;
state->line_break_pending = FALSE;
state->next_heading_without_vertical_skip = FALSE;
state->horizontal_rule_just_drawn = FALSE;
state->last_extract_from = NULL;
state->body_node = body;
state->chapter_node = NULL;
state->section_node = NULL;
state->para_node = NULL;
state->carousel_node = NULL;
state->material_node = NULL;
state->ap = body;
}
#line 46 "inweb/Chapter 3/The Weaver.w"
;
chapter *C, *last_heading = NULL;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
if (C->md->imported == FALSE) {
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Reader__range_within(S->md->sect_range, wv->weave_range)) {
{
#line 65 "inweb/Chapter 3/The Weaver.w"
if (last_heading != C) {
{
#line 79 "inweb/Chapter 3/The Weaver.w"
if (wv->theme_match == NULL) {
if (last_heading != NULL) {
tree_node *F = WeaveTree__chapter_footer(tree, last_heading);
Trees__make_child(F, state->chapter_node);
}
}
}
#line 66 "inweb/Chapter 3/The Weaver.w"
;
tree_node *CH = WeaveTree__chapter(tree, C);
Trees__make_child(CH, state->body_node);
state->chapter_node = CH;
state->ap = CH;
last_heading = C;
if (wv->theme_match == NULL) {
tree_node *H = WeaveTree__chapter_header(tree, C);
Trees__make_child(H, state->chapter_node);
}
}
}
#line 53 "inweb/Chapter 3/The Weaver.w"
;
{
#line 87 "inweb/Chapter 3/The Weaver.w"
tree_node *SH = WeaveTree__section(tree, S);
Trees__make_child(SH, state->chapter_node);
state->section_node = SH;
state->ap = SH;
if (wv->theme_match == NULL) {
tree_node *H = WeaveTree__section_header(tree, S);
Trees__make_child(H, state->section_node);
}
}
#line 54 "inweb/Chapter 3/The Weaver.w"
;
LanguageMethods__begin_weave(S, wv);
{
#line 145 "inweb/Chapter 3/The Weaver.w"
paragraph *current_P = NULL;
int toc_made = FALSE;
for (source_line *LLL = S->first_line; LLL; LLL = LLL->next_line) {
wv->current_weave_line = LLL;
if (LLL->owning_paragraph == NULL)
{
#line 167 "inweb/Chapter 3/The Weaver.w"
if (LLL->category == INTERFACE_BODY_LCAT) {
state->horizontal_rule_just_drawn = FALSE;
continue;
}
if (LLL->category == PURPOSE_BODY_LCAT) {
continue;
}
if (LLL->category == DEFINITIONS_LCAT) {
Weaver__weave_subheading(tree, wv, state->ap, TL_IS_287);
state->next_heading_without_vertical_skip = TRUE;
state->horizontal_rule_just_drawn = FALSE;
continue;
}
if (LLL->category == BAR_LCAT) {
state->kind_of_material = COMMENTARY_MATERIAL;
state->next_heading_without_vertical_skip = TRUE;
if (state->horizontal_rule_just_drawn == FALSE) {
tree_node *B = WeaveTree__bar(tree);
Trees__make_child(B, state->ap);
}
continue;
}
if ((LLL->category == CHAPTER_HEADING_LCAT) ||
(LLL->category == SECTION_HEADING_LCAT))
continue;
}
#line 150 "inweb/Chapter 3/The Weaver.w"
else if (LLL->owning_paragraph != current_P) {
if (toc_made == FALSE) {
if (Str__len(S->sect_purpose) > 0) {
tree_node *F = WeaveTree__purpose(tree, S->sect_purpose);
Trees__make_child(F, state->ap);
}
Weaver__weave_table_of_contents(tree, state->ap, S);
toc_made = TRUE;
}
current_P = LLL->owning_paragraph;
if (Tags__tagged_with(current_P, wv->theme_match))
{
#line 194 "inweb/Chapter 3/The Weaver.w"
if (current_P->starts_on_new_page)
Trees__make_child(WeaveTree__pagebreak(tree), state->ap);
source_line *L = LLL;
if ((L->category != HEADING_START_LCAT) &&
(L->category != PARAGRAPH_START_LCAT))
Main__error_in_web(TL_IS_288, L); /* should never happen */
{
#line 220 "inweb/Chapter 3/The Weaver.w"
LanguageMethods__reset_syntax_colouring(S->sect_language);
if (wv->theme_match)
{
#line 233 "inweb/Chapter 3/The Weaver.w"
text_stream *cap = Tags__retrieve_caption(L->owning_paragraph, wv->theme_match);
if (Str__len(cap) > 0) {
Weaver__weave_subheading(tree, wv, state->ap, C->md->ch_title);
} else if (state->last_extract_from != S) {
TEMPORARY_TEXT(extr)
WRITE_TO(extr, "From %S: %S", C->md->ch_title, S->md->sect_title);
Weaver__weave_subheading(tree, wv, state->ap, extr);
DISCARD_TEXT(extr)
}
state->last_extract_from = S;
}
#line 221 "inweb/Chapter 3/The Weaver.w"
;
state->para_node = WeaveTree__paragraph_heading(tree, current_P,
state->next_heading_without_vertical_skip);
Trees__make_child(state->para_node, state->section_node);
Weaver__change_material_for_para(tree, state);
state->kind_of_material = COMMENTARY_MATERIAL;
state->next_heading_without_vertical_skip = FALSE;
}
#line 201 "inweb/Chapter 3/The Weaver.w"
;
{
#line 248 "inweb/Chapter 3/The Weaver.w"
if (Str__len(L->text_operand2) > 0) {
TEMPORARY_TEXT(matter)
WRITE_TO(matter, "%S\n", L->text_operand2);
Weaver__commentary_text(tree, wv, state->ap, matter);
DISCARD_TEXT(matter)
}
}
#line 203 "inweb/Chapter 3/The Weaver.w"
;
L = L->next_line;
for (; ((L) && (L->owning_paragraph == current_P)); L = L->next_line) {
wv->current_weave_line = L;
if (LanguageMethods__skip_in_weaving(S->sect_language, wv, L) == FALSE) {
lines_woven++;
{
#line 276 "inweb/Chapter 3/The Weaver.w"
if (L->category == COMMAND_LCAT) {
if (L->command_code == PAGEBREAK_CMD)
Trees__make_child(WeaveTree__pagebreak(tree), state->ap);
if (L->command_code == GRAMMAR_INDEX_CMD)
Trees__make_child(WeaveTree__grammar_index(tree), state->ap);
if (L->command_code == FIGURE_CMD)
{
#line 297 "inweb/Chapter 3/The Weaver.w"
int w, h;
text_stream *figname = Parser__dimensions(L->text_operand, &w, &h, L);
Trees__make_child(WeaveTree__figure(tree, figname, w, h), state->ap);
}
#line 281 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == HTML_CMD)
{
#line 302 "inweb/Chapter 3/The Weaver.w"
Trees__make_child(WeaveTree__raw_extract(tree, L->text_operand),
state->ap);
}
#line 282 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == AUDIO_CMD)
{
#line 306 "inweb/Chapter 3/The Weaver.w"
int w, h;
text_stream *figname = Parser__dimensions(L->text_operand, &w, &h, L);
Trees__make_child(WeaveTree__audio(tree, figname, w), state->ap);
}
#line 283 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == VIDEO_CMD)
{
#line 311 "inweb/Chapter 3/The Weaver.w"
int w, h;
text_stream *figname = Parser__dimensions(L->text_operand, &w, &h, L);
Trees__make_child(WeaveTree__video(tree, figname, w, h), state->ap);
}
#line 284 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == DOWNLOAD_CMD)
{
#line 316 "inweb/Chapter 3/The Weaver.w"
Trees__make_child(WeaveTree__download(tree, L->text_operand, L->text_operand2),
state->ap);
}
#line 285 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == EMBED_CMD)
{
#line 320 "inweb/Chapter 3/The Weaver.w"
int w, h;
text_stream *ID = Parser__dimensions(L->text_operand2, &w, &h, L);
Trees__make_child(WeaveTree__embed(tree, L->text_operand, ID, w, h), state->ap);
}
#line 286 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == CAROUSEL_CMD)
{
#line 325 "inweb/Chapter 3/The Weaver.w"
tree_node *C = WeaveTree__carousel_slide(tree, L->text_operand, L->command_code);
Trees__make_child(C, state->para_node);
state->ap = C;
state->carousel_node = C;
}
#line 287 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == CAROUSEL_ABOVE_CMD)
{
#line 325 "inweb/Chapter 3/The Weaver.w"
tree_node *C = WeaveTree__carousel_slide(tree, L->text_operand, L->command_code);
Trees__make_child(C, state->para_node);
state->ap = C;
state->carousel_node = C;
}
#line 288 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == CAROUSEL_BELOW_CMD)
{
#line 325 "inweb/Chapter 3/The Weaver.w"
tree_node *C = WeaveTree__carousel_slide(tree, L->text_operand, L->command_code);
Trees__make_child(C, state->para_node);
state->ap = C;
state->carousel_node = C;
}
#line 289 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == CAROUSEL_UNCAPTIONED_CMD)
{
#line 325 "inweb/Chapter 3/The Weaver.w"
tree_node *C = WeaveTree__carousel_slide(tree, L->text_operand, L->command_code);
Trees__make_child(C, state->para_node);
state->ap = C;
state->carousel_node = C;
}
#line 290 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == CAROUSEL_END_CMD)
{
#line 331 "inweb/Chapter 3/The Weaver.w"
state->ap = state->para_node;
state->carousel_node = NULL;
}
#line 291 "inweb/Chapter 3/The Weaver.w"
;
/* Otherwise assume it was a tangler command, and ignore it here */
continue;
}
}
#line 209 "inweb/Chapter 3/The Weaver.w"
;
{
#line 256 "inweb/Chapter 3/The Weaver.w"
if (L->category == BEGIN_CODE_LCAT) {
state->line_break_pending = FALSE;
LanguageMethods__reset_syntax_colouring(S->sect_language);
continue;
}
if (L->category == END_EXTRACT_LCAT) {
Weaver__change_material(tree, state, COMMENTARY_MATERIAL, FALSE, NULL, NULL);
continue;
}
TEMPORARY_TEXT(matter) Str__copy(matter, L->text);
if (L->is_commentary)
{
#line 339 "inweb/Chapter 3/The Weaver.w"
{
#line 351 "inweb/Chapter 3/The Weaver.w"
if (L->category == SOURCE_DISPLAY_LCAT) {
Trees__make_child(WeaveTree__display_line(tree, L->text_operand), state->ap);
continue;
}
}
#line 339 "inweb/Chapter 3/The Weaver.w"
;
{
#line 360 "inweb/Chapter 3/The Weaver.w"
if (Regexp__string_is_white_space(matter)) {
if ((L->next_line) && (L->next_line->category == COMMENT_BODY_LCAT)) {
match_results mr = Regexp__create_mr();
if ((state->kind_of_material != CODE_MATERIAL) ||
(Regexp__match(&mr, matter, L"\t|(%c*)|(%c*?)")))
Trees__make_child(WeaveTree__vskip(tree, TRUE), state->ap);
Regexp__dispose_of(&mr);
}
continue;
}
}
#line 340 "inweb/Chapter 3/The Weaver.w"
;
{
#line 375 "inweb/Chapter 3/The Weaver.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, matter, L"%(-...%) (%c*)")) { /* continue double */
Weaver__change_material(tree, state, COMMENTARY_MATERIAL, FALSE, NULL, NULL);
Trees__make_child(WeaveTree__weave_item_node(tree, 2, TL_IS_289), state->ap);
Str__copy(matter, mr.exp[0]);
} else if (Regexp__match(&mr, matter, L"%(...%) (%c*)")) { /* continue single */
Weaver__change_material(tree, state, COMMENTARY_MATERIAL, FALSE, NULL, NULL);
Trees__make_child(WeaveTree__weave_item_node(tree, 1, TL_IS_290), state->ap);
Str__copy(matter, mr.exp[0]);
} else if (Regexp__match(&mr, matter, L"%(-([a-zA-Z0-9*]+)%) (%c*)")) { /* begin double */
Weaver__change_material(tree, state, COMMENTARY_MATERIAL, FALSE, NULL, NULL);
Trees__make_child(WeaveTree__weave_item_node(tree, 2, mr.exp[0]), state->ap);
Str__copy(matter, mr.exp[1]);
} else if (Regexp__match(&mr, matter, L"%(([a-zA-Z0-9*]+)%) (%c*)")) { /* begin single */
Weaver__change_material(tree, state, COMMENTARY_MATERIAL, FALSE, NULL, NULL);
Trees__make_child(WeaveTree__weave_item_node(tree, 1, mr.exp[0]), state->ap);
Str__copy(matter, mr.exp[1]);
}
Regexp__dispose_of(&mr);
}
#line 341 "inweb/Chapter 3/The Weaver.w"
;
{
#line 399 "inweb/Chapter 3/The Weaver.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, matter, L"\t|(%c*)|(%c*?)")) {
TEMPORARY_TEXT(original)
Weaver__change_material(tree, state, CODE_MATERIAL, FALSE, NULL, NULL);
Str__copy(original, mr.exp[0]);
Str__copy(matter, mr.exp[1]);
TEMPORARY_TEXT(colouring)
for (int i=0; i<Str__len(original); i++) PUT_TO(colouring, PLAIN_COLOUR);
tree_node *CL = WeaveTree__code_line(tree);
Trees__make_child(CL, state->ap);
TextWeaver__source_code(tree, CL, original, colouring, L->enable_hyperlinks);
DISCARD_TEXT(colouring)
DISCARD_TEXT(original)
Weaver__commentary_text(tree, wv, state->ap, matter);
Regexp__dispose_of(&mr);
continue;
}
Regexp__dispose_of(&mr);
}
#line 342 "inweb/Chapter 3/The Weaver.w"
;
{
#line 419 "inweb/Chapter 3/The Weaver.w"
if (L->category == FOOTNOTE_TEXT_LCAT) {
Weaver__change_material(tree, state, FOOTNOTES_MATERIAL, FALSE, NULL, NULL);
footnote *F = L->footnote_text;
tree_node *FN = WeaveTree__footnote(tree, F->cue_text);
Trees__make_child(FN, state->material_node);
if (F->cued_already == FALSE) Main__error_in_web(TL_IS_291, L);
state->ap = FN;
}
}
#line 343 "inweb/Chapter 3/The Weaver.w"
;
WRITE_TO(matter, "\n");
Weaver__commentary_text(tree, wv, state->ap, matter);
continue;
}
#line 268 "inweb/Chapter 3/The Weaver.w"
else
{
#line 434 "inweb/Chapter 3/The Weaver.w"
{
#line 468 "inweb/Chapter 3/The Weaver.w"
if (state->kind_of_material != CODE_MATERIAL) {
int will_be = CODE_MATERIAL;
if (L->category == MACRO_DEFINITION_LCAT)
will_be = MACRO_MATERIAL;
else if ((L->category == BEGIN_DEFINITION_LCAT) ||
(L->category == CONT_DEFINITION_LCAT))
will_be = DEFINITION_MATERIAL;
else if ((state->kind_of_material == DEFINITION_MATERIAL) &&
((L->category == CODE_BODY_LCAT) || (L->category == COMMENT_BODY_LCAT)) &&
(Str__len(L->text) == 0))
will_be = DEFINITION_MATERIAL;
programming_language *pl = L->colour_as;
if (pl == NULL) pl = S->sect_language;
if (will_be != CODE_MATERIAL) pl = NULL;
theme_tag *T = Tags__find_by_name(TL_IS_292, FALSE);
if ((T) && (Tags__tagged_with(L->owning_paragraph, T))) {
programming_language *prepl =
Languages__find_by_name(TL_IS_293, wv->weave_web, FALSE);
if (prepl) pl = prepl;
}
text_stream *note = NULL;
if (Str__len(L->extract_to) > 0) {
note = Str__new();
WRITE_TO(note, "This is part of the extract file %S.", L->extract_to);
}
Weaver__change_material(tree, state, will_be, L->plainer, pl, note);
state->line_break_pending = FALSE;
}
}
#line 434 "inweb/Chapter 3/The Weaver.w"
;
{
#line 501 "inweb/Chapter 3/The Weaver.w"
if (state->line_break_pending) {
Trees__make_child(WeaveTree__vskip(tree, FALSE), state->ap);
state->line_break_pending = FALSE;
}
if (Regexp__string_is_white_space(matter)) {
state->line_break_pending = TRUE;
goto ClumsyLabel;
}
}
#line 435 "inweb/Chapter 3/The Weaver.w"
;
Str__rectify_indentation(matter, 4);
TEMPORARY_TEXT(prefatory)
TEMPORARY_TEXT(concluding_comment)
{
#line 514 "inweb/Chapter 3/The Weaver.w"
TEMPORARY_TEXT(part_before_comment)
TEMPORARY_TEXT(part_within_comment)
programming_language *pl = S->sect_language;
if (L->category == TEXT_EXTRACT_LCAT) pl = L->colour_as;
if ((pl) && (LanguageMethods__parse_comment(pl,
matter, part_before_comment, part_within_comment))) {
Str__copy(matter, part_before_comment);
Str__copy(concluding_comment, part_within_comment);
}
DISCARD_TEXT(part_before_comment)
DISCARD_TEXT(part_within_comment)
}
#line 441 "inweb/Chapter 3/The Weaver.w"
;
{
#line 529 "inweb/Chapter 3/The Weaver.w"
if (L->category == BEGIN_DEFINITION_LCAT) {
match_results mr = Regexp__create_mr();
if ((Regexp__match(&mr, matter, L"@d (%c*)")) ||
(Regexp__match(&mr, matter, L"@define (%c*)"))) {
Str__copy(prefatory, TL_IS_294);
Str__copy(matter, mr.exp[0]);
} else if (Regexp__match(&mr, matter, L"@default (%c*)")) {
Str__copy(prefatory, TL_IS_295);
Str__copy(matter, mr.exp[0]);
} else if ((Regexp__match(&mr, matter, L"@e (%c*)")) ||
(Regexp__match(&mr, matter, L"@enum (%c*)"))) {
Str__copy(prefatory, TL_IS_296);
Str__copy(matter, mr.exp[0]);
}
Regexp__dispose_of(&mr);
}
}
#line 442 "inweb/Chapter 3/The Weaver.w"
;
tree_node *CL = WeaveTree__code_line(tree);
Trees__make_child(CL, state->ap);
if (Str__len(prefatory) > 0)
Trees__make_child(WeaveTree__weave_defn_node(tree, prefatory), CL);
Str__clear(prefatory);
{
#line 547 "inweb/Chapter 3/The Weaver.w"
TEMPORARY_TEXT(OUT)
int taken = LanguageMethods__weave_code_line(OUT, S->sect_language, wv,
W, C, S, L, matter, concluding_comment);
if (taken) {
tree_node *V = WeaveTree__verbatim(tree, OUT);
Trees__make_child(V, CL);
}
DISCARD_TEXT(OUT)
if (taken) goto ClumsyLabel;
}
#line 450 "inweb/Chapter 3/The Weaver.w"
;
{
#line 558 "inweb/Chapter 3/The Weaver.w"
match_results mr = Regexp__create_mr();
while (Regexp__match(&mr, matter, L"(%c*?)%@%<(%c*?)%@%>(%c*)")) {
para_macro *pmac = Macros__find_by_name(mr.exp[1], S);
if (pmac) {
TEMPORARY_TEXT(front_colouring)
LanguageMethods__syntax_colour(S->sect_language, wv, L, mr.exp[0], front_colouring);
TextWeaver__source_code(tree, CL, mr.exp[0], front_colouring, L->enable_hyperlinks);
DISCARD_TEXT(front_colouring)
Str__copy(matter, mr.exp[2]);
int defn = (L->owning_paragraph == pmac->defining_paragraph)?TRUE:FALSE;
if (defn) Str__clear(matter);
Trees__make_child(WeaveTree__pmac(tree, pmac, defn), CL);
} else break;
}
Regexp__dispose_of(&mr);
}
#line 452 "inweb/Chapter 3/The Weaver.w"
;
TEMPORARY_TEXT(colouring)
LanguageMethods__syntax_colour(S->sect_language, wv, L, matter, colouring);
TextWeaver__source_code(tree, CL, matter, colouring, L->enable_hyperlinks);
DISCARD_TEXT(colouring)
if (Str__len(concluding_comment) > 0)
TextWeaver__comment_text_in_code(tree, CL, concluding_comment);
DISCARD_TEXT(concluding_comment)
DISCARD_TEXT(prefatory)
ClumsyLabel: ;
}
#line 269 "inweb/Chapter 3/The Weaver.w"
;
DISCARD_TEXT(matter)
}
#line 210 "inweb/Chapter 3/The Weaver.w"
;
}
}
L = NULL;
Weaver__change_material(tree, state, ENDNOTES_MATERIAL, FALSE, NULL, NULL);
Weaver__show_endnotes_on_previous_paragraph(tree, wv, state->ap, current_P);
}
#line 162 "inweb/Chapter 3/The Weaver.w"
;
}
}
}
#line 56 "inweb/Chapter 3/The Weaver.w"
;
{
#line 97 "inweb/Chapter 3/The Weaver.w"
if (wv->theme_match == NULL) {
tree_node *F = WeaveTree__section_footer(tree, S);
Trees__make_child(F, state->section_node);
}
}
#line 57 "inweb/Chapter 3/The Weaver.w"
;
}
}
{
#line 79 "inweb/Chapter 3/The Weaver.w"
if (wv->theme_match == NULL) {
if (last_heading != NULL) {
tree_node *F = WeaveTree__chapter_footer(tree, last_heading);
Trees__make_child(F, state->chapter_node);
}
}
}
#line 60 "inweb/Chapter 3/The Weaver.w"
;
return lines_woven;
}
#line 111 "inweb/Chapter 3/The Weaver.w"
#line 127 "inweb/Chapter 3/The Weaver.w"
#line 579 "inweb/Chapter 3/The Weaver.w"
void Weaver__show_endnotes_on_previous_paragraph(heterogeneous_tree *tree,
weave_order *wv, tree_node *ap, paragraph *P) {
tree_node *body = ap;
theme_tag *T = Tags__find_by_name(TL_IS_297, FALSE);
if ((T) && (Tags__tagged_with(P, T)))
{
#line 597 "inweb/Chapter 3/The Weaver.w"
tree_node *E = WeaveTree__endnote(tree);
Trees__make_child(E, body); ap = E;
TextWeaver__commentary_text(tree, ap, TL_IS_298);
TEMPORARY_TEXT(url)
int ext = FALSE;
if (Colonies__resolve_reference_in_weave(url, NULL, wv->weave_to,
TL_IS_299, wv->weave_web->md, NULL, &ext))
Trees__make_child(WeaveTree__url(tree, url, TL_IS_300, ext), ap);
else
TextWeaver__commentary_text(tree, ap, TL_IS_301);
DISCARD_TEXT(url)
TextWeaver__commentary_text(tree, ap, TL_IS_302);
}
#line 584 "inweb/Chapter 3/The Weaver.w"
;
Tags__show_endnote_on_ifdefs(tree, ap, P);
if (P->defines_macro)
{
#line 611 "inweb/Chapter 3/The Weaver.w"
tree_node *E = WeaveTree__endnote(tree);
Trees__make_child(E, body); ap = E;
TextWeaver__commentary_text(tree, ap, TL_IS_303);
int ct = 0;
macro_usage *mu;
LOOP_OVER_LINKED_LIST(mu, macro_usage, P->defines_macro->macro_usages)
ct++;
if (ct == 1) TextWeaver__commentary_text(tree, ap, TL_IS_304);
else {
int k = 0, used_flag = FALSE;
LOOP_OVER_LINKED_LIST(mu, macro_usage, P->defines_macro->macro_usages)
if (P != mu->used_in_paragraph) {
if (used_flag) {
if (k < ct-1) TextWeaver__commentary_text(tree, ap, TL_IS_305);
else TextWeaver__commentary_text(tree, ap, TL_IS_306);
} else {
TextWeaver__commentary_text(tree, ap, TL_IS_307);
}
Trees__make_child(WeaveTree__locale(tree, mu->used_in_paragraph, NULL), ap);
used_flag = TRUE; k++;
switch (mu->multiplicity) {
case 1: break;
case 2: TextWeaver__commentary_text(tree, ap, TL_IS_308); break;
case 3: TextWeaver__commentary_text(tree, ap, TL_IS_309); break;
case 4: TextWeaver__commentary_text(tree, ap, TL_IS_310); break;
case 5: TextWeaver__commentary_text(tree, ap, TL_IS_311); break;
default: {
TEMPORARY_TEXT(mt)
WRITE_TO(mt, " (%d times)", mu->multiplicity);
TextWeaver__commentary_text(tree, ap, mt);
DISCARD_TEXT(mt)
break;
}
}
}
}
TextWeaver__commentary_text(tree, ap, TL_IS_312);
}
#line 587 "inweb/Chapter 3/The Weaver.w"
;
language_function *fn;
LOOP_OVER_LINKED_LIST(fn, language_function, P->functions)
{
#line 650 "inweb/Chapter 3/The Weaver.w"
if (fn->usage_described == FALSE)
Weaver__show_function_usage(tree, wv, ap, P, fn, FALSE);
}
#line 590 "inweb/Chapter 3/The Weaver.w"
;
language_type *st;
LOOP_OVER_LINKED_LIST(st, language_type, P->structures)
{
#line 654 "inweb/Chapter 3/The Weaver.w"
tree_node *E = WeaveTree__endnote(tree);
Trees__make_child(E, body); ap = E;
TextWeaver__commentary_text(tree, ap, TL_IS_313);
TextWeaver__commentary_text(tree, ap, st->structure_name);
section *S;
LOOP_OVER(S, section) S->scratch_flag = FALSE;
structure_element *elt;
LOOP_OVER_LINKED_LIST(elt, structure_element, st->elements) {
hash_table_entry *hte =
Analyser__find_hash_entry_for_section(elt->element_created_at->owning_section,
elt->element_name, FALSE);
if (hte) {
hash_table_entry_usage *hteu;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if (hteu->form_of_usage & ELEMENT_ACCESS_USAGE)
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
}
}
int usage_count = 0, external = 0;
LOOP_OVER(S, section)
if (S->scratch_flag) {
usage_count++;
if (S != P->under_section) external++;
}
if (external == 0) TextWeaver__commentary_text(tree, ap, TL_IS_314);
else {
TextWeaver__commentary_text(tree, ap, TL_IS_315);
int c = 0;
LOOP_OVER(S, section)
if ((S->scratch_flag) && (S != P->under_section)) {
if (c++ > 0) TextWeaver__commentary_text(tree, ap, TL_IS_316);
TextWeaver__commentary_text(tree, ap, S->md->sect_range);
}
if (P->under_section->scratch_flag) TextWeaver__commentary_text(tree, ap, TL_IS_317);
}
TextWeaver__commentary_text(tree, ap, TL_IS_318);
}
#line 593 "inweb/Chapter 3/The Weaver.w"
;
}
#line 694 "inweb/Chapter 3/The Weaver.w"
void Weaver__show_function_usage(heterogeneous_tree *tree, weave_order *wv,
tree_node *ap, paragraph *P, language_function *fn, int as_list) {
tree_node *body = ap;
fn->usage_described = TRUE;
hash_table_entry *hte =
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
fn->function_name, FALSE);
if (as_list == FALSE) {
tree_node *E = WeaveTree__endnote(tree);
Trees__make_child(E, body); ap = E;
TextWeaver__commentary_text(tree, ap, TL_IS_319);
TextWeaver__commentary_text(tree, ap, fn->function_name);
}
int used_flag = FALSE;
hash_table_entry_usage *hteu = NULL;
section *last_cited_in = NULL;
int count_under = 0;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if ((P != hteu->usage_recorded_at) &&
(P->under_section == hteu->usage_recorded_at->under_section))
{
#line 733 "inweb/Chapter 3/The Weaver.w"
if (as_list == FALSE) {
if (used_flag == FALSE) TextWeaver__commentary_text(tree, ap, TL_IS_324);
}
used_flag = TRUE;
section *S = hteu->usage_recorded_at->under_section;
if ((S != last_cited_in) && (S != P->under_section)) {
count_under = 0;
if (last_cited_in) {
if (as_list == FALSE) {
if (last_cited_in != P->under_section) TextWeaver__commentary_text(tree, ap, TL_IS_325);
else TextWeaver__commentary_text(tree, ap, TL_IS_326);
} else {
Trees__make_child(WeaveTree__linebreak(tree), ap);
}
}
TextWeaver__commentary_text(tree, ap, hteu->usage_recorded_at->under_section->md->sect_title);
if (as_list == FALSE) TextWeaver__commentary_text(tree, ap, TL_IS_327);
else TextWeaver__commentary_text(tree, ap, TL_IS_328);
}
if (count_under++ > 0) TextWeaver__commentary_text(tree, ap, TL_IS_329);
Trees__make_child(WeaveTree__locale(tree, hteu->usage_recorded_at, NULL), ap);
last_cited_in = hteu->usage_recorded_at->under_section;
}
#line 714 "inweb/Chapter 3/The Weaver.w"
;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if (P->under_section != hteu->usage_recorded_at->under_section)
{
#line 733 "inweb/Chapter 3/The Weaver.w"
if (as_list == FALSE) {
if (used_flag == FALSE) TextWeaver__commentary_text(tree, ap, TL_IS_324);
}
used_flag = TRUE;
section *S = hteu->usage_recorded_at->under_section;
if ((S != last_cited_in) && (S != P->under_section)) {
count_under = 0;
if (last_cited_in) {
if (as_list == FALSE) {
if (last_cited_in != P->under_section) TextWeaver__commentary_text(tree, ap, TL_IS_325);
else TextWeaver__commentary_text(tree, ap, TL_IS_326);
} else {
Trees__make_child(WeaveTree__linebreak(tree), ap);
}
}
TextWeaver__commentary_text(tree, ap, hteu->usage_recorded_at->under_section->md->sect_title);
if (as_list == FALSE) TextWeaver__commentary_text(tree, ap, TL_IS_327);
else TextWeaver__commentary_text(tree, ap, TL_IS_328);
}
if (count_under++ > 0) TextWeaver__commentary_text(tree, ap, TL_IS_329);
Trees__make_child(WeaveTree__locale(tree, hteu->usage_recorded_at, NULL), ap);
last_cited_in = hteu->usage_recorded_at->under_section;
}
#line 717 "inweb/Chapter 3/The Weaver.w"
;
if (used_flag == FALSE) {
if (as_list == FALSE) {
TextWeaver__commentary_text(tree, ap, TL_IS_320);
} else {
TextWeaver__commentary_text(tree, ap, TL_IS_321);
}
}
if (as_list == FALSE) {
if ((last_cited_in != P->under_section) && (last_cited_in))
TextWeaver__commentary_text(tree, ap, TL_IS_322);
TextWeaver__commentary_text(tree, ap, TL_IS_323);
}
}
#line 759 "inweb/Chapter 3/The Weaver.w"
void Weaver__weave_subheading(heterogeneous_tree *tree, weave_order *wv,
tree_node *ap, text_stream *text) {
tree_node *D = WeaveTree__subheading(tree, text);
Trees__make_child(D, ap);
}
void Weaver__change_material(heterogeneous_tree *tree,
weaver_state *state, int new_material, int plainly, programming_language *pl,
text_stream *note) {
if (state->kind_of_material != new_material) {
tree_node *D = WeaveTree__material(tree, new_material, plainly, pl, note);
if (state->carousel_node) Trees__make_child(D, state->carousel_node);
else Trees__make_child(D, state->para_node);
state->material_node = D;
state->ap = D;
state->kind_of_material = new_material;
}
}
void Weaver__change_material_for_para(heterogeneous_tree *tree, weaver_state *state) {
tree_node *D = WeaveTree__material(tree, COMMENTARY_MATERIAL, FALSE, NULL, NULL);
Trees__make_child(D, state->para_node);
state->material_node = D;
state->ap = D;
state->kind_of_material = COMMENTARY_MATERIAL;
}
void Weaver__figure(heterogeneous_tree *tree, weave_order *wv,
tree_node *ap, text_stream *figname, int w, int h) {
tree_node *F = WeaveTree__figure(tree, figname, w, h);
Trees__make_child(F, ap);
}
void Weaver__commentary_text(heterogeneous_tree *tree, weave_order *wv,
tree_node *ap, text_stream *matter) {
TextWeaver__commentary_text(tree, ap, matter);
}
#line 802 "inweb/Chapter 3/The Weaver.w"
int Weaver__weave_table_of_contents(heterogeneous_tree *tree,
tree_node *ap, section *S) {
int noteworthy = 0;
paragraph *P;
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
if ((P->weight > 0) && ((S->barred == FALSE) || (P->above_bar == FALSE)))
noteworthy++;
if (noteworthy == 0) return FALSE;
tree_node *TOC = WeaveTree__table_of_contents(tree, S->md->sect_range);
Trees__make_child(TOC, ap);
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
if ((P->weight > 0) && ((S->barred == FALSE) || (P->above_bar == FALSE))) {
TEMPORARY_TEXT(loc)
WRITE_TO(loc, "%S%S", P->ornament, P->paragraph_number);
Trees__make_child(
WeaveTree__contents_line(tree, loc,
P->first_line_in_paragraph->text_operand, P), TOC);
DISCARD_TEXT(loc)
}
return TRUE;
}
#line 12 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__commentary_text(heterogeneous_tree *tree, tree_node *ap, text_stream *matter) {
TextWeaver__commentary_r(tree, ap, matter, FALSE, FALSE);
}
void TextWeaver__comment_text_in_code(heterogeneous_tree *tree, tree_node *ap, text_stream *matter) {
TextWeaver__commentary_r(tree, ap, matter, FALSE, TRUE);
}
void TextWeaver__commentary_r(heterogeneous_tree *tree, tree_node *ap, text_stream *matter,
int within, int in_code) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
weave_order *wv = C->wv;
text_stream *code_in_comments_notation =
Bibliographic__get_datum(wv->weave_web->md,
(in_code)?(TL_IS_330):(TL_IS_331));
if (Str__ne(code_in_comments_notation, TL_IS_332))
{
#line 51 "inweb/Chapter 3/The Weaver of Text.w"
for (int i=0; i < Str__len(matter); i++) {
if (Str__get_at(matter, i) == '\\') i += Str__len(code_in_comments_notation) - 1;
else if (Str__includes_at(matter, i, code_in_comments_notation)) {
TEMPORARY_TEXT(before)
Str__copy(before, matter); Str__truncate(before, i);
TEMPORARY_TEXT(after)
Str__substr(after, Str__at(matter,
i + Str__len(code_in_comments_notation)), Str__end(matter));
TextWeaver__commentary_r(tree, ap, before, within, in_code);
TextWeaver__commentary_r(tree, ap, after, (within)?FALSE:TRUE, in_code);
DISCARD_TEXT(before)
DISCARD_TEXT(after)
return;
}
}
}
#line 26 "inweb/Chapter 3/The Weaver of Text.w"
;
int display_flag = TRUE;
text_stream *tex_notation = Bibliographic__get_datum(wv->weave_web->md,
TL_IS_333);
if (Str__ne(tex_notation, TL_IS_334))
{
#line 99 "inweb/Chapter 3/The Weaver of Text.w"
int N = Str__len(tex_notation);
for (int i=0; i < Str__len(matter); i++) {
if ((within == FALSE) && (Str__includes_at(matter, i, tex_notation))) {
int j = i + N;
while (j < Str__len(matter)) {
if (Str__includes_at(matter, j, tex_notation)) {
int allow = FALSE;
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(maths)
TEMPORARY_TEXT(after)
Str__substr(before, Str__start(matter), Str__at(matter, i));
Str__substr(maths, Str__at(matter, i + N), Str__at(matter, j));
Str__substr(after, Str__at(matter, j + N), Str__end(matter));
TextWeaver__commentary_r(tree, ap, before, within, in_code);
Trees__make_child(WeaveTree__mathematics(tree, maths, display_flag), ap);
TextWeaver__commentary_r(tree, ap, after, within, in_code);
allow = TRUE;
DISCARD_TEXT(before)
DISCARD_TEXT(maths)
DISCARD_TEXT(after)
if (allow) return;
}
j++;
}
}
}
}
#line 31 "inweb/Chapter 3/The Weaver of Text.w"
;
display_flag = FALSE;
tex_notation = Bibliographic__get_datum(wv->weave_web->md,
TL_IS_335);
if (Str__ne(tex_notation, TL_IS_336))
{
#line 99 "inweb/Chapter 3/The Weaver of Text.w"
int N = Str__len(tex_notation);
for (int i=0; i < Str__len(matter); i++) {
if ((within == FALSE) && (Str__includes_at(matter, i, tex_notation))) {
int j = i + N;
while (j < Str__len(matter)) {
if (Str__includes_at(matter, j, tex_notation)) {
int allow = FALSE;
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(maths)
TEMPORARY_TEXT(after)
Str__substr(before, Str__start(matter), Str__at(matter, i));
Str__substr(maths, Str__at(matter, i + N), Str__at(matter, j));
Str__substr(after, Str__at(matter, j + N), Str__end(matter));
TextWeaver__commentary_r(tree, ap, before, within, in_code);
Trees__make_child(WeaveTree__mathematics(tree, maths, display_flag), ap);
TextWeaver__commentary_r(tree, ap, after, within, in_code);
allow = TRUE;
DISCARD_TEXT(before)
DISCARD_TEXT(maths)
DISCARD_TEXT(after)
if (allow) return;
}
j++;
}
}
}
}
#line 35 "inweb/Chapter 3/The Weaver of Text.w"
;
text_stream *xref_notation = Bibliographic__get_datum(wv->weave_web->md,
TL_IS_337);
if (Str__ne(xref_notation, TL_IS_338))
{
#line 150 "inweb/Chapter 3/The Weaver of Text.w"
int N = Str__len(xref_notation);
for (int i=0; i < Str__len(matter); i++) {
if ((within == FALSE) && (Str__includes_at(matter, i, xref_notation)) &&
((i == 0) || (TextWeaver__boundary_character(TRUE,
Str__get_at(matter, i-1))))) {
int j = i + N+1;
while (j < Str__len(matter)) {
if ((Str__includes_at(matter, j, xref_notation)) &&
(TextWeaver__boundary_character(FALSE,
Str__get_at(matter, j+Str__len(xref_notation))))) {
int allow = FALSE;
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(reference)
TEMPORARY_TEXT(after)
Str__substr(before, Str__start(matter), Str__at(matter, i));
Str__substr(reference, Str__at(matter, i + N), Str__at(matter, j));
Str__substr(after, Str__at(matter, j + N), Str__end(matter));
{
#line 179 "inweb/Chapter 3/The Weaver of Text.w"
TEMPORARY_TEXT(url)
TEMPORARY_TEXT(title)
int ext = FALSE;
if (Colonies__resolve_reference_in_weave(url, title, wv->weave_to, reference,
wv->weave_web->md, wv->current_weave_line, &ext)) {
TextWeaver__commentary_r(tree, ap, before, within, in_code);
Trees__make_child(WeaveTree__url(tree, url, title, ext), ap);
TextWeaver__commentary_r(tree, ap, after, within, in_code);
allow = TRUE;
}
DISCARD_TEXT(url)
DISCARD_TEXT(title)
}
#line 167 "inweb/Chapter 3/The Weaver of Text.w"
;
DISCARD_TEXT(before)
DISCARD_TEXT(reference)
DISCARD_TEXT(after)
if (allow) return;
}
j++;
}
}
}
}
#line 39 "inweb/Chapter 3/The Weaver of Text.w"
;
if (within) {
TextWeaver__inline_code_fragment(tree, ap, matter);
} else {
{
#line 68 "inweb/Chapter 3/The Weaver of Text.w"
for (int i=0; i < Str__len(matter); i++) {
if ((Str__includes_at(matter, i, TL_IS_339)) ||
(Str__includes_at(matter, i, TL_IS_340))) {
TEMPORARY_TEXT(before)
Str__copy(before, matter); Str__truncate(before, i);
TEMPORARY_TEXT(after)
Str__substr(after, Str__at(matter, i), Str__end(matter));
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, after, L"(https*://%C+)(%c*)")) {
while (TextWeaver__boundary_character(FALSE, Str__get_last_char(mr.exp[0]))) {
wchar_t c = Str__get_last_char(mr.exp[0]);
Str__delete_last_character(mr.exp[0]);
TEMPORARY_TEXT(longer)
WRITE_TO(longer, "%c%S", c, mr.exp[1]);
Str__clear(mr.exp[1]);
Str__copy(mr.exp[1], longer);
DISCARD_TEXT(longer)
}
TextWeaver__commentary_r(tree, ap, before, within, in_code);
Trees__make_child(WeaveTree__url(tree, mr.exp[0], mr.exp[0], TRUE), ap);
TextWeaver__commentary_r(tree, ap, mr.exp[1], within, in_code);
Regexp__dispose_of(&mr);
return;
}
Regexp__dispose_of(&mr);
DISCARD_TEXT(before)
DISCARD_TEXT(after)
}
}
}
#line 44 "inweb/Chapter 3/The Weaver of Text.w"
;
{
#line 127 "inweb/Chapter 3/The Weaver of Text.w"
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(cue)
TEMPORARY_TEXT(after)
int allow = FALSE;
if (Parser__detect_footnote(wv->weave_web, matter, before, cue, after)) {
footnote *F = Parser__find_footnote_in_para(
wv->current_weave_line->owning_paragraph, cue);
if (F) {
F->cued_already = TRUE;
allow = TRUE;
TextWeaver__commentary_r(tree, ap, before, within, in_code);
Trees__make_child(WeaveTree__footnote_cue(tree, F->cue_text), ap);
TextWeaver__commentary_r(tree, ap, after, within, in_code);
} else {
Main__error_in_web(TL_IS_341, wv->current_weave_line);
}
}
DISCARD_TEXT(before)
DISCARD_TEXT(cue)
DISCARD_TEXT(after)
if (allow) return;
}
#line 45 "inweb/Chapter 3/The Weaver of Text.w"
;
TextWeaver__commentary_fragment(tree, ap, matter, in_code);
}
}
#line 200 "inweb/Chapter 3/The Weaver of Text.w"
int TextWeaver__boundary_character(int before, wchar_t c) {
if (c == 0) return TRUE;
if (Characters__is_whitespace(c)) return TRUE;
if ((c == '.') || (c == ',') || (c == '!') || (c == '?') || (c == ';') ||
(c == '(')|| (c == ')')) return TRUE;
if ((before == FALSE) && (c == ':')) return TRUE;
return FALSE;
}
#line 210 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__commentary_fragment(heterogeneous_tree *tree, tree_node *ap,
text_stream *fragment, int in_code) {
if (Str__len(fragment) > 0)
Trees__make_child(WeaveTree__commentary(tree, fragment, in_code), ap);
}
void TextWeaver__inline_code_fragment(heterogeneous_tree *tree, tree_node *ap, text_stream *fragment) {
tree_node *I = WeaveTree__inline(tree);
Trees__make_child(I, ap);
TEMPORARY_TEXT(colouring)
for (int i=0; i< Str__len(fragment); i++) PUT_TO(colouring, EXTRACT_COLOUR);
tree_node *SC = WeaveTree__source_code(tree, fragment, colouring);
DISCARD_TEXT(colouring)
Trees__make_child(SC, I);
}
#line 229 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__source_code(heterogeneous_tree *tree, tree_node *ap,
text_stream *matter, text_stream *colouring, int linked) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
weave_order *wv = C->wv;
Str__truncate(colouring, Str__len(matter));
int from = 0;
for (int i=0; i < Str__len(matter); i++) {
if (linked) {
{
#line 261 "inweb/Chapter 3/The Weaver of Text.w"
if ((Str__includes_at(matter, i, TL_IS_344)) ||
(Str__includes_at(matter, i, TL_IS_345))) {
TEMPORARY_TEXT(after)
Str__substr(after, Str__at(matter, i), Str__end(matter));
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, after, L"(https*://%C+)(%c*)")) {
tree_node *U = WeaveTree__url(tree, mr.exp[0], mr.exp[0], TRUE);
TextWeaver__source_code_piece(tree, ap, matter, colouring, from, i);
Trees__make_child(U, ap);
i += Str__len(mr.exp[0]);
from = i;
}
DISCARD_TEXT(after)
}
}
#line 237 "inweb/Chapter 3/The Weaver of Text.w"
;
text_stream *xref_notation = Bibliographic__get_datum(wv->weave_web->md,
TL_IS_342);
if (Str__ne(xref_notation, TL_IS_343))
{
#line 277 "inweb/Chapter 3/The Weaver of Text.w"
int N = Str__len(xref_notation);
if ((Str__includes_at(matter, i, xref_notation))) {
int j = i + N+1;
while (j < Str__len(matter)) {
if (Str__includes_at(matter, j, xref_notation)) {
TEMPORARY_TEXT(reference)
Str__substr(reference, Str__at(matter, i + N), Str__at(matter, j));
{
#line 293 "inweb/Chapter 3/The Weaver of Text.w"
TEMPORARY_TEXT(url)
TEMPORARY_TEXT(title)
int ext = FALSE;
if (Colonies__resolve_reference_in_weave(url, title, wv->weave_to, reference,
wv->weave_web->md, wv->current_weave_line, &ext)) {
tree_node *U = WeaveTree__url(tree, url, title, ext);
TextWeaver__source_code_piece(tree, ap, matter, colouring, from, i);
Trees__make_child(U, ap);
i = j + N;
from = i;
}
DISCARD_TEXT(url)
DISCARD_TEXT(title)
}
#line 284 "inweb/Chapter 3/The Weaver of Text.w"
;
DISCARD_TEXT(reference)
break;
}
j++;
}
}
}
#line 241 "inweb/Chapter 3/The Weaver of Text.w"
;
}
if ((Str__get_at(colouring, i) == FUNCTION_COLOUR) &&
(wv->current_weave_line->category != TEXT_EXTRACT_LCAT)) {
TEMPORARY_TEXT(fname)
int j = i;
while (Str__get_at(colouring, j) == FUNCTION_COLOUR)
PUT_TO(fname, Str__get_at(matter, j++));
if (Analyser__is_reserved_word_for_section(
wv->current_weave_line->owning_section, fname, FUNCTION_COLOUR))
{
#line 308 "inweb/Chapter 3/The Weaver of Text.w"
language_function *fn = Analyser__get_function(
wv->current_weave_line->owning_section, fname, FUNCTION_COLOUR);
if (fn) {
source_line *defn_line = fn->function_header_at;
if (wv->current_weave_line == defn_line) {
if (fn->usage_described == FALSE) {
TextWeaver__source_code_piece(tree, ap, matter, colouring, from, i);
tree_node *FD = WeaveTree__function_defn(tree, fn);
Trees__make_child(FD, ap);
Weaver__show_function_usage(tree, wv, FD,
defn_line->owning_paragraph, fn, TRUE);
i += Str__len(fname) - 1;
from = i+1;
}
} else {
TextWeaver__source_code_piece(tree, ap, matter, colouring, from, i);
TEMPORARY_TEXT(url)
Colonies__paragraph_URL(url, defn_line->owning_paragraph, wv->weave_to);
tree_node *U = WeaveTree__function_usage(tree, url, fn);
Trees__make_child(U, ap);
i += Str__len(fname) - 1;
from = i+1;
}
}
}
#line 251 "inweb/Chapter 3/The Weaver of Text.w"
;
DISCARD_TEXT(fname)
}
}
if (from < Str__len(matter))
TextWeaver__source_code_piece(tree, ap, matter, colouring, from, Str__len(matter));
}
#line 334 "inweb/Chapter 3/The Weaver of Text.w"
void TextWeaver__source_code_piece(heterogeneous_tree *tree, tree_node *ap,
text_stream *matter, text_stream *colouring, int from, int to) {
if (to > from) {
TEMPORARY_TEXT(m)
TEMPORARY_TEXT(c)
Str__substr(m, Str__at(matter, from), Str__at(matter, to));
Str__substr(c, Str__at(colouring, from), Str__at(colouring, to));
tree_node *SC = WeaveTree__source_code(tree, m, c);
Trees__make_child(SC, ap);
DISCARD_TEXT(m)
DISCARD_TEXT(c)
}
}
#line 14 "inweb/Chapter 3/The Tangler.w"
void Tangler__tangle(web *W, tangle_target *target, filename *dest_file) {
programming_language *lang = target->tangle_language;
PRINT(" tangling <%/f> (written in %S)\n", dest_file, lang->language_name);
text_stream TO_struct;
text_stream *OUT = &TO_struct;
if (STREAM_OPEN_TO_FILE(OUT, dest_file, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to write tangled file", dest_file);
{
#line 40 "inweb/Chapter 3/The Tangler.w"
/* (a) The shebang line, a header for scripting languages, and other heading matter */
LanguageMethods__shebang(OUT, lang, W, target);
LanguageMethods__disclaimer(OUT, lang, W, target);
LanguageMethods__additional_early_matter(OUT, lang, W, target);
chapter *C; section *S; paragraph *P;
LOOP_OVER_PARAGRAPHS(C, S, target, P)
if ((P->placed_very_early) && (P->defines_macro == NULL))
Tangler__tangle_paragraph(OUT, P);
/* (b) Results of |@d| declarations */
{
#line 72 "inweb/Chapter 3/The Tangler.w"
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, target)
if (L->category == BEGIN_DEFINITION_LCAT)
if (L->default_defn == FALSE)
{
#line 88 "inweb/Chapter 3/The Tangler.w"
if (L->owning_paragraph == NULL) Main__error_in_web(TL_IS_346, L);
else Tags__open_ifdefs(OUT, L->owning_paragraph);
LanguageMethods__start_definition(OUT, lang,
L->text_operand,
L->text_operand2, S, L);
while ((L->next_line) && (L->next_line->category == CONT_DEFINITION_LCAT)) {
L = L->next_line;
LanguageMethods__prolong_definition(OUT, lang, L->text, S, L);
}
LanguageMethods__end_definition(OUT, lang, S, L);
if (L->owning_paragraph) Tags__close_ifdefs(OUT, L->owning_paragraph);
}
#line 77 "inweb/Chapter 3/The Tangler.w"
;
LOOP_WITHIN_TANGLE(C, S, target)
if (L->category == BEGIN_DEFINITION_LCAT)
if (L->default_defn) {
LanguageMethods__open_ifdef(OUT, lang, L->text_operand, FALSE);
{
#line 88 "inweb/Chapter 3/The Tangler.w"
if (L->owning_paragraph == NULL) Main__error_in_web(TL_IS_346, L);
else Tags__open_ifdefs(OUT, L->owning_paragraph);
LanguageMethods__start_definition(OUT, lang,
L->text_operand,
L->text_operand2, S, L);
while ((L->next_line) && (L->next_line->category == CONT_DEFINITION_LCAT)) {
L = L->next_line;
LanguageMethods__prolong_definition(OUT, lang, L->text, S, L);
}
LanguageMethods__end_definition(OUT, lang, S, L);
if (L->owning_paragraph) Tags__close_ifdefs(OUT, L->owning_paragraph);
}
#line 82 "inweb/Chapter 3/The Tangler.w"
;
LanguageMethods__close_ifdef(OUT, lang, L->text_operand, FALSE);
}
Enumerations__define_extents(OUT, target, lang);
}
#line 50 "inweb/Chapter 3/The Tangler.w"
;
/* (c) Miscellaneous automated C predeclarations */
LanguageMethods__additional_predeclarations(OUT, lang, W);
/* (d) Above-the-bar code from all of the sections (global variables, and such) */
LOOP_OVER_PARAGRAPHS(C, S, target, P)
if ((P->placed_early) && (P->defines_macro == NULL))
Tangler__tangle_paragraph(OUT, P);
/* (e) Below-the-bar code: the bulk of the program itself */
LOOP_OVER_PARAGRAPHS(C, S, target, P)
if ((P->placed_early == FALSE) && (P->placed_very_early == FALSE) && (P->defines_macro == NULL))
Tangler__tangle_paragraph(OUT, P);
/* (f) Opposite of the shebang: a footer */
LanguageMethods__gnabehs(OUT, lang, W);
}
#line 22 "inweb/Chapter 3/The Tangler.w"
;
STREAM_CLOSE(OUT);
{
#line 101 "inweb/Chapter 3/The Tangler.w"
filename *F;
LOOP_OVER_LINKED_LIST(F, filename, W->headers)
Shell__copy(F, Reader__tangled_folder(W), "");
}
#line 25 "inweb/Chapter 3/The Tangler.w"
;
{
#line 112 "inweb/Chapter 3/The Tangler.w"
text_stream *extract_names[MAX_EXTRACT_FILES];
text_stream extract_files[MAX_EXTRACT_FILES];
int no_extract_files = 0;
chapter *C; section *S; paragraph *P;
LOOP_OVER_PARAGRAPHS(C, S, target, P)
for (source_line *L = P->first_line_in_paragraph;
((L) && (L->owning_paragraph == P)); L = L->next_line)
if (Str__len(L->extract_to) > 0) {
int j = no_extract_files;
for (int i=0; i<no_extract_files; i++)
if (Str__eq(L->extract_to, extract_names[i])) j = i;
if (j == no_extract_files) {
if (j == MAX_EXTRACT_FILES)
Errors__fatal("too many extract files in tangle");
extract_names[j] = Str__duplicate(L->extract_to);
filename *F = Filenames__in(Filenames__up(dest_file), L->extract_to);
if (STREAM_OPEN_TO_FILE(&(extract_files[j]), F, UTF8_ENC) == FALSE)
Errors__fatal_with_file("unable to write extract file", F);
no_extract_files++;
}
WRITE_TO(&(extract_files[j]), "%S\n", L->text);
}
for (int i=0; i<no_extract_files; i++) STREAM_CLOSE(&(extract_files[i]));
}
#line 26 "inweb/Chapter 3/The Tangler.w"
;
LanguageMethods__additional_tangling(lang, W, target);
}
#line 141 "inweb/Chapter 3/The Tangler.w"
void Tangler__tangle_paragraph(OUTPUT_STREAM, paragraph *P) {
Tags__open_ifdefs(OUT, P);
int contiguous = FALSE;
for (source_line *L = P->first_line_in_paragraph;
((L) && (L->owning_paragraph == P)); L = L->next_line) {
if (LanguageMethods__will_insert_in_tangle(P->under_section->sect_language, L)) {
{
#line 166 "inweb/Chapter 3/The Tangler.w"
if (contiguous == FALSE) {
contiguous = TRUE;
LanguageMethods__insert_line_marker(OUT, P->under_section->sect_language, L);
}
}
#line 147 "inweb/Chapter 3/The Tangler.w"
;
LanguageMethods__insert_in_tangle(OUT, P->under_section->sect_language, L);
}
if ((L->category != CODE_BODY_LCAT) || (L->suppress_tangling)) {
contiguous = FALSE;
} else {
{
#line 166 "inweb/Chapter 3/The Tangler.w"
if (contiguous == FALSE) {
contiguous = TRUE;
LanguageMethods__insert_line_marker(OUT, P->under_section->sect_language, L);
}
}
#line 153 "inweb/Chapter 3/The Tangler.w"
;
Tangler__tangle_line(OUT, L->text, P->under_section, L); WRITE("\n");
}
}
Tags__close_ifdefs(OUT, P);
}
#line 176 "inweb/Chapter 3/The Tangler.w"
void Tangler__tangle_line(OUTPUT_STREAM, text_stream *original, section *S, source_line *L) {
int mlen, slen;
int mpos = Regexp__find_expansion(original, '@', '<', '@', '>', &mlen);
int spos = Regexp__find_expansion(original, '[', '[', ']', ']', &slen);
if ((mpos >= 0) && ((spos == -1) || (mpos <= spos)) &&
(LanguageMethods__allow_expansion(S->sect_language, original)))
{
#line 208 "inweb/Chapter 3/The Tangler.w"
TEMPORARY_TEXT(temp)
Str__copy(temp, original); Str__truncate(temp, mpos);
LanguageMethods__tangle_line(OUT, S->sect_language, temp);
programming_language *lang = S->sect_language;
for (int i=0; i<mlen-4; i++) Str__put_at(temp, i, Str__get_at(original, mpos+2+i));
Str__truncate(temp, mlen-4);
para_macro *pmac = Macros__find_by_name(temp, S);
if (pmac) {
LanguageMethods__before_macro_expansion(OUT, lang, pmac);
Tangler__tangle_paragraph(OUT, pmac->defining_paragraph);
LanguageMethods__after_macro_expansion(OUT, lang, pmac);
LanguageMethods__insert_line_marker(OUT, lang, L);
} else {
Main__error_in_web(TL_IS_347, L);
WRITE_TO(STDERR, "Macro is '%S'\n", temp);
LanguageMethods__comment(OUT, lang, temp); /* recover by putting macro name in comment */
}
TEMPORARY_TEXT(rest)
Str__substr(rest, Str__at(original, mpos + mlen), Str__end(original));
Tangler__tangle_line(OUT, rest, S, L);
DISCARD_TEXT(rest)
DISCARD_TEXT(temp)
}
#line 182 "inweb/Chapter 3/The Tangler.w"
else if (spos >= 0)
{
#line 248 "inweb/Chapter 3/The Tangler.w"
web *W = S->owning_web;
TEMPORARY_TEXT(temp)
for (int i=0; i<spos; i++) PUT_TO(temp, Str__get_at(original, i));
LanguageMethods__tangle_line(OUT, S->sect_language, temp);
for (int i=0; i<slen-4; i++) Str__put_at(temp, i, Str__get_at(original, spos+2+i));
Str__truncate(temp, slen-4);
if (LanguageMethods__special_tangle_command(OUT, S->sect_language, temp) == FALSE) {
if (Bibliographic__look_up_datum(W->md, temp))
WRITE("%S", Bibliographic__get_datum(W->md, temp));
else
WRITE("[[%S]]", temp);
}
TEMPORARY_TEXT(rest)
Str__substr(rest, Str__at(original, spos + slen), Str__end(original));
Tangler__tangle_line(OUT, rest, S, L);
DISCARD_TEXT(rest)
DISCARD_TEXT(temp)
}
#line 184 "inweb/Chapter 3/The Tangler.w"
else
LanguageMethods__tangle_line(OUT, S->sect_language, original); /* this is usually what happens */
}
#line 273 "inweb/Chapter 3/The Tangler.w"
tangle_target *Tangler__primary_target(web *W) {
if (W == NULL) internal_error("no such web");
return FIRST_IN_LINKED_LIST(tangle_target, W->tangle_targets);
}
#line 10 "inweb/Chapter 4/Programming Languages.w"
programming_language *Languages__find_by_name(text_stream *lname, web *W,
int error_if_not_found) {
programming_language *pl;
{
#line 22 "inweb/Chapter 4/Programming Languages.w"
LOOP_OVER(pl, programming_language)
if (Str__eq(lname, pl->language_name))
return pl;
}
#line 13 "inweb/Chapter 4/Programming Languages.w"
;
{
#line 27 "inweb/Chapter 4/Programming Languages.w"
filename *F = NULL;
if (W) {
pathname *P = Pathnames__down(W->md->path_to_web, TL_IS_348);
{
#line 43 "inweb/Chapter 4/Programming Languages.w"
if (F == NULL) {
TEMPORARY_TEXT(leaf)
WRITE_TO(leaf, "%S.ildf", lname);
F = Filenames__in(P, leaf);
DISCARD_TEXT(leaf)
if (TextFiles__exists(F) == FALSE) F = NULL;
}
}
#line 30 "inweb/Chapter 4/Programming Languages.w"
;
}
pathname *P = Languages__default_directory();
{
#line 43 "inweb/Chapter 4/Programming Languages.w"
if (F == NULL) {
TEMPORARY_TEXT(leaf)
WRITE_TO(leaf, "%S.ildf", lname);
F = Filenames__in(P, leaf);
DISCARD_TEXT(leaf)
if (TextFiles__exists(F) == FALSE) F = NULL;
}
}
#line 33 "inweb/Chapter 4/Programming Languages.w"
;
if (F == NULL) {
if (error_if_not_found)
Errors__fatal_with_text(
"unsupported programming language '%S'", lname);
return NULL;
}
pl = Languages__read_definition(F);
}
#line 14 "inweb/Chapter 4/Programming Languages.w"
;
if (Str__ne(pl->language_name, lname))
Errors__fatal_with_text(
"definition of programming language '%S' is for something else", lname);
return pl;
}
#line 54 "inweb/Chapter 4/Programming Languages.w"
programming_language *Languages__default(web *W) {
return Languages__find_by_name(TL_IS_349, W, TRUE);
}
void Languages__show(OUTPUT_STREAM) {
WRITE("Inweb can see the following programming language definitions:\n\n");
int N = NUMBER_CREATED(programming_language);
programming_language **sorted_table =
Memory__calloc(N, (int) sizeof(programming_language *), ARRAY_SORTING_MREASON);
int i=0; programming_language *pl;
LOOP_OVER(pl, programming_language) sorted_table[i++] = pl;
qsort(sorted_table, (size_t) N, sizeof(programming_language *), Languages__compare_names);
for (int i=0; i<N; i++) {
programming_language *pl = sorted_table[i];
WRITE("%S: %S\n", pl->language_name, pl->language_details);
}
Memory__I7_free(sorted_table, ARRAY_SORTING_MREASON, N*((int) sizeof(programming_language *)));
}
#line 75 "inweb/Chapter 4/Programming Languages.w"
int Languages__compare_names(const void *ent1, const void *ent2) {
text_stream *tx1 = (*((const programming_language **) ent1))->language_name;
text_stream *tx2 = (*((const programming_language **) ent2))->language_name;
return Str__cmp_insensitive(tx1, tx2);
}
#line 84 "inweb/Chapter 4/Programming Languages.w"
void Languages__read_definitions(pathname *P) {
if (P == NULL) P = Languages__default_directory();
scan_directory *D = Directories__open(P);
TEMPORARY_TEXT(leafname)
while (Directories__next(D, leafname)) {
if (Platform__is_folder_separator(Str__get_last_char(leafname)) == FALSE) {
filename *F = Filenames__in(P, leafname);
Languages__read_definition(F);
}
}
DISCARD_TEXT(leafname)
Directories__close(D);
}
pathname *Languages__default_directory(void) {
return Pathnames__down(path_to_inweb, TL_IS_350);
}
#line 148 "inweb/Chapter 4/Programming Languages.w"
#line 160 "inweb/Chapter 4/Programming Languages.w"
programming_language *Languages__read_definition(filename *F) {
programming_language *pl = CREATE(programming_language);
{
#line 174 "inweb/Chapter 4/Programming Languages.w"
pl->language_name = NULL;
pl->file_extension = NULL;
pl->supports_namespaces = FALSE;
pl->line_comment = NULL;
pl->whole_line_comment = NULL;
pl->multiline_comment_open = NULL;
pl->multiline_comment_close = NULL;
pl->string_literal = NULL;
pl->string_literal_escape = NULL;
pl->character_literal = NULL;
pl->character_literal_escape = NULL;
pl->binary_literal_prefix = NULL;
pl->octal_literal_prefix = NULL;
pl->hexadecimal_literal_prefix = NULL;
pl->negative_literal_prefix = NULL;
pl->shebang = NULL;
pl->line_marker = NULL;
pl->before_macro_expansion = NULL;
pl->after_macro_expansion = NULL;
pl->start_definition = NULL;
pl->prolong_definition = NULL;
pl->end_definition = NULL;
pl->start_ifdef = NULL;
pl->end_ifdef = NULL;
pl->start_ifndef = NULL;
pl->end_ifndef = NULL;
pl->C_like = FALSE;
pl->suppress_disclaimer = FALSE;
pl->type_notation[0] = 0;
pl->function_notation[0] = 0;
pl->reserved_words = NEW_LINKED_LIST(reserved_word);
Analyser__initialise_hash_table(&(pl->built_in_keywords));
pl->program = NULL;
pl->methods = Methods__new_set();
}
#line 163 "inweb/Chapter 4/Programming Languages.w"
;
language_reader_state lrs;
lrs.defining = pl;
lrs.current_block = NULL;
TextFiles__read(F, FALSE, "can't open programming language definition file",
TRUE, Languages__read_definition_line, NULL, (void *) &lrs);
{
#line 219 "inweb/Chapter 4/Programming Languages.w"
if (pl->C_like) CLike__make_c_like(pl);
if (Str__eq(pl->language_name, TL_IS_351)) InCSupport__add_features(pl);
ACMESupport__add_fallbacks(pl);
}
#line 169 "inweb/Chapter 4/Programming Languages.w"
;
return pl;
}
#line 226 "inweb/Chapter 4/Programming Languages.w"
void Languages__read_definition_line(text_stream *line, text_file_position *tfp, void *v_state) {
language_reader_state *state = (language_reader_state *) v_state;
programming_language *pl = state->defining;
Str__trim_white_space(line); /* ignore trailing space */
if (Str__len(line) == 0) return; /* ignore blank lines */
if (Str__get_first_char(line) == '#') return; /* lines opening with |#| are comments */
match_results mr = Regexp__create_mr();
if (state->current_block)
{
#line 327 "inweb/Chapter 4/Programming Languages.w"
if (Str__eq(line, TL_IS_383)) {
state->current_block = state->current_block->parent;
} else if (Regexp__match(&mr, line, L"characters {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block =
Languages__new_block(state->current_block, CHARACTERS_CRULE_RUN);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"characters in (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block =
Languages__new_block(state->current_block, CHARACTERS_IN_CRULE_RUN);
rule->execute_block->char_set = Languages__text(mr.exp[0], tfp, FALSE);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"runs of (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
wchar_t r = UNQUOTED_COLOUR;
if (Str__ne(mr.exp[0], TL_IS_384)) r = Languages__colour(mr.exp[0], tfp);
rule->execute_block = Languages__new_block(state->current_block, (int) r);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"instances of (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block = Languages__new_block(state->current_block, INSTANCES_CRULE_RUN);
rule->execute_block->run_instance = Languages__text(mr.exp[0], tfp, FALSE);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"matches of (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block = Languages__new_block(state->current_block, MATCHES_CRULE_RUN);
Languages__regexp(rule->execute_block->match_regexp_text, mr.exp[0], tfp);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"brackets in (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block = Languages__new_block(state->current_block, BRACKETS_CRULE_RUN);
Languages__regexp(rule->execute_block->match_regexp_text, mr.exp[0], tfp);
state->current_block = rule->execute_block;
} else {
int at = -1, quoted = FALSE;
for (int i=0; i<Str__len(line)-1; i++) {
if (Str__get_at(line, i) == '"') quoted = quoted?FALSE:TRUE;
if ((quoted) && (Str__get_at(line, i) == '\\')) i++;
if ((quoted == FALSE) &&
(Str__get_at(line, i) == '=') && (Str__get_at(line, i+1) == '>')) at = i;
}
if (at >= 0) {
TEMPORARY_TEXT(premiss)
TEMPORARY_TEXT(conclusion)
Str__substr(premiss, Str__start(line), Str__at(line, at));
Str__substr(conclusion, Str__at(line, at+2), Str__end(line));
Languages__parse_rule(state, premiss, conclusion, tfp);
DISCARD_TEXT(conclusion)
DISCARD_TEXT(premiss)
} else {
Errors__in_text_file("line in colouring block illegible", tfp);
}
}
}
#line 235 "inweb/Chapter 4/Programming Languages.w"
else
{
#line 244 "inweb/Chapter 4/Programming Languages.w"
if (Regexp__match(&mr, line, L"colouring {")) {
if (pl->program) Errors__in_text_file("duplicate colouring program", tfp);
pl->program = Languages__new_block(NULL, WHOLE_LINE_CRULE_RUN);
state->current_block = pl->program;
} else if (Regexp__match(&mr, line, L"keyword (%C+) of (%c+?)")) {
Languages__reserved(pl, Languages__text(mr.exp[0], tfp, FALSE), Languages__colour(mr.exp[1], tfp), tfp);
} else if (Regexp__match(&mr, line, L"keyword (%C+)")) {
Languages__reserved(pl, Languages__text(mr.exp[0], tfp, FALSE), RESERVED_COLOUR, tfp);
} else if (Regexp__match(&mr, line, L"(%c+) *: *(%c+?)")) {
text_stream *key = mr.exp[0], *value = Str__duplicate(mr.exp[1]);
if (Str__eq(key, TL_IS_352)) pl->language_name = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_353))
pl->language_details = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_354))
pl->file_extension = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_355))
pl->line_comment = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_356))
pl->whole_line_comment = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_357))
pl->multiline_comment_open = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_358))
pl->multiline_comment_close = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_359))
pl->string_literal = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_360))
pl->string_literal_escape = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_361))
pl->character_literal = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_362))
pl->character_literal_escape = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_363))
pl->binary_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_364))
pl->octal_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_365))
pl->hexadecimal_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_366))
pl->negative_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_367))
pl->shebang = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_368))
pl->line_marker = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_369))
pl->before_macro_expansion = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_370))
pl->after_macro_expansion = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_371))
pl->start_definition = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_372))
pl->prolong_definition = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_373))
pl->end_definition = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_374))
pl->start_ifdef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_375))
pl->start_ifndef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_376))
pl->end_ifdef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_377))
pl->end_ifndef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_378))
pl->C_like = Languages__boolean(value, tfp);
else if (Str__eq(key, TL_IS_379))
pl->suppress_disclaimer = Languages__boolean(value, tfp);
else if (Str__eq(key, TL_IS_380))
pl->supports_namespaces = Languages__boolean(value, tfp);
else if (Str__eq(key, TL_IS_381))
Languages__regexp(pl->function_notation, value, tfp);
else if (Str__eq(key, TL_IS_382))
Languages__regexp(pl->type_notation, value, tfp);
else {
Errors__in_text_file("unknown property name before ':'", tfp);
}
} else {
Errors__in_text_file("line in language definition illegible", tfp);
}
}
#line 236 "inweb/Chapter 4/Programming Languages.w"
;
Regexp__dispose_of(&mr);
}
#line 406 "inweb/Chapter 4/Programming Languages.w"
#line 408 "inweb/Chapter 4/Programming Languages.w"
colouring_language_block *Languages__new_block(colouring_language_block *within, int r) {
colouring_language_block *block = CREATE(colouring_language_block);
block->rules = NEW_LINKED_LIST(colouring_rule);
block->parent = within;
block->run = r;
block->run_instance = NULL;
block->char_set = NULL;
block->match_regexp_text[0] = 0;
block->mr = Regexp__create_mr();
return block;
}
#line 460 "inweb/Chapter 4/Programming Languages.w"
#line 462 "inweb/Chapter 4/Programming Languages.w"
colouring_rule *Languages__new_rule(colouring_language_block *within) {
if (within == NULL) internal_error("rule outside block");
colouring_rule *rule = CREATE(colouring_rule);
ADD_TO_LINKED_LIST(rule, colouring_rule, within->rules);
rule->sense = TRUE;
rule->match_colour = NOT_A_COLOUR;
rule->match_text = NULL;
rule->match_prefix = NOT_A_RULE_PREFIX;
rule->match_keyword_of_colour = NOT_A_COLOUR;
rule->match_regexp_text[0] = 0;
rule->number = 0;
rule->number_of = 0;
rule->set_to_colour = NOT_A_COLOUR;
rule->set_prefix_to_colour = NOT_A_COLOUR;
rule->execute_block = NULL;
rule->debug = FALSE;
rule->fix_position = 0;
rule->mr = Regexp__create_mr();
return rule;
}
#line 486 "inweb/Chapter 4/Programming Languages.w"
void Languages__parse_rule(language_reader_state *state, text_stream *premiss,
text_stream *action, text_file_position *tfp) {
match_results mr = Regexp__create_mr();
colouring_rule *rule = Languages__new_rule(state->current_block);
Str__trim_white_space(premiss); Str__trim_white_space(action);
{
#line 497 "inweb/Chapter 4/Programming Languages.w"
while (Regexp__match(&mr, premiss, L"not (%c+)")) {
rule->sense = (rule->sense)?FALSE:TRUE;
Str__clear(premiss); Str__copy(premiss, mr.exp[0]);
}
if (Regexp__match(&mr, premiss, L"number (%d+)")) {
rule->number = Str__atoi(mr.exp[0], 0);
} else if (Regexp__match(&mr, premiss, L"number (%d+) of (%d+)")) {
rule->number = Str__atoi(mr.exp[0], 0);
rule->number_of = Str__atoi(mr.exp[1], 0);
} else if (Regexp__match(&mr, premiss, L"keyword of (%c+)")) {
rule->match_keyword_of_colour = Languages__colour(mr.exp[0], tfp);
} else if (Regexp__match(&mr, premiss, L"keyword")) {
Errors__in_text_file("ambiguous: make it keyword of !reserved or \"keyword\"", tfp);
} else if (Regexp__match(&mr, premiss, L"prefix (%c+)")) {
rule->match_prefix = UNSPACED_RULE_PREFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"matching (%c+)")) {
Languages__regexp(rule->match_regexp_text, mr.exp[0], tfp);
} else if (Regexp__match(&mr, premiss, L"spaced prefix (%c+)")) {
rule->match_prefix = SPACED_RULE_PREFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"optionally spaced prefix (%c+)")) {
rule->match_prefix = OPTIONALLY_SPACED_RULE_PREFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"suffix (%c+)")) {
rule->match_prefix = UNSPACED_RULE_SUFFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"spaced suffix (%c+)")) {
rule->match_prefix = SPACED_RULE_SUFFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"optionally spaced suffix (%c+)")) {
rule->match_prefix = OPTIONALLY_SPACED_RULE_SUFFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"coloured (%c+)")) {
rule->match_colour = Languages__colour(mr.exp[0], tfp);
} else if (Str__len(premiss) > 0) {
rule->match_text = Languages__text(premiss, tfp, FALSE);
}
}
#line 491 "inweb/Chapter 4/Programming Languages.w"
;
{
#line 537 "inweb/Chapter 4/Programming Languages.w"
if (Str__eq(action, TL_IS_385)) {
rule->execute_block =
Languages__new_block(state->current_block, WHOLE_LINE_CRULE_RUN);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, action, L"(!%c+) on prefix")) {
rule->set_prefix_to_colour = Languages__colour(mr.exp[0], tfp);
} else if (Regexp__match(&mr, action, L"(!%c+) on suffix")) {
rule->set_prefix_to_colour = Languages__colour(mr.exp[0], tfp);
} else if (Regexp__match(&mr, action, L"(!%c+) on both")) {
rule->set_to_colour = Languages__colour(mr.exp[0], tfp);
rule->set_prefix_to_colour = rule->set_to_colour;
} else if (Str__get_first_char(action) == '!') {
rule->set_to_colour = Languages__colour(action, tfp);
} else if (Str__eq(action, TL_IS_386)) {
rule->debug = TRUE;
} else {
Errors__in_text_file("action after '=>' illegible", tfp);
}
}
#line 492 "inweb/Chapter 4/Programming Languages.w"
;
Regexp__dispose_of(&mr);
}
#line 565 "inweb/Chapter 4/Programming Languages.w"
reserved_word *Languages__reserved(programming_language *pl, text_stream *W, wchar_t C,
text_file_position *tfp) {
reserved_word *rw;
LOOP_OVER_LINKED_LIST(rw, reserved_word, pl->reserved_words)
if (Str__eq(rw->word, W)) {
Errors__in_text_file("duplicate reserved word", tfp);
}
rw = CREATE(reserved_word);
rw->word = Str__duplicate(W);
rw->colour = (int) C;
ADD_TO_LINKED_LIST(rw, reserved_word, pl->reserved_words);
Analyser__mark_reserved_word(&(pl->built_in_keywords), rw->word, (int) C);
return rw;
}
#line 603 "inweb/Chapter 4/Programming Languages.w"
wchar_t Languages__colour(text_stream *T, text_file_position *tfp) {
if (Str__get_first_char(T) != '!') {
Errors__in_text_file("colour names must begin with !", tfp);
return PLAIN_COLOUR;
}
if (Str__eq(T, TL_IS_387)) return STRING_COLOUR;
else if (Str__eq(T, TL_IS_388)) return FUNCTION_COLOUR;
else if (Str__eq(T, TL_IS_389)) return DEFINITION_COLOUR;
else if (Str__eq(T, TL_IS_390)) return RESERVED_COLOUR;
else if (Str__eq(T, TL_IS_391)) return ELEMENT_COLOUR;
else if (Str__eq(T, TL_IS_392)) return IDENTIFIER_COLOUR;
else if (Str__eq(T, TL_IS_393)) return CHARACTER_COLOUR;
else if (Str__eq(T, TL_IS_394)) return CONSTANT_COLOUR;
else if (Str__eq(T, TL_IS_395)) return PLAIN_COLOUR;
else if (Str__eq(T, TL_IS_396)) return EXTRACT_COLOUR;
else if (Str__eq(T, TL_IS_397)) return COMMENT_COLOUR;
else {
Errors__in_text_file("no such !colour", tfp);
return PLAIN_COLOUR;
}
}
#line 628 "inweb/Chapter 4/Programming Languages.w"
int Languages__boolean(text_stream *T, text_file_position *tfp) {
if (Str__eq(T, TL_IS_398)) return TRUE;
else if (Str__eq(T, TL_IS_399)) return FALSE;
else {
Errors__in_text_file("must be true or false", tfp);
return FALSE;
}
}
#line 642 "inweb/Chapter 4/Programming Languages.w"
text_stream *Languages__text(text_stream *T, text_file_position *tfp, int allow) {
text_stream *V = Str__new();
if (Str__len(T) > 0) {
int bareword = TRUE, spaced = FALSE, from = 0, to = Str__len(T)-1;
if ((to > from) &&
(Str__get_at(T, from) == '"') && (Str__get_at(T, to) == '"')) {
bareword = FALSE; from++; to--;
}
for (int i=from; i<=to; i++) {
wchar_t c = Str__get_at(T, i);
if (c == ' ') spaced = TRUE;
if ((c == '\\') && (Str__get_at(T, i+1) == 'n')) {
PUT_TO(V, '\n');
i++;
} else if ((c == '\\') && (Str__get_at(T, i+1) == 's')) {
PUT_TO(V, ' ');
i++;
} else if ((c == '\\') && (Str__get_at(T, i+1) == 't')) {
PUT_TO(V, '\t');
i++;
} else if ((c == '\\') && (Str__get_at(T, i+1) == '\\')) {
PUT_TO(V, '\\');
i++;
} else if ((bareword == FALSE) && (c == '\\') && (Str__get_at(T, i+1) == '"')) {
PUT_TO(V, '"');
i++;
} else if ((bareword == FALSE) && (c == '"')) {
Errors__in_text_file(
"backslash needed before internal double-quotation mark", tfp);
} else if ((bareword) && (c == '!') && (i == from)) {
Errors__in_text_file(
"a literal starting with ! must be in double-quotation marks", tfp);
} else if ((bareword) && (c == '/')) {
Errors__in_text_file(
"forward slashes can only be used in quoted strings", tfp);
} else if ((bareword) && (c == '"')) {
Errors__in_text_file(
"double-quotation marks can only be used in quoted strings", tfp);
} else {
PUT_TO(V, c);
}
}
if ((bareword) && (spaced) && (allow == FALSE)) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "'%S' seems to be literal text, but if so it needs double-quotation marks", T);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err)
}
if (bareword) {
int rw = FALSE;
if (Str__eq(V, TL_IS_400)) rw = TRUE;
if (Str__eq(V, TL_IS_401)) rw = TRUE;
if (Str__eq(V, TL_IS_402)) rw = TRUE;
if (Str__eq(V, TL_IS_403)) rw = TRUE;
if (Str__eq(V, TL_IS_404)) rw = TRUE;
if (Str__eq(V, TL_IS_405)) rw = TRUE;
if (Str__eq(V, TL_IS_406)) rw = TRUE;
if (Str__eq(V, TL_IS_407)) rw = TRUE;
if (Str__eq(V, TL_IS_408)) rw = TRUE;
if (Str__eq(V, TL_IS_409)) rw = TRUE;
if (Str__eq(V, TL_IS_410)) rw = TRUE;
if (Str__eq(V, TL_IS_411)) rw = TRUE;
if (Str__eq(V, TL_IS_412)) rw = TRUE;
if (Str__eq(V, TL_IS_413)) rw = TRUE;
if (Str__eq(V, TL_IS_414)) rw = TRUE;
if (Str__eq(V, TL_IS_415)) rw = TRUE;
if (Str__eq(V, TL_IS_416)) rw = TRUE;
if (Str__eq(V, TL_IS_417)) rw = TRUE;
if (Str__eq(V, TL_IS_418)) rw = TRUE;
if (Str__eq(V, TL_IS_419)) rw = TRUE;
if (Str__eq(V, TL_IS_420)) rw = TRUE;
if (Str__eq(V, TL_IS_421)) rw = TRUE;
if (rw) {
TEMPORARY_TEXT(err)
WRITE_TO(err, "'%S' is a reserved word, so you should put it in double-quotation marks", V);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err)
}
}
}
return V;
}
#line 729 "inweb/Chapter 4/Programming Languages.w"
void Languages__regexp(wchar_t *write_to, text_stream *T, text_file_position *tfp) {
if (write_to == NULL) internal_error("no buffer");
write_to[0] = 0;
if (Str__len(T) > 0) {
int from = 0, to = Str__len(T)-1, x = 0;
if ((to > from) &&
(Str__get_at(T, from) == '/') && (Str__get_at(T, to) == '/')) {
from++; to--;
for (int i=from; i<=to; i++) {
wchar_t c = Str__get_at(T, i);
if (c == '\\') {
wchar_t w = Str__get_at(T, i+1);
if (w == '\\') {
x = Languages__add_to_regexp(write_to, x, w);
} else if (w == 'd') {
x = Languages__add_escape_to_regexp(write_to, x, 'd');
} else if (w == 't') {
x = Languages__add_escape_to_regexp(write_to, x, 't');
} else if (w == 's') {
x = Languages__add_to_regexp(write_to, x, ' ');
} else if (w == 'S') {
x = Languages__add_escape_to_regexp(write_to, x, 'C');
} else if (w == '"') {
x = Languages__add_escape_to_regexp(write_to, x, 'q');
} else {
x = Languages__add_escape_to_regexp(write_to, x, w);
}
i++;
continue;
}
if (c == '.') {
x = Languages__add_escape_to_regexp(write_to, x, 'c');
continue;
}
if (c == '%') {
x = Languages__add_escape_to_regexp(write_to, x, '%');
continue;
}
x = Languages__add_to_regexp(write_to, x, c);
}
} else {
Errors__in_text_file(
"the expression to match must be in slashes '/'", tfp);
}
if (x >= MAX_ILDF_REGEXP_LENGTH)
Errors__in_text_file(
"the expression to match is too long", tfp);
}
}
int Languages__add_to_regexp(wchar_t *write_to, int i, wchar_t c) {
if (i < MAX_ILDF_REGEXP_LENGTH) write_to[i++] = c;
return i;
}
int Languages__add_escape_to_regexp(wchar_t *write_to, int i, wchar_t c) {
i = Languages__add_to_regexp(write_to, i, '%');
i = Languages__add_to_regexp(write_to, i, c);
return i;
}
#line 18 "inweb/Chapter 4/Types and Functions.w"
#line 20 "inweb/Chapter 4/Types and Functions.w"
language_type *first_cst_alphabetically = NULL;
language_type *Functions__new_struct(web *W, text_stream *name, source_line *L) {
language_type *str = CREATE(language_type);
{
#line 32 "inweb/Chapter 4/Types and Functions.w"
str->structure_name = Str__duplicate(name);
str->structure_header_at = L;
str->tangled = FALSE;
str->typedef_ends = NULL;
str->incorporates = NEW_LINKED_LIST(language_type);
str->elements = NEW_LINKED_LIST(structure_element);
}
#line 24 "inweb/Chapter 4/Types and Functions.w"
;
Analyser__mark_reserved_word_at_line(L, str->structure_name, RESERVED_COLOUR);
{
#line 40 "inweb/Chapter 4/Types and Functions.w"
Tags__add_by_name(L->owning_paragraph, TL_IS_422);
ADD_TO_LINKED_LIST(str, language_type, W->language_types);
ADD_TO_LINKED_LIST(str, language_type, L->owning_paragraph->structures);
}
#line 26 "inweb/Chapter 4/Types and Functions.w"
;
{
#line 45 "inweb/Chapter 4/Types and Functions.w"
str->next_cst_alphabetically = NULL;
if (first_cst_alphabetically == NULL) first_cst_alphabetically = str;
else {
int placed = FALSE;
language_type *last = NULL;
for (language_type *seq = first_cst_alphabetically; seq;
seq = seq->next_cst_alphabetically) {
if (Str__cmp(str->structure_name, seq->structure_name) < 0) {
if (seq == first_cst_alphabetically) {
str->next_cst_alphabetically = first_cst_alphabetically;
first_cst_alphabetically = str;
} else {
last->next_cst_alphabetically = str;
str->next_cst_alphabetically = seq;
}
placed = TRUE;
break;
}
last = seq;
}
if (placed == FALSE) last->next_cst_alphabetically = str;
}
}
#line 27 "inweb/Chapter 4/Types and Functions.w"
;
return str;
}
#line 84 "inweb/Chapter 4/Types and Functions.w"
#line 86 "inweb/Chapter 4/Types and Functions.w"
structure_element *Functions__new_element(language_type *str, text_stream *elname,
source_line *L) {
Analyser__mark_reserved_word_at_line(L, elname, ELEMENT_COLOUR);
structure_element *elt = CREATE(structure_element);
elt->element_name = Str__duplicate(elname);
elt->allow_sharing = FALSE;
elt->element_created_at = L;
if (LanguageMethods__share_element(L->owning_section->sect_language, elname))
elt->allow_sharing = TRUE;
ADD_TO_LINKED_LIST(elt, structure_element, str->elements);
return elt;
}
#line 100 "inweb/Chapter 4/Types and Functions.w"
language_type *Functions__find_structure(web *W, text_stream *name) {
language_type *str;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
if (Str__eq(name, str->structure_name))
return str;
return NULL;
}
#line 125 "inweb/Chapter 4/Types and Functions.w"
#line 127 "inweb/Chapter 4/Types and Functions.w"
language_function *Functions__new_function(text_stream *fname, source_line *L) {
hash_table_entry *hte =
Analyser__mark_reserved_word_at_line(L, fname, FUNCTION_COLOUR);
language_function *fn = CREATE(language_function);
hte->as_function = fn;
{
#line 143 "inweb/Chapter 4/Types and Functions.w"
fn->function_name = Str__duplicate(fname);
fn->function_arguments = Str__new();
fn->function_type = Str__new();
fn->within_namespace = FALSE;
fn->called_from_other_sections = FALSE;
fn->call_freely = FALSE;
fn->function_header_at = L;
fn->usage_described = FALSE;
if ((Str__eq_wide_string(fname, L"main")) &&
(L->owning_section->sect_language->C_like))
fn->usage_described = TRUE;
fn->no_conditionals = 0;
}
#line 132 "inweb/Chapter 4/Types and Functions.w"
;
{
#line 157 "inweb/Chapter 4/Types and Functions.w"
paragraph *P = L->owning_paragraph;
if (P) ADD_TO_LINKED_LIST(fn, language_function, P->functions);
L->function_defined = fn;
}
#line 133 "inweb/Chapter 4/Types and Functions.w"
;
if (L->owning_section->sect_language->supports_namespaces)
{
#line 162 "inweb/Chapter 4/Types and Functions.w"
text_stream *declared_namespace = NULL;
text_stream *ambient_namespace = L->owning_section->sect_namespace;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, fname, L"(%c+::)%c*")) {
declared_namespace = mr.exp[0];
fn->within_namespace = TRUE;
} else if ((Str__eq_wide_string(fname, L"main")) &&
(Str__eq_wide_string(ambient_namespace, L"Main::")))
declared_namespace = TL_IS_423;
if ((Str__ne(declared_namespace, ambient_namespace)) &&
(L->owning_paragraph->placed_very_early == FALSE)) {
TEMPORARY_TEXT(err_mess)
if (Str__len(declared_namespace) == 0)
WRITE_TO(err_mess, "Function '%S' should have namespace prefix '%S'",
fname, ambient_namespace);
else if (Str__len(ambient_namespace) == 0)
WRITE_TO(err_mess, "Function '%S' declared in a section with no namespace",
fname);
else
WRITE_TO(err_mess, "Function '%S' declared in a section with the wrong namespace '%S'",
fname, ambient_namespace);
Main__error_in_web(err_mess, L);
DISCARD_TEXT(err_mess)
}
Regexp__dispose_of(&mr);
}
#line 135 "inweb/Chapter 4/Types and Functions.w"
;
return fn;
}
#line 192 "inweb/Chapter 4/Types and Functions.w"
int Functions__used_elsewhere(language_function *fn) {
paragraph *P = fn->function_header_at->owning_paragraph;
hash_table_entry *hte =
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
fn->function_name, FALSE);
hash_table_entry_usage *hteu = NULL;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if ((P != hteu->usage_recorded_at) &&
(P->under_section == hteu->usage_recorded_at->under_section))
return TRUE;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if (P->under_section != hteu->usage_recorded_at->under_section)
return TRUE;
return FALSE;
}
#line 213 "inweb/Chapter 4/Types and Functions.w"
void Functions__catalogue(section *S, int functions_too) {
language_type *str;
LOOP_OVER(str, language_type)
if (str->structure_header_at->owning_section == S)
PRINT(" %S ", str->structure_name);
if (functions_too) {
language_function *fn;
LOOP_OVER(fn, language_function)
if (fn->function_header_at->owning_section == S)
PRINT("\n %S", fn->function_name);
}
}
#line 36 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(PARSE_TYPES_PAR_MTID, programming_language *pl, web *W)
void LanguageMethods__parse_types(web *W, programming_language *pl) {
VOID_METHOD_CALL(pl, PARSE_TYPES_PAR_MTID, W);
}
#line 44 "inweb/Chapter 4/Language Methods.w"
#line 46 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(PARSE_FUNCTIONS_PAR_MTID, programming_language *pl, web *W)
void LanguageMethods__parse_functions(web *W, programming_language *pl) {
VOID_METHOD_CALL(pl, PARSE_FUNCTIONS_PAR_MTID, W);
}
#line 56 "inweb/Chapter 4/Language Methods.w"
#line 58 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(FURTHER_PARSING_PAR_MTID, programming_language *pl, web *W)
void LanguageMethods__further_parsing(web *W, programming_language *pl) {
VOID_METHOD_CALL(pl, FURTHER_PARSING_PAR_MTID, W);
}
#line 69 "inweb/Chapter 4/Language Methods.w"
#line 71 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(SUBCATEGORISE_LINE_PAR_MTID, programming_language *pl, source_line *L)
void LanguageMethods__subcategorise_line(programming_language *pl, source_line *L) {
VOID_METHOD_CALL(pl, SUBCATEGORISE_LINE_PAR_MTID, L);
}
#line 82 "inweb/Chapter 4/Language Methods.w"
#line 84 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(PARSE_COMMENT_TAN_MTID, programming_language *pl, text_stream *line, text_stream *before, text_stream *within)
int LanguageMethods__parse_comment(programming_language *pl,
text_stream *line, text_stream *before, text_stream *within) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, PARSE_COMMENT_TAN_MTID, line, before, within);
return rv;
}
#line 102 "inweb/Chapter 4/Language Methods.w"
#line 104 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(SHEBANG_TAN_MTID, programming_language *pl, text_stream *OUT, web *W, tangle_target *target)
void LanguageMethods__shebang(OUTPUT_STREAM, programming_language *pl, web *W, tangle_target *target) {
VOID_METHOD_CALL(pl, SHEBANG_TAN_MTID, OUT, W, target);
}
#line 113 "inweb/Chapter 4/Language Methods.w"
#line 115 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(SUPPRESS_DISCLAIMER_TAN_MTID, programming_language *pl)
void LanguageMethods__disclaimer(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) {
int rv = FALSE;
INT_METHOD_CALL_WITHOUT_ARGUMENTS(rv, pl, SUPPRESS_DISCLAIMER_TAN_MTID);
if (rv == FALSE)
LanguageMethods__comment(OUT, pl, TL_IS_424);
}
#line 127 "inweb/Chapter 4/Language Methods.w"
#line 129 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(ADDITIONAL_EARLY_MATTER_TAN_MTID, programming_language *pl, text_stream *OUT, web *W, tangle_target *target)
void LanguageMethods__additional_early_matter(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) {
VOID_METHOD_CALL(pl, ADDITIONAL_EARLY_MATTER_TAN_MTID, OUT, W, target);
}
#line 143 "inweb/Chapter 4/Language Methods.w"
#line 145 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(START_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *term, text_stream *start, section *S, source_line *L)
INT_METHOD_TYPE(PROLONG_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *more, section *S, source_line *L)
INT_METHOD_TYPE(END_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, section *S, source_line *L)
void LanguageMethods__start_definition(OUTPUT_STREAM, programming_language *pl,
text_stream *term, text_stream *start, section *S, source_line *L) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, START_DEFN_TAN_MTID, OUT, term, start, S, L);
if (rv == FALSE)
Main__error_in_web(TL_IS_425, L);
}
void LanguageMethods__prolong_definition(OUTPUT_STREAM, programming_language *pl,
text_stream *more, section *S, source_line *L) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, PROLONG_DEFN_TAN_MTID, OUT, more, S, L);
if (rv == FALSE)
Main__error_in_web(TL_IS_426, L);
}
void LanguageMethods__end_definition(OUTPUT_STREAM, programming_language *pl,
section *S, source_line *L) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, END_DEFN_TAN_MTID, OUT, S, L);
}
#line 175 "inweb/Chapter 4/Language Methods.w"
#line 177 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(ADDITIONAL_PREDECLARATIONS_TAN_MTID, programming_language *pl, text_stream *OUT, web *W)
void LanguageMethods__additional_predeclarations(OUTPUT_STREAM, programming_language *pl, web *W) {
VOID_METHOD_CALL(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, OUT, W);
}
#line 188 "inweb/Chapter 4/Language Methods.w"
#line 190 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(SUPPRESS_EXPANSION_TAN_MTID, programming_language *pl, text_stream *material)
int LanguageMethods__allow_expansion(programming_language *pl, text_stream *material) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, SUPPRESS_EXPANSION_TAN_MTID, material);
return (rv)?FALSE:TRUE;
}
#line 202 "inweb/Chapter 4/Language Methods.w"
#line 204 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(TANGLE_COMMAND_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *data)
int LanguageMethods__special_tangle_command(OUTPUT_STREAM, programming_language *pl, text_stream *data) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, TANGLE_COMMAND_TAN_MTID, OUT, data);
return rv;
}
#line 219 "inweb/Chapter 4/Language Methods.w"
#line 221 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(WILL_TANGLE_EXTRA_LINE_TAN_MTID, programming_language *pl, source_line *L)
VOID_METHOD_TYPE(TANGLE_EXTRA_LINE_TAN_MTID, programming_language *pl, text_stream *OUT, source_line *L)
int LanguageMethods__will_insert_in_tangle(programming_language *pl, source_line *L) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, WILL_TANGLE_EXTRA_LINE_TAN_MTID, L);
return rv;
}
void LanguageMethods__insert_in_tangle(OUTPUT_STREAM, programming_language *pl, source_line *L) {
VOID_METHOD_CALL(pl, TANGLE_EXTRA_LINE_TAN_MTID, OUT, L);
}
#line 238 "inweb/Chapter 4/Language Methods.w"
#line 240 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(INSERT_LINE_MARKER_TAN_MTID, programming_language *pl, text_stream *OUT, source_line *L)
void LanguageMethods__insert_line_marker(OUTPUT_STREAM, programming_language *pl, source_line *L) {
VOID_METHOD_CALL(pl, INSERT_LINE_MARKER_TAN_MTID, OUT, L);
}
#line 251 "inweb/Chapter 4/Language Methods.w"
#line 253 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(BEFORE_MACRO_EXPANSION_TAN_MTID, programming_language *pl, text_stream *OUT, para_macro *pmac)
VOID_METHOD_TYPE(AFTER_MACRO_EXPANSION_TAN_MTID, programming_language *pl, text_stream *OUT, para_macro *pmac)
void LanguageMethods__before_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) {
VOID_METHOD_CALL(pl, BEFORE_MACRO_EXPANSION_TAN_MTID, OUT, pmac);
}
void LanguageMethods__after_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) {
VOID_METHOD_CALL(pl, AFTER_MACRO_EXPANSION_TAN_MTID, OUT, pmac);
}
#line 268 "inweb/Chapter 4/Language Methods.w"
#line 270 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(OPEN_IFDEF_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *symbol, int sense)
VOID_METHOD_TYPE(CLOSE_IFDEF_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *symbol, int sense)
void LanguageMethods__open_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) {
VOID_METHOD_CALL(pl, OPEN_IFDEF_TAN_MTID, OUT, symbol, sense);
}
void LanguageMethods__close_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) {
VOID_METHOD_CALL(pl, CLOSE_IFDEF_TAN_MTID, OUT, symbol, sense);
}
#line 282 "inweb/Chapter 4/Language Methods.w"
#line 284 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(COMMENT_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *comm)
void LanguageMethods__comment(OUTPUT_STREAM, programming_language *pl, text_stream *comm) {
VOID_METHOD_CALL(pl, COMMENT_TAN_MTID, OUT, comm);
}
#line 294 "inweb/Chapter 4/Language Methods.w"
#line 296 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(TANGLE_LINE_UNUSUALLY_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *original)
void LanguageMethods__tangle_line(OUTPUT_STREAM, programming_language *pl, text_stream *original) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, TANGLE_LINE_UNUSUALLY_TAN_MTID, OUT, original);
if (rv == FALSE) WRITE("%S", original);
}
#line 306 "inweb/Chapter 4/Language Methods.w"
#line 308 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(GNABEHS_TAN_MTID, programming_language *pl, text_stream *OUT, web *W)
void LanguageMethods__gnabehs(OUTPUT_STREAM, programming_language *pl, web *W) {
VOID_METHOD_CALL(pl, GNABEHS_TAN_MTID, OUT, W);
}
#line 318 "inweb/Chapter 4/Language Methods.w"
#line 320 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(ADDITIONAL_TANGLING_TAN_MTID, programming_language *pl, web *W, tangle_target *target)
void LanguageMethods__additional_tangling(programming_language *pl, web *W, tangle_target *target) {
VOID_METHOD_CALL(pl, ADDITIONAL_TANGLING_TAN_MTID, W, target);
}
#line 330 "inweb/Chapter 4/Language Methods.w"
#line 332 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(BEGIN_WEAVE_WEA_MTID, programming_language *pl, section *S, weave_order *wv)
void LanguageMethods__begin_weave(section *S, weave_order *wv) {
VOID_METHOD_CALL(S->sect_language, BEGIN_WEAVE_WEA_MTID, S, wv);
}
#line 340 "inweb/Chapter 4/Language Methods.w"
#line 342 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(SKIP_IN_WEAVING_WEA_MTID, programming_language *pl, weave_order *wv, source_line *L)
int LanguageMethods__skip_in_weaving(programming_language *pl, weave_order *wv, source_line *L) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, SKIP_IN_WEAVING_WEA_MTID, wv, L);
return rv;
}
#line 355 "inweb/Chapter 4/Language Methods.w"
#line 357 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(RESET_SYNTAX_COLOURING_WEA_MTID, programming_language *pl)
void LanguageMethods__reset_syntax_colouring(programming_language *pl) {
VOID_METHOD_CALL_WITHOUT_ARGUMENTS(pl, RESET_SYNTAX_COLOURING_WEA_MTID);
}
#line 365 "inweb/Chapter 4/Language Methods.w"
#line 367 "inweb/Chapter 4/Language Methods.w"
int colouring_state = PLAIN_COLOUR;
INT_METHOD_TYPE(SYNTAX_COLOUR_WEA_MTID, programming_language *pl,
weave_order *wv, source_line *L, text_stream *matter, text_stream *colouring)
int LanguageMethods__syntax_colour(programming_language *pl,
weave_order *wv, source_line *L, text_stream *matter, text_stream *colouring) {
for (int i=0; i < Str__len(matter); i++) Str__put_at(colouring, i, PLAIN_COLOUR);
int rv = FALSE;
programming_language *colour_as = pl;
if (L->category == TEXT_EXTRACT_LCAT) colour_as = L->colour_as;
theme_tag *T = Tags__find_by_name(TL_IS_427, FALSE);
if ((T) && (Tags__tagged_with(L->owning_paragraph, T))) {
programming_language *prepl = Languages__find_by_name(TL_IS_428, wv->weave_web, FALSE);
if ((L->category == PREFORM_LCAT) || (L->category == PREFORM_GRAMMAR_LCAT))
if (prepl) colour_as = prepl;
}
if (colour_as)
INT_METHOD_CALL(rv, colour_as, SYNTAX_COLOUR_WEA_MTID, wv, L,
matter, colouring);
return rv;
}
#line 394 "inweb/Chapter 4/Language Methods.w"
#line 396 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(WEAVE_CODE_LINE_WEA_MTID, programming_language *pl, text_stream *OUT, weave_order *wv, web *W,
chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment)
int LanguageMethods__weave_code_line(OUTPUT_STREAM, programming_language *pl, weave_order *wv,
web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, WEAVE_CODE_LINE_WEA_MTID, OUT, wv, W, C, S, L, matter, concluding_comment);
return rv;
}
#line 408 "inweb/Chapter 4/Language Methods.w"
#line 410 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(NOTIFY_NEW_TAG_WEA_MTID, programming_language *pl, theme_tag *tag)
void LanguageMethods__new_tag_declared(theme_tag *tag) {
programming_language *pl;
LOOP_OVER(pl, programming_language)
VOID_METHOD_CALL(pl, NOTIFY_NEW_TAG_WEA_MTID, tag);
}
#line 430 "inweb/Chapter 4/Language Methods.w"
#line 432 "inweb/Chapter 4/Language Methods.w"
VOID_METHOD_TYPE(ANALYSIS_ANA_MTID, programming_language *pl, web *W)
VOID_METHOD_TYPE(POST_ANALYSIS_ANA_MTID, programming_language *pl, web *W)
void LanguageMethods__early_preweave_analysis(programming_language *pl, web *W) {
VOID_METHOD_CALL(pl, ANALYSIS_ANA_MTID, W);
}
void LanguageMethods__late_preweave_analysis(programming_language *pl, web *W) {
VOID_METHOD_CALL(pl, POST_ANALYSIS_ANA_MTID, W);
}
#line 445 "inweb/Chapter 4/Language Methods.w"
#line 447 "inweb/Chapter 4/Language Methods.w"
INT_METHOD_TYPE(SHARE_ELEMENT_ANA_MTID, programming_language *pl, text_stream *element_name)
int LanguageMethods__share_element(programming_language *pl, text_stream *element_name) {
int rv = FALSE;
INT_METHOD_CALL(rv, pl, SHARE_ELEMENT_ANA_MTID, element_name);
return rv;
}
#line 457 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__supports_definitions(programming_language *pl) {
if (Str__len(pl->start_definition) > 0) return TRUE;
if (Str__len(pl->prolong_definition) > 0) return TRUE;
if (Str__len(pl->end_definition) > 0) return TRUE;
return FALSE;
}
#line 16 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__add_fallbacks(programming_language *pl) {
if (Methods__provided(pl->methods, PARSE_TYPES_PAR_MTID) == FALSE)
METHOD_ADD(pl, PARSE_TYPES_PAR_MTID, ACMESupport__parse_types);
if (Methods__provided(pl->methods, PARSE_FUNCTIONS_PAR_MTID) == FALSE)
METHOD_ADD(pl, PARSE_FUNCTIONS_PAR_MTID, ACMESupport__parse_functions);
if (Methods__provided(pl->methods, ANALYSIS_ANA_MTID) == FALSE)
METHOD_ADD(pl, ANALYSIS_ANA_MTID, ACMESupport__analyse_code);
if (Methods__provided(pl->methods, POST_ANALYSIS_ANA_MTID) == FALSE)
METHOD_ADD(pl, POST_ANALYSIS_ANA_MTID, ACMESupport__post_analysis);
if (Methods__provided(pl->methods, PARSE_COMMENT_TAN_MTID) == FALSE)
METHOD_ADD(pl, PARSE_COMMENT_TAN_MTID, ACMESupport__parse_comment);
if (Methods__provided(pl->methods, COMMENT_TAN_MTID) == FALSE)
METHOD_ADD(pl, COMMENT_TAN_MTID, ACMESupport__comment);
if (Methods__provided(pl->methods, SHEBANG_TAN_MTID) == FALSE)
METHOD_ADD(pl, SHEBANG_TAN_MTID, ACMESupport__shebang);
if (Methods__provided(pl->methods, BEFORE_MACRO_EXPANSION_TAN_MTID) == FALSE)
METHOD_ADD(pl, BEFORE_MACRO_EXPANSION_TAN_MTID, ACMESupport__before_macro_expansion);
if (Methods__provided(pl->methods, AFTER_MACRO_EXPANSION_TAN_MTID) == FALSE)
METHOD_ADD(pl, AFTER_MACRO_EXPANSION_TAN_MTID, ACMESupport__after_macro_expansion);
if (Methods__provided(pl->methods, START_DEFN_TAN_MTID) == FALSE)
METHOD_ADD(pl, START_DEFN_TAN_MTID, ACMESupport__start_definition);
if (Methods__provided(pl->methods, PROLONG_DEFN_TAN_MTID) == FALSE)
METHOD_ADD(pl, PROLONG_DEFN_TAN_MTID, ACMESupport__prolong_definition);
if (Methods__provided(pl->methods, END_DEFN_TAN_MTID) == FALSE)
METHOD_ADD(pl, END_DEFN_TAN_MTID, ACMESupport__end_definition);
if (Methods__provided(pl->methods, OPEN_IFDEF_TAN_MTID) == FALSE)
METHOD_ADD(pl, OPEN_IFDEF_TAN_MTID, ACMESupport__I6_open_ifdef);
if (Methods__provided(pl->methods, CLOSE_IFDEF_TAN_MTID) == FALSE)
METHOD_ADD(pl, CLOSE_IFDEF_TAN_MTID, ACMESupport__I6_close_ifdef);
if (Methods__provided(pl->methods, INSERT_LINE_MARKER_TAN_MTID) == FALSE)
METHOD_ADD(pl, INSERT_LINE_MARKER_TAN_MTID, ACMESupport__insert_line_marker);
if (Methods__provided(pl->methods, SUPPRESS_DISCLAIMER_TAN_MTID) == FALSE)
METHOD_ADD(pl, SUPPRESS_DISCLAIMER_TAN_MTID, ACMESupport__suppress_disclaimer);
if (Methods__provided(pl->methods, BEGIN_WEAVE_WEA_MTID) == FALSE)
METHOD_ADD(pl, BEGIN_WEAVE_WEA_MTID, ACMESupport__begin_weave);
if (Methods__provided(pl->methods, RESET_SYNTAX_COLOURING_WEA_MTID) == FALSE)
METHOD_ADD(pl, RESET_SYNTAX_COLOURING_WEA_MTID, ACMESupport__reset_syntax_colouring);
if (Methods__provided(pl->methods, SYNTAX_COLOUR_WEA_MTID) == FALSE)
METHOD_ADD(pl, SYNTAX_COLOUR_WEA_MTID, ACMESupport__syntax_colour);
}
#line 62 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__expand(OUTPUT_STREAM, text_stream *prototype, text_stream *S,
int N, filename *F) {
if (Str__len(prototype) > 0) {
for (int i=0; i<Str__len(prototype); i++) {
wchar_t c = Str__get_at(prototype, i);
if ((c == '%') && (Str__get_at(prototype, i+1) == 'S') && (S)) {
WRITE("%S", S);
i++;
} else if ((c == '%') && (Str__get_at(prototype, i+1) == 'd') && (N >= 0)) {
WRITE("%d", N);
i++;
} else if ((c == '%') && (Str__get_at(prototype, i+1) == 'f') && (F)) {
WRITE("%/f", F);
i++;
} else {
PUT(c);
}
}
}
}
#line 86 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__shebang(programming_language *pl, text_stream *OUT, web *W,
tangle_target *target) {
ACMESupport__expand(OUT, pl->shebang, NULL, -1, NULL);
}
void ACMESupport__before_macro_expansion(programming_language *pl,
OUTPUT_STREAM, para_macro *pmac) {
ACMESupport__expand(OUT, pl->before_macro_expansion, NULL, -1, NULL);
}
void ACMESupport__after_macro_expansion(programming_language *pl,
OUTPUT_STREAM, para_macro *pmac) {
ACMESupport__expand(OUT, pl->after_macro_expansion, NULL, -1, NULL);
}
int ACMESupport__start_definition(programming_language *pl, text_stream *OUT,
text_stream *term, text_stream *start, section *S, source_line *L) {
if (LanguageMethods__supports_definitions(pl)) {
ACMESupport__expand(OUT, pl->start_definition, term, -1, NULL);
Tangler__tangle_line(OUT, start, S, L);
}
return TRUE;
}
int ACMESupport__prolong_definition(programming_language *pl,
text_stream *OUT, text_stream *more, section *S, source_line *L) {
if (LanguageMethods__supports_definitions(pl)) {
ACMESupport__expand(OUT, pl->prolong_definition, NULL, -1, NULL);
Tangler__tangle_line(OUT, more, S, L);
}
return TRUE;
}
int ACMESupport__end_definition(programming_language *pl,
text_stream *OUT, section *S, source_line *L) {
if (LanguageMethods__supports_definitions(pl)) {
ACMESupport__expand(OUT, pl->end_definition, NULL, -1, NULL);
}
return TRUE;
}
void ACMESupport__I6_open_ifdef(programming_language *pl,
text_stream *OUT, text_stream *symbol, int sense) {
if (sense) ACMESupport__expand(OUT, pl->start_ifdef, symbol, -1, NULL);
else ACMESupport__expand(OUT, pl->start_ifndef, symbol, -1, NULL);
}
void ACMESupport__I6_close_ifdef(programming_language *pl,
text_stream *OUT, text_stream *symbol, int sense) {
if (sense) ACMESupport__expand(OUT, pl->end_ifdef, symbol, -1, NULL);
else ACMESupport__expand(OUT, pl->end_ifndef, symbol, -1, NULL);
}
void ACMESupport__insert_line_marker(programming_language *pl,
text_stream *OUT, source_line *L) {
ACMESupport__expand(OUT, pl->line_marker, NULL,
L->source.line_count, L->source.text_file_filename);
}
void ACMESupport__comment(programming_language *pl,
text_stream *OUT, text_stream *comm) {
if (Str__len(pl->multiline_comment_open) > 0) {
ACMESupport__expand(OUT, pl->multiline_comment_open, NULL, -1, NULL);
WRITE(" %S ", comm);
ACMESupport__expand(OUT, pl->multiline_comment_close, NULL, -1, NULL);
WRITE("\n");
} else if (Str__len(pl->line_comment) > 0) {
ACMESupport__expand(OUT, pl->line_comment, NULL, -1, NULL);
WRITE(" %S\n", comm);
} else if (Str__len(pl->whole_line_comment) > 0) {
ACMESupport__expand(OUT, pl->whole_line_comment, NULL, -1, NULL);
WRITE(" %S\n", comm);
}
}
#line 166 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__parse_comment(programming_language *pl,
text_stream *line, text_stream *part_before_comment, text_stream *part_within_comment) {
int q_mode = 0, c_mode = 0, non_white_space = FALSE, c_position = -1, c_end = -1;
for (int i=0; i<Str__len(line); i++) {
wchar_t c = Str__get_at(line, i);
switch (c_mode) {
case 0:
{
#line 200 "inweb/Chapter 4/ACME Support.w"
switch (q_mode) {
case 0:
{
#line 207 "inweb/Chapter 4/ACME Support.w"
if (!(Characters__is_whitespace(c))) non_white_space = TRUE;
if (c == Str__get_first_char(pl->string_literal)) q_mode = 2;
else if (c == Str__get_first_char(pl->character_literal)) q_mode = 1;
else if (Str__includes_at(line, i, pl->multiline_comment_open)) {
c_mode = 2; c_position = i; non_white_space = FALSE;
i += Str__len(pl->multiline_comment_open) - 1;
} else if (Str__includes_at(line, i, pl->line_comment)) {
c_mode = 1; c_position = i; c_end = Str__len(line); non_white_space = FALSE;
i += Str__len(pl->line_comment) - 1;
} else if (Str__includes_at(line, i, pl->whole_line_comment)) {
int material_exists = FALSE;
for (int j=0; j<i; j++)
if (!(Characters__is_whitespace(Str__get_at(line, j))))
material_exists = TRUE;
if (material_exists == FALSE) {
c_mode = 1; c_position = i; c_end = Str__len(line);
non_white_space = FALSE;
i += Str__len(pl->whole_line_comment) - 1;
}
}
}
#line 201 "inweb/Chapter 4/ACME Support.w"
; break;
case 1:
{
#line 229 "inweb/Chapter 4/ACME Support.w"
if (!(Characters__is_whitespace(c))) non_white_space = TRUE;
if (c == Str__get_first_char(pl->character_literal_escape)) i += 1;
if (c == Str__get_first_char(pl->character_literal)) q_mode = 0;
q_mode = 0;
}
#line 202 "inweb/Chapter 4/ACME Support.w"
; break;
case 2:
{
#line 235 "inweb/Chapter 4/ACME Support.w"
if (!(Characters__is_whitespace(c))) non_white_space = TRUE;
if (c == Str__get_first_char(pl->string_literal_escape)) i += 1;
if (c == Str__get_first_char(pl->string_literal)) q_mode = 0;
q_mode = 0;
}
#line 203 "inweb/Chapter 4/ACME Support.w"
; break;
}
}
#line 172 "inweb/Chapter 4/ACME Support.w"
; break;
case 1:
{
#line 197 "inweb/Chapter 4/ACME Support.w"
;
}
#line 173 "inweb/Chapter 4/ACME Support.w"
; break;
case 2:
{
#line 192 "inweb/Chapter 4/ACME Support.w"
if (Str__includes_at(line, i, pl->multiline_comment_close)) {
c_mode = 0; c_end = i; i += Str__len(pl->multiline_comment_close) - 1;
}
}
#line 174 "inweb/Chapter 4/ACME Support.w"
; break;
}
}
if (c_mode == 2) c_end = Str__len(line);
if ((c_position >= 0) && (non_white_space == FALSE)) {
Str__clear(part_before_comment);
for (int i=0; i<c_position; i++)
PUT_TO(part_before_comment, Str__get_at(line, i));
Str__clear(part_within_comment);
for (int i=c_position + 2; i<c_end; i++)
PUT_TO(part_within_comment, Str__get_at(line, i));
Str__trim_white_space_at_end(part_within_comment);
return TRUE;
}
return FALSE;
}
#line 243 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_types(programming_language *self, web *W) {
if (W->main_language->type_notation[0]) {
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
if (S->sect_language == W->main_language) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, W->main_language->type_notation)) {
Functions__new_function(mr.exp[0], L);
}
Regexp__dispose_of(&mr);
}
}
}
}
#line 262 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_functions(programming_language *self, web *W) {
if (W->main_language->function_notation[0]) {
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
if (S->sect_language == W->main_language) {
match_results mr = Regexp__create_mr();
if ((L->category != TEXT_EXTRACT_LCAT) &&
(Regexp__match(&mr, L->text, W->main_language->function_notation))) {
Functions__new_function(mr.exp[0], L);
}
Regexp__dispose_of(&mr);
}
}
}
}
#line 287 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__post_analysis(programming_language *self, web *W) {
int check_namespaces = FALSE;
if (Str__eq_wide_string(Bibliographic__get_datum(W->md, TL_IS_429), L"On"))
check_namespaces = TRUE;
language_function *fn;
LOOP_OVER(fn, language_function) {
hash_table_entry *hte =
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
fn->function_name, FALSE);
if (hte) {
hash_table_entry_usage *hteu;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages) {
if ((hteu->form_of_usage & FCALL_USAGE) || (fn->within_namespace))
if (hteu->usage_recorded_at->under_section != fn->function_header_at->owning_section)
fn->called_from_other_sections = TRUE;
}
}
if ((fn->within_namespace != fn->called_from_other_sections)
&& (check_namespaces)
&& (fn->call_freely == FALSE)) {
if (fn->within_namespace)
Main__error_in_web(
TL_IS_430,
fn->function_header_at);
else
Main__error_in_web(
TL_IS_431,
fn->function_header_at);
}
}
}
#line 323 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__analyse_code(programming_language *self, web *W) {
language_function *fn;
LOOP_OVER(fn, language_function)
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
fn->function_name, TRUE);
language_type *str;
structure_element *elt;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
LOOP_OVER_LINKED_LIST(elt, structure_element, str->elements)
if (elt->allow_sharing == FALSE)
Analyser__find_hash_entry_for_section(elt->element_created_at->owning_section,
elt->element_name, TRUE);
}
#line 341 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__suppress_disclaimer(programming_language *pl) {
return pl->suppress_disclaimer;
}
#line 348 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__begin_weave(programming_language *pl, section *S, weave_order *wv) {
reserved_word *rw;
LOOP_OVER_LINKED_LIST(rw, reserved_word, pl->reserved_words)
Analyser__mark_reserved_word_for_section(S, rw->word, rw->colour);
}
#line 357 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__reset_syntax_colouring(programming_language *pl) {
Painter__reset_syntax_colouring(pl);
}
int ACMESupport__syntax_colour(programming_language *pl,
weave_order *wv, source_line *L, text_stream *matter, text_stream *colouring) {
section *S = L->owning_section;
hash_table *ht = &(S->sect_target->symbols);
if ((L->category == TEXT_EXTRACT_LCAT) && (pl != S->sect_language))
ht = &(pl->built_in_keywords);
return Painter__syntax_colour(pl, ht, matter, colouring, FALSE);
}
#line 16 "inweb/Chapter 4/The Painter.w"
int painter_count = 1;
void Painter__reset_syntax_colouring(programming_language *pl) {
colouring_state = PLAIN_COLOUR;
painter_count = 1;
}
#line 38 "inweb/Chapter 4/The Painter.w"
int Painter__syntax_colour(programming_language *pl,
hash_table *HT, text_stream *matter, text_stream *colouring, int with_comments) {
int from = 0, to = Str__len(matter) - 1;
if (with_comments) {
TEMPORARY_TEXT(part_before_comment)
TEMPORARY_TEXT(part_within_comment)
if (LanguageMethods__parse_comment(pl,
matter, part_before_comment, part_within_comment)) {
int N = Str__len(matter);
for (int i=Str__len(part_before_comment); i<N; i++)
Str__put_at(colouring, i, COMMENT_COLOUR);
from = 0; to = Str__len(part_before_comment);
}
DISCARD_TEXT(part_before_comment)
DISCARD_TEXT(part_within_comment)
}
Painter__syntax_colour_inner(pl, HT, matter, colouring, from, to);
return FALSE;
}
void Painter__syntax_colour_inner(programming_language *pl,
hash_table *HT, text_stream *matter, text_stream *colouring, int from, int to) {
{
#line 66 "inweb/Chapter 4/The Painter.w"
int squote = Str__get_first_char(pl->character_literal);
int squote_escape = Str__get_first_char(pl->character_literal_escape);
int dquote = Str__get_first_char(pl->string_literal);
int dquote_escape = Str__get_first_char(pl->string_literal_escape);
for (int i=from; i <= to; i++) {
wchar_t skip = NOT_A_COLOUR;
int one_off = -1, will_be = -1;
switch (colouring_state) {
case PLAIN_COLOUR: {
wchar_t c = Str__get_at(matter, i);
if (c == dquote) {
colouring_state = STRING_COLOUR;
break;
}
if (c == squote) {
colouring_state = CHARACTER_COLOUR;
break;
}
if (Painter__identifier_at(pl, matter, colouring, i))
one_off = IDENTIFIER_COLOUR;
break;
}
case CHARACTER_COLOUR: {
wchar_t c = Str__get_at(matter, i);
if (c == squote) will_be = PLAIN_COLOUR;
if (c == squote_escape) skip = CHARACTER_COLOUR;
break;
}
case STRING_COLOUR: {
wchar_t c = Str__get_at(matter, i);
if (c == dquote) will_be = PLAIN_COLOUR;
if (c == dquote_escape) skip = STRING_COLOUR;
break;
}
}
if (one_off >= 0) Str__put_at(colouring, i, (wchar_t) one_off);
else Str__put_at(colouring, i, (wchar_t) colouring_state);
if (will_be >= 0) colouring_state = will_be;
if ((skip != NOT_A_COLOUR) && (i<to)) {
i++; Str__put_at(colouring, i, skip);
}
}
}
#line 60 "inweb/Chapter 4/The Painter.w"
;
{
#line 110 "inweb/Chapter 4/The Painter.w"
int base = -1, dec_possible = TRUE;
for (int i=from; i <= to; i++) {
if ((Str__get_at(colouring, i) == PLAIN_COLOUR) ||
(Str__get_at(colouring, i) == IDENTIFIER_COLOUR)) {
wchar_t c = Str__get_at(matter, i);
if (Str__includes_at(matter, i, pl->binary_literal_prefix)) {
base = 2;
for (int j=0; j<Str__len(pl->binary_literal_prefix); j++)
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
dec_possible = TRUE;
continue;
} else if (Str__includes_at(matter, i, pl->octal_literal_prefix)) {
base = 8;
for (int j=0; j<Str__len(pl->octal_literal_prefix); j++)
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
dec_possible = TRUE;
continue;
} else if (Str__includes_at(matter, i, pl->hexadecimal_literal_prefix)) {
base = 16;
for (int j=0; j<Str__len(pl->hexadecimal_literal_prefix); j++)
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
dec_possible = TRUE;
continue;
}
if ((Str__includes_at(matter, i, pl->negative_literal_prefix)) &&
(dec_possible) && (base == 0)) {
base = 10;
Str__put_at(colouring, i, (char) CONSTANT_COLOUR);
continue;
}
int pass = FALSE;
switch (base) {
case -1:
if ((dec_possible) && (Characters__isdigit(c))) {
base = 10; pass = TRUE;
}
break;
case 2: if ((c == '0') || (c == '1')) pass = TRUE; break;
case 10: if (Characters__isdigit(c)) pass = TRUE; break;
case 16: if (Characters__isdigit(c)) pass = TRUE;
int d = Characters__tolower(c);
if ((d == 'a') || (d == 'b') || (d == 'c') ||
(d == 'd') || (d == 'e') || (d == 'f')) pass = TRUE;
break;
}
if (pass) {
Str__put_at(colouring, i, (char) CONSTANT_COLOUR);
} else {
if (Characters__is_whitespace(c)) dec_possible = TRUE;
else dec_possible = FALSE;
base = -1;
}
}
}
}
#line 61 "inweb/Chapter 4/The Painter.w"
;
{
#line 195 "inweb/Chapter 4/The Painter.w"
if (pl->program)
Painter__execute(HT, pl->program, matter, colouring, from, to, painter_count++);
}
#line 62 "inweb/Chapter 4/The Painter.w"
;
}
#line 171 "inweb/Chapter 4/The Painter.w"
int Painter__identifier_at(programming_language *pl,
text_stream *matter, text_stream *colouring, int i) {
wchar_t c = Str__get_at(matter, i);
if ((i > 0) && (Str__get_at(colouring, i-1) == IDENTIFIER_COLOUR)) {
if ((c == '_') ||
((c >= 'A') && (c <= 'Z')) ||
((c >= 'a') && (c <= 'z')) ||
((c >= '0') && (c <= '9'))) return TRUE;
if ((c == ':') && (pl->supports_namespaces)) return TRUE;
} else {
wchar_t d = 0;
if (i > 0) d = Str__get_at(matter, i);
if ((d >= '0') && (d <= '9')) return FALSE;
if ((c == '_') ||
((c >= 'A') && (c <= 'Z')) ||
((c >= 'a') && (c <= 'z'))) return TRUE;
}
return FALSE;
}
#line 204 "inweb/Chapter 4/The Painter.w"
void Painter__execute(hash_table *HT, colouring_language_block *block, text_stream *matter,
text_stream *colouring, int from, int to, int N) {
if (block == NULL) internal_error("no block");
TEMPORARY_TEXT(colouring_at_start)
Str__copy(colouring_at_start, colouring);
colouring_rule *rule;
LOOP_OVER_LINKED_LIST(rule, colouring_rule, block->rules) {
switch (block->run) {
case WHOLE_LINE_CRULE_RUN:
Painter__execute_rule(HT, rule, matter, colouring, from, to,
(N == 0)?1:N);
break;
case CHARACTERS_CRULE_RUN:
for (int i=from; i<=to; i++)
Painter__execute_rule(HT, rule, matter, colouring, i, i, i-from+1);
break;
case CHARACTERS_IN_CRULE_RUN:
for (int count=1, i=from; i<=to; i++)
for (int j=0; j<Str__len(block->char_set); j++)
if (Str__get_at(matter, i) == Str__get_at(block->char_set, j) ) {
Painter__execute_rule(HT, rule, matter, colouring, i, i, count++);
break;
}
break;
case INSTANCES_CRULE_RUN: {
int L = Str__len(block->run_instance) - 1;
if (L >= 0)
for (int count=1, i=from; i<=to - L; i++)
if (Str__includes_at(matter, i, block->run_instance)) {
Painter__execute_rule(HT, rule, matter, colouring, i, i+L, count++);
i += L;
}
break;
}
case MATCHES_CRULE_RUN:
for (int count=1, i=from; i<=to; i++) {
int L = Regexp__match_from(&(block->mr), matter, block->match_regexp_text, i, TRUE);
if (L > 0) {
Painter__execute_rule(HT, rule, matter, colouring, i, i+L-1, count++);
i += L-1;
}
}
break;
case BRACKETS_CRULE_RUN:
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
if (block->mr.exp[i])
Str__clear(block->mr.exp[i]);
if (Regexp__match(&(block->mr), matter, block->match_regexp_text))
for (int count=1, i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
if (block->mr.exp_at[i] >= 0)
Painter__execute_rule(HT, rule, matter, colouring,
block->mr.exp_at[i],
block->mr.exp_at[i] + Str__len(block->mr.exp[i])-1,
count++);
break;
default: {
int ident_from = -1, count = 1;
for (int i=from; i<=to; i++) {
int col = Str__get_at(colouring_at_start, i);
if ((col == block->run) ||
((block->run == UNQUOTED_COLOUR) &&
((col != STRING_COLOUR) && (col != CHARACTER_COLOUR)))) {
if (ident_from == -1) ident_from = i;
} else {
if (ident_from >= 0)
Painter__execute_rule(HT, rule, matter, colouring, ident_from, i-1, count++);
ident_from = -1;
}
}
if (ident_from >= 0)
Painter__execute_rule(HT, rule, matter, colouring, ident_from, to, count++);
break;
}
}
}
DISCARD_TEXT(colouring_at_start)
}
#line 285 "inweb/Chapter 4/The Painter.w"
void Painter__execute_rule(hash_table *HT, colouring_rule *rule, text_stream *matter,
text_stream *colouring, int from, int to, int N) {
if (Painter__satisfies(HT, rule, matter, colouring, from, to, N) == rule->sense)
Painter__follow(HT, rule, matter, colouring, from, to);
}
#line 301 "inweb/Chapter 4/The Painter.w"
int Painter__satisfies(hash_table *HT, colouring_rule *rule, text_stream *matter,
text_stream *colouring, int from, int to, int N) {
if (rule->number > 0) {
if (rule->number_of > 0) {
if (rule->number != ((N-1)%(rule->number_of)) + 1) return FALSE;
} else {
if (rule->number != N) return FALSE;
}
} else if (rule->match_regexp_text[0]) {
TEMPORARY_TEXT(T)
for (int j=from; j<=to; j++) PUT_TO(T, Str__get_at(matter, j));
int rv = Regexp__match(&(rule->mr), T, rule->match_regexp_text);
DISCARD_TEXT(T)
if (rv == FALSE) return FALSE;
} else if (Str__len(rule->match_text) > 0) {
if ((rule->match_prefix == UNSPACED_RULE_PREFIX) ||
(rule->match_prefix == SPACED_RULE_PREFIX) ||
(rule->match_prefix == OPTIONALLY_SPACED_RULE_PREFIX)) {
int pos = from;
if (rule->match_prefix != UNSPACED_RULE_PREFIX) {
while ((pos > 0) && (Characters__is_whitespace(pos-1))) pos--;
if ((rule->match_prefix == SPACED_RULE_PREFIX) && (pos == from))
return FALSE;
}
if (Str__includes_at(matter,
pos-Str__len(rule->match_text), rule->match_text) == FALSE)
return FALSE;
rule->fix_position = pos-Str__len(rule->match_text);
} else if ((rule->match_prefix == UNSPACED_RULE_SUFFIX) ||
(rule->match_prefix == SPACED_RULE_SUFFIX) ||
(rule->match_prefix == OPTIONALLY_SPACED_RULE_SUFFIX)) {
int pos = to + 1;
if (rule->match_prefix != UNSPACED_RULE_SUFFIX) {
while ((pos < Str__len(rule->match_text)) && (Characters__is_whitespace(pos))) pos++;
if ((rule->match_prefix == SPACED_RULE_SUFFIX) && (pos == from))
return FALSE;
}
if (Str__includes_at(matter, pos, rule->match_text) == FALSE)
return FALSE;
rule->fix_position = pos;
} else {
if (Str__len(rule->match_text) != to-from+1)
return FALSE;
for (int i=from; i<=to; i++)
if (Str__get_at(matter, i) != Str__get_at(rule->match_text, i-from))
return FALSE;
}
} else if (rule->match_keyword_of_colour != NOT_A_COLOUR) {
TEMPORARY_TEXT(id)
Str__substr(id, Str__at(matter, from), Str__at(matter, to+1));
int rw = Analyser__is_reserved_word(HT, id, (int) rule->match_keyword_of_colour);
DISCARD_TEXT(id)
if (rw == FALSE) return FALSE;
} else if (rule->match_colour != NOT_A_COLOUR) {
for (int i=from; i<=to; i++)
if (Str__get_at(colouring, i) != rule->match_colour)
return FALSE;
}
return TRUE;
}
#line 365 "inweb/Chapter 4/The Painter.w"
void Painter__follow(hash_table *HT, colouring_rule *rule, text_stream *matter,
text_stream *colouring, int from, int to) {
if (rule->execute_block)
Painter__execute(HT, rule->execute_block, matter, colouring, from, to, 0);
else if (rule->debug)
{
#line 381 "inweb/Chapter 4/The Painter.w"
PRINT("[%d, %d] text: ", from, to);
for (int i=from; i<=to; i++)
PUT_TO(STDOUT, Str__get_at(matter, i));
PRINT("\n[%d, %d] cols: ", from, to);
for (int i=from; i<=to; i++)
PUT_TO(STDOUT, Str__get_at(colouring, i));
PRINT("\n");
}
#line 369 "inweb/Chapter 4/The Painter.w"
else {
if (rule->set_to_colour != NOT_A_COLOUR)
for (int i=from; i<=to; i++)
Str__put_at(colouring, i, rule->set_to_colour);
if (rule->set_prefix_to_colour != NOT_A_COLOUR)
for (int i=rule->fix_position; i<rule->fix_position+Str__len(rule->match_text); i++)
Str__put_at(colouring, i, rule->set_prefix_to_colour);
}
}
#line 392 "inweb/Chapter 4/The Painter.w"
linked_list *Painter__lines(filename *F) {
linked_list *L = NEW_LINKED_LIST(text_stream);
TextFiles__read(F, FALSE, "unable to read file of textual extract", TRUE,
&Painter__text_file_helper, NULL, L);
int n = -1, c = 0;
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, L) {
c++;
if (Str__is_whitespace(T) == FALSE)
n = c;
}
if (n >= 0) {
linked_list *R = NEW_LINKED_LIST(text_stream);
c = 0;
LOOP_OVER_LINKED_LIST(T, text_stream, L)
if (++c <= n)
ADD_TO_LINKED_LIST(T, text_stream, R);
return R;
}
return L;
}
void Painter__text_file_helper(text_stream *text, text_file_position *tfp, void *state) {
linked_list *L = (linked_list *) state;
ADD_TO_LINKED_LIST(Str__duplicate(text), text_stream, L);
}
void Painter__colour_file(programming_language *pl, filename *F, text_stream *to, text_stream *coloured) {
linked_list *L = Painter__lines(F);
if (pl) Painter__reset_syntax_colouring(pl);
int c = 1;
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, L) {
if (c++ > 1) { PUT_TO(to, '\n'); PUT_TO(coloured, NEWLINE_COLOUR); }
Str__trim_white_space_at_end(T);
TEMPORARY_TEXT(ST)
TEMPORARY_TEXT(SC)
LOOP_THROUGH_TEXT(pos, T)
if (Str__get(pos) == '\t')
WRITE_TO(ST, " ");
else
PUT_TO(ST, Str__get(pos));
if (pl) {
Painter__syntax_colour(pl, (pl)?(&(pl->built_in_keywords)):NULL, ST, SC, TRUE);
} else {
LOOP_THROUGH_TEXT(pos, ST)
PUT_TO(SC, PLAIN_COLOUR);
}
WRITE_TO(to, "%S", ST);
WRITE_TO(coloured, "%S", SC);
}
if (c > 0) { PUT_TO(to, '\n'); PUT_TO(coloured, NEWLINE_COLOUR); }
}
#line 9 "inweb/Chapter 4/C-Like Languages.w"
void CLike__make_c_like(programming_language *pl) {
METHOD_ADD(pl, PARSE_TYPES_PAR_MTID, CLike__parse_types);
METHOD_ADD(pl, PARSE_FUNCTIONS_PAR_MTID, CLike__parse_functions);
METHOD_ADD(pl, SUBCATEGORISE_LINE_PAR_MTID, CLike__subcategorise_code);
METHOD_ADD(pl, ADDITIONAL_EARLY_MATTER_TAN_MTID, CLike__additional_early_matter);
METHOD_ADD(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, CLike__additional_predeclarations);
}
#line 24 "inweb/Chapter 4/C-Like Languages.w"
void CLike__parse_types(programming_language *self, web *W) {
{
#line 50 "inweb/Chapter 4/C-Like Languages.w"
language_type *current_str = NULL;
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
if (Str__len(L->extract_to) == 0) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"typedef struct (%i+) %c*{%c*")) {
current_str = Functions__new_struct(W, mr.exp[0], L);
Tags__add_by_name(L->owning_paragraph, TL_IS_432);
} else if ((Str__get_first_char(L->text) == '}') && (current_str)) {
current_str->typedef_ends = L;
current_str = NULL;
} else if ((current_str) && (current_str->typedef_ends == NULL)) {
{
#line 82 "inweb/Chapter 4/C-Like Languages.w"
TEMPORARY_TEXT(p)
Str__copy(p, L->text);
Str__trim_white_space(p);
{
#line 104 "inweb/Chapter 4/C-Like Languages.w"
wchar_t *modifier_patterns[] = {
L"(struct )(%C%c*)", L"(signed )(%C%c*)", L"(unsigned )(%C%c*)",
L"(short )(%C%c*)", L"(long )(%C%c*)", L"(static )(%C%c*)", NULL };
int seek_modifiers = TRUE;
while (seek_modifiers) {
seek_modifiers = FALSE;
for (int i = 0; modifier_patterns[i]; i++)
if (Regexp__match(&mr, p, modifier_patterns[i])) {
Str__copy(p, mr.exp[1]);
seek_modifiers = TRUE;
break;
}
}
}
#line 85 "inweb/Chapter 4/C-Like Languages.w"
;
string_position pos = Str__start(p);
if (Str__get(pos) != '/') { /* a slash must introduce a comment here */
{
#line 122 "inweb/Chapter 4/C-Like Languages.w"
while ((Str__get(pos)) && (Characters__is_space_or_tab(Str__get(pos)) == FALSE))
pos = Str__forward(pos);
}
#line 88 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 128 "inweb/Chapter 4/C-Like Languages.w"
while ((Characters__is_space_or_tab(Str__get(pos))) || (Str__get(pos) == '*') ||
(Str__get(pos) == '(') || (Str__get(pos) == ')')) pos = Str__forward(pos);
}
#line 89 "inweb/Chapter 4/C-Like Languages.w"
;
if (Str__in_range(pos)) {
match_results mr = Regexp__create_mr();
TEMPORARY_TEXT(elname)
{
#line 135 "inweb/Chapter 4/C-Like Languages.w"
Str__substr(elname, pos, Str__end(p));
if (Regexp__match(&mr, elname, L"(%i+)%c*")) Str__copy(elname, mr.exp[0]);
}
#line 93 "inweb/Chapter 4/C-Like Languages.w"
;
Functions__new_element(current_str, elname, L);
DISCARD_TEXT(elname)
Regexp__dispose_of(&mr);
}
}
DISCARD_TEXT(p)
}
#line 64 "inweb/Chapter 4/C-Like Languages.w"
;
} else if ((Regexp__match(&mr, L->text, L"typedef %c+")) &&
(Regexp__match(&mr, L->text, L"%c+##%c+") == FALSE)) {
if (L->owning_paragraph->placed_very_early == FALSE)
L->category = TYPEDEF_LCAT;
}
Regexp__dispose_of(&mr);
}
}
}
#line 25 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 152 "inweb/Chapter 4/C-Like Languages.w"
language_type *current_str;
LOOP_OVER(current_str, language_type) {
for (source_line *L = current_str->structure_header_at;
((L) && (L != current_str->typedef_ends));
L = L->next_line) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L" struct (%i+) %i%c*"))
{
#line 165 "inweb/Chapter 4/C-Like Languages.w"
text_stream *used_structure = mr.exp[0];
language_type *str;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
if ((str != current_str) &&
(Str__eq(used_structure, str->structure_name)))
ADD_TO_LINKED_LIST(str, language_type, current_str->incorporates);
}
#line 159 "inweb/Chapter 4/C-Like Languages.w"
;
Regexp__dispose_of(&mr);
}
}
}
#line 26 "inweb/Chapter 4/C-Like Languages.w"
;
}
#line 184 "inweb/Chapter 4/C-Like Languages.w"
int cc_sp = 0;
source_line *cc_stack[MAX_CONDITIONAL_COMPILATION_STACK];
void CLike__parse_functions(programming_language *self, web *W) {
cc_sp = 0;
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if ((L->category == CODE_BODY_LCAT) ||
(L->category == BEGIN_DEFINITION_LCAT) ||
(L->category == CONT_DEFINITION_LCAT)) {
{
#line 203 "inweb/Chapter 4/C-Like Languages.w"
match_results mr = Regexp__create_mr();
if ((Regexp__match(&mr, L->text, L" *#ifn*def %c+")) ||
(Regexp__match(&mr, L->text, L" *#IFN*DEF %c+"))) {
if (cc_sp >= MAX_CONDITIONAL_COMPILATION_STACK)
Main__error_in_web(TL_IS_434, L);
else
cc_stack[cc_sp++] = L;
}
if ((Regexp__match(&mr, L->text, L" *#endif *")) ||
(Regexp__match(&mr, L->text, L" *#ENDIF *"))) {
if (cc_sp <= 0)
Main__error_in_web(TL_IS_435, L);
else
cc_sp--;
}
}
#line 195 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 229 "inweb/Chapter 4/C-Like Languages.w"
if (!(Characters__is_space_or_tab(Str__get_first_char(L->text)))) {
TEMPORARY_TEXT(qualifiers)
TEMPORARY_TEXT(modified)
Str__copy(modified, L->text);
{
#line 256 "inweb/Chapter 4/C-Like Languages.w"
wchar_t *modifier_patterns[] = {
L"(signed )(%C%c*)", L"(unsigned )(%C%c*)",
L"(short )(%C%c*)", L"(long )(%C%c*)", L"(static )(%C%c*)", NULL };
int seek_modifiers = TRUE;
while (seek_modifiers) {
seek_modifiers = FALSE;
match_results mr = Regexp__create_mr();
for (int i = 0; modifier_patterns[i]; i++)
if (Regexp__match(&mr, modified, modifier_patterns[i])) {
Str__concatenate(qualifiers, mr.exp[0]);
Str__copy(modified, mr.exp[1]);
seek_modifiers = TRUE; break;
}
Regexp__dispose_of(&mr);
}
}
#line 233 "inweb/Chapter 4/C-Like Languages.w"
;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, modified, L"(%i+) (%**)(%i+)%((%c*)")) {
TEMPORARY_TEXT(ftype) Str__copy(ftype, mr.exp[0]);
TEMPORARY_TEXT(asts) Str__copy(asts, mr.exp[1]);
TEMPORARY_TEXT(fname) Str__copy(fname, mr.exp[2]);
TEMPORARY_TEXT(arguments) Str__copy(arguments, mr.exp[3]);
{
#line 273 "inweb/Chapter 4/C-Like Languages.w"
{
#line 293 "inweb/Chapter 4/C-Like Languages.w"
source_line *AL = L;
int arg_lc = 1;
while ((AL) && (arg_lc <= MAX_ARG_LINES) && (Regexp__find_open_brace(arguments) == -1)) {
if (AL->next_line == NULL) {
TEMPORARY_TEXT(err_mess)
WRITE_TO(err_mess, "Function '%S' has a malformed declaration", fname);
Main__error_in_web(err_mess, L);
DISCARD_TEXT(err_mess)
break;
}
AL = AL->next_line;
WRITE_TO(arguments, " %S", AL->text);
arg_lc++;
}
int n = Regexp__find_open_brace(arguments);
if (n >= 0) Str__truncate(arguments, n);
}
#line 273 "inweb/Chapter 4/C-Like Languages.w"
;
language_function *fn = Functions__new_function(fname, L);
fn->function_arguments = Str__duplicate(arguments);
WRITE_TO(fn->function_type, "%S%S %S", qualifiers, ftype, asts);
if (Str__eq_wide_string(fn->function_name, L"isdigit")) fn->call_freely = TRUE;
fn->no_conditionals = cc_sp;
for (int i=0; i<cc_sp; i++) fn->within_conditionals[i] = cc_stack[i];
}
#line 240 "inweb/Chapter 4/C-Like Languages.w"
;
DISCARD_TEXT(ftype)
DISCARD_TEXT(asts)
DISCARD_TEXT(fname)
DISCARD_TEXT(arguments)
}
DISCARD_TEXT(qualifiers)
DISCARD_TEXT(modified)
Regexp__dispose_of(&mr);
}
}
#line 196 "inweb/Chapter 4/C-Like Languages.w"
;
}
if (cc_sp > 0)
Main__error_in_web(TL_IS_433, NULL);
}
#line 316 "inweb/Chapter 4/C-Like Languages.w"
void CLike__subcategorise_code(programming_language *self, source_line *L) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"#include <(%C+)>%c*")) {
text_stream *library_file = mr.exp[0];
wchar_t *ansi_libs[] = {
L"assert.h", L"ctype.h", L"errno.h", L"float.h", L"limits.h",
L"locale.h", L"math.h", L"setjmp.h", L"signal.h", L"stdarg.h",
L"stddef.h", L"stdio.h", L"stdlib.h", L"string.h", L"time.h",
NULL
};
for (int j = 0; ansi_libs[j]; j++)
if (Str__eq_wide_string(library_file, ansi_libs[j]))
L->category = C_LIBRARY_INCLUDE_LCAT;
}
Regexp__dispose_of(&mr);
}
#line 345 "inweb/Chapter 4/C-Like Languages.w"
void CLike__additional_early_matter(programming_language *self, text_stream *OUT, web *W, tangle_target *target) {
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, target)
if (L->category == C_LIBRARY_INCLUDE_LCAT) {
Tags__open_ifdefs(OUT, L->owning_paragraph);
Tangler__tangle_line(OUT, L->text, S, L);
WRITE("\n");
Tags__close_ifdefs(OUT, L->owning_paragraph);
}
}
#line 364 "inweb/Chapter 4/C-Like Languages.w"
void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) {
{
#line 393 "inweb/Chapter 4/C-Like Languages.w"
language_type *str;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
str->tangled = FALSE;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
CLike__tangle_structure(OUT, self, str);
}
#line 365 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 374 "inweb/Chapter 4/C-Like Languages.w"
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if (L->category == TYPEDEF_LCAT) {
Tags__open_ifdefs(OUT, L->owning_paragraph);
LanguageMethods__tangle_line(OUT, W->main_language, L->text);
WRITE("\n");
Tags__close_ifdefs(OUT, L->owning_paragraph);
}
}
#line 366 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 435 "inweb/Chapter 4/C-Like Languages.w"
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if (L->function_defined) {
if (L->owning_paragraph == NULL) {
TEMPORARY_TEXT(err_mess)
WRITE_TO(err_mess, "Function '%S' seems outside of any paragraph",
L->function_defined->function_name);
Main__error_in_web(err_mess, L);
DISCARD_TEXT(err_mess)
continue;
}
if (L->owning_paragraph->placed_very_early == FALSE) {
language_function *fn = L->function_defined;
int to_close = 0;
for (int i=0; i<fn->no_conditionals; i++) {
match_results mr = Regexp__create_mr();
if (!(Regexp__match(&mr, fn->within_conditionals[i]->text,
L"%c*inweb: always predeclare%c*"))) {
WRITE("%S\n", fn->within_conditionals[i]->text);
to_close++;
}
}
Tags__open_ifdefs(OUT, L->owning_paragraph);
LanguageMethods__insert_line_marker(OUT, W->main_language, L);
WRITE("%S ", fn->function_type);
LanguageMethods__tangle_line(OUT, W->main_language, fn->function_name);
WRITE("(%S;\n", fn->function_arguments);
Tags__close_ifdefs(OUT, L->owning_paragraph);
for (int i=0; i<to_close; i++) {
WRITE("#endif\n");
}
}
}
}
#line 367 "inweb/Chapter 4/C-Like Languages.w"
;
}
#line 402 "inweb/Chapter 4/C-Like Languages.w"
void CLike__tangle_structure(OUTPUT_STREAM, programming_language *self, language_type *str) {
if (str->tangled != FALSE) return;
str->tangled = NOT_APPLICABLE;
language_type *embodied = NULL;
LOOP_OVER_LINKED_LIST(embodied, language_type, str->incorporates)
CLike__tangle_structure(OUT, self, embodied);
str->tangled = TRUE;
Tags__open_ifdefs(OUT, str->structure_header_at->owning_paragraph);
LanguageMethods__insert_line_marker(OUT, self, str->structure_header_at);
for (source_line *L = str->structure_header_at; L; L = L->next_line) {
WRITE("%S\n", L->text);
L->suppress_tangling = TRUE;
if (L == str->typedef_ends) break;
}
Tags__close_ifdefs(OUT, str->structure_header_at->owning_paragraph);
}
#line 10 "inweb/Chapter 4/InC Support.w"
void InCSupport__add_features(programming_language *pl) {
METHOD_ADD(pl, FURTHER_PARSING_PAR_MTID, InCSupport__further_parsing);
METHOD_ADD(pl, SUPPRESS_EXPANSION_TAN_MTID, InCSupport__suppress_expansion);
METHOD_ADD(pl, TANGLE_COMMAND_TAN_MTID, InCSupport__special_tangle_command);
METHOD_ADD(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, InCSupport__additional_predeclarations);
METHOD_ADD(pl, WILL_TANGLE_EXTRA_LINE_TAN_MTID, InCSupport__will_insert_in_tangle);
METHOD_ADD(pl, TANGLE_EXTRA_LINE_TAN_MTID, InCSupport__insert_in_tangle);
METHOD_ADD(pl, TANGLE_LINE_UNUSUALLY_TAN_MTID, InCSupport__tangle_line);
METHOD_ADD(pl, GNABEHS_TAN_MTID, InCSupport__gnabehs);
METHOD_ADD(pl, ADDITIONAL_TANGLING_TAN_MTID, InCSupport__additional_tangling);
METHOD_ADD(pl, SKIP_IN_WEAVING_WEA_MTID, InCSupport__skip_in_weaving);
METHOD_ADD(pl, WEAVE_CODE_LINE_WEA_MTID, InCSupport__weave_code_line);
METHOD_ADD(pl, NOTIFY_NEW_TAG_WEA_MTID, InCSupport__new_tag_declared);
METHOD_ADD(pl, ANALYSIS_ANA_MTID, InCSupport__analyse_code);
METHOD_ADD(pl, SHARE_ELEMENT_ANA_MTID, InCSupport__share_element);
}
#line 33 "inweb/Chapter 4/InC Support.w"
theme_tag *Preform_theme = NULL;
#line 39 "inweb/Chapter 4/InC Support.w"
preform_nonterminal *alphabetical_list_of_nonterminals = NULL;
void InCSupport__further_parsing(programming_language *self, web *W) {
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if ((L->category == CODE_BODY_LCAT) || (L->category == CONT_DEFINITION_LCAT)) {
{
#line 67 "inweb/Chapter 4/InC Support.w"
int form = NOT_A_NONTERMINAL; /* one of the four values above, or a non-negative word count */
TEMPORARY_TEXT(pntname)
TEMPORARY_TEXT(header)
{
#line 80 "inweb/Chapter 4/InC Support.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"(<%p+>) ::=%c*")) {
form = A_GRAMMAR_NONTERMINAL;
Str__copy(pntname, mr.exp[0]);
Str__copy(header, mr.exp[0]);
{
#line 218 "inweb/Chapter 4/InC Support.w"
Tags__add_by_name(L->owning_paragraph, TL_IS_436);
source_line *AL;
for (AL = L; (AL) && (AL->category == CODE_BODY_LCAT); AL = AL->next_line) {
if (Regexp__string_is_white_space(AL->text)) break;
AL->category = PREFORM_GRAMMAR_LCAT;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, AL->text, L"(%c+?) ==> (%c*)")) {
AL->text_operand = Str__duplicate(mr.exp[0]);
AL->text_operand2 = Str__duplicate(mr.exp[1]);
} else {
AL->text_operand = AL->text;
AL->text_operand2 = Str__new();
}
{
#line 244 "inweb/Chapter 4/InC Support.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, AL->text_operand, L"(%c*)%/%*%c*%*%/ *"))
AL->text_operand = Str__duplicate(mr.exp[0]);
Regexp__dispose_of(&mr);
}
#line 231 "inweb/Chapter 4/InC Support.w"
;
{
#line 254 "inweb/Chapter 4/InC Support.w"
TEMPORARY_TEXT(to_scan) Str__copy(to_scan, AL->text_operand2);
match_results mr = Regexp__create_mr();
while (Regexp__match(&mr, to_scan, L"%c*?<<(%P+?)>> =(%c*)")) {
TEMPORARY_TEXT(var_given) Str__copy(var_given, mr.exp[0]);
TEMPORARY_TEXT(type_given) WRITE_TO(type_given, "int");
Str__copy(to_scan, mr.exp[1]);
if (Regexp__match(&mr, var_given, L"(%p+):%p+")) {
Str__clear(type_given);
WRITE_TO(type_given, "%S *", mr.exp[0]);
}
nonterminal_variable *ntv;
LOOP_OVER(ntv, nonterminal_variable)
if (Str__eq(ntv->ntv_name, var_given))
break;
if (ntv == NULL)
{
#line 289 "inweb/Chapter 4/InC Support.w"
ntv = CREATE(nonterminal_variable);
ntv->ntv_name = Str__duplicate(var_given);
ntv->ntv_type = Str__duplicate(type_given);
LOOP_THROUGH_TEXT(P, var_given)
if ((Str__get(P) == '-') || (Str__get(P) == ':'))
Str__put(P, '_');
ntv->ntv_identifier = Str__new();
WRITE_TO(ntv->ntv_identifier, "%S_NTMV", var_given);
ntv->first_mention = AL;
}
#line 268 "inweb/Chapter 4/InC Support.w"
;
DISCARD_TEXT(var_given)
DISCARD_TEXT(type_given)
}
DISCARD_TEXT(to_scan)
Regexp__dispose_of(&mr);
}
#line 232 "inweb/Chapter 4/InC Support.w"
;
Regexp__dispose_of(&mr);
}
}
#line 85 "inweb/Chapter 4/InC Support.w"
;
} else if (Regexp__match(&mr, L->text, L"((<%p+>) internal %?) {%c*")) {
form = A_VORACIOUS_NONTERMINAL;
Str__copy(pntname, mr.exp[1]);
Str__copy(header, mr.exp[0]);
} else if (Regexp__match(&mr, L->text, L"((<%p+>) internal) {%c*")) {
form = A_FLEXIBLE_NONTERMINAL;
Str__copy(pntname, mr.exp[1]);
Str__copy(header, mr.exp[0]);
} else if (Regexp__match(&mr, L->text, L"((<%p+>) internal (%d+)) {%c*")) {
form = Str__atoi(mr.exp[2], 0);
Str__copy(pntname, mr.exp[1]);
Str__copy(header, mr.exp[0]);
}
Regexp__dispose_of(&mr);
}
#line 70 "inweb/Chapter 4/InC Support.w"
;
if (form != NOT_A_NONTERMINAL)
{
#line 122 "inweb/Chapter 4/InC Support.w"
preform_nonterminal *pnt = CREATE(preform_nonterminal);
pnt->where_defined = L;
pnt->nt_name = Str__duplicate(pntname);
pnt->unangled_name = Str__duplicate(pntname);
pnt->as_C_identifier = Str__duplicate(pntname);
pnt->next_pnt_alphabetically = NULL;
{
#line 136 "inweb/Chapter 4/InC Support.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, pntname, L"%<(%c*)%>")) pnt->unangled_name = Str__duplicate(mr.exp[0]);
Regexp__dispose_of(&mr);
}
#line 128 "inweb/Chapter 4/InC Support.w"
;
{
#line 146 "inweb/Chapter 4/InC Support.w"
Str__delete_first_character(pnt->as_C_identifier);
LOOP_THROUGH_TEXT(pos, pnt->as_C_identifier) {
if (Str__get(pos) == '-') Str__put(pos, '_');
if (Str__get(pos) == '>') { Str__put(pos, 0); break; }
}
WRITE_TO(pnt->as_C_identifier, "_NTM");
}
#line 129 "inweb/Chapter 4/InC Support.w"
;
{
#line 161 "inweb/Chapter 4/InC Support.w"
pnt->voracious = FALSE; if (form == A_VORACIOUS_NONTERMINAL) pnt->voracious = TRUE;
pnt->as_function = TRUE; if (form == A_GRAMMAR_NONTERMINAL) pnt->as_function = FALSE;
pnt->takes_pointer_result = FALSE;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, pnt->nt_name, L"<k-%c+")) pnt->takes_pointer_result = TRUE;
if (Regexp__match(&mr, pnt->nt_name, L"<s-%c+")) pnt->takes_pointer_result = TRUE;
Regexp__dispose_of(&mr);
int min = 1, max = form;
if (form < 0) max = INFINITE_WORD_COUNT;
if (max == 0) min = 0;
else if (max != INFINITE_WORD_COUNT) min = max;
pnt->min_word_count = min;
pnt->max_word_count = max;
}
#line 130 "inweb/Chapter 4/InC Support.w"
;
{
#line 178 "inweb/Chapter 4/InC Support.w"
if (alphabetical_list_of_nonterminals == NULL) alphabetical_list_of_nonterminals = pnt;
else {
int placed = FALSE;
preform_nonterminal *last = NULL;
for (preform_nonterminal *seq = alphabetical_list_of_nonterminals; seq;
seq = seq->next_pnt_alphabetically) {
if (Str__cmp(pntname, seq->nt_name) < 0) {
if (seq == alphabetical_list_of_nonterminals) {
pnt->next_pnt_alphabetically = alphabetical_list_of_nonterminals;
alphabetical_list_of_nonterminals = pnt;
} else {
last->next_pnt_alphabetically = pnt;
pnt->next_pnt_alphabetically = seq;
}
placed = TRUE;
break;
}
last = seq;
}
if (placed == FALSE) last->next_pnt_alphabetically = pnt;
}
}
#line 132 "inweb/Chapter 4/InC Support.w"
;
{
#line 201 "inweb/Chapter 4/InC Support.w"
L->preform_nonterminal_defined = pnt;
if (Preform_theme) Tags__add_to_paragraph(L->owning_paragraph, Preform_theme, NULL);
L->category = PREFORM_LCAT;
L->text_operand = Str__duplicate(header);
}
#line 133 "inweb/Chapter 4/InC Support.w"
;
}
#line 71 "inweb/Chapter 4/InC Support.w"
;
DISCARD_TEXT(pntname)
DISCARD_TEXT(header)
}
#line 46 "inweb/Chapter 4/InC Support.w"
;
{
#line 305 "inweb/Chapter 4/InC Support.w"
for (int i = 0, quoted = FALSE; i < Str__len(L->text); i++) {
if (Str__get_at(L->text, i) == '"')
if ((Str__get_at(L->text, i-1) != '\\') &&
((Str__get_at(L->text, i-1) != '\'') || (Str__get_at(L->text, i+1) != '\'')))
quoted = quoted?FALSE:TRUE;
if ((fundamental_mode != WEAVE_MODE) && (quoted == FALSE) &&
(Str__get_at(L->text, i) == 'I') && (Str__get_at(L->text, i+1) == '"'))
{
#line 316 "inweb/Chapter 4/InC Support.w"
TEMPORARY_TEXT(lit)
int i_was = i;
int ended = FALSE;
i += 2;
while (Str__get_at(L->text, i)) {
if (Str__get_at(L->text, i) == '"') { ended = TRUE; break; }
PUT_TO(lit, Str__get_at(L->text, i++));
}
if (ended)
{
#line 347 "inweb/Chapter 4/InC Support.w"
text_literal *tl = CREATE(text_literal);
tl->tl_identifier = Str__new();
WRITE_TO(tl->tl_identifier, "TL_IS_%d", tl->allocation_id);
tl->tl_content = Str__duplicate(lit);
TEMPORARY_TEXT(before)
TEMPORARY_TEXT(after)
Str__copy(before, L->text);
Str__truncate(before, i_was);
Str__copy_tail(after, L->text, i+1);
Str__clear(L->text);
WRITE_TO(L->text, "%S%S", before, tl->tl_identifier);
i = Str__len(L->text);
WRITE_TO(L->text, "%S", after);
DISCARD_TEXT(before)
DISCARD_TEXT(after)
}
#line 324 "inweb/Chapter 4/InC Support.w"
;
DISCARD_TEXT(lit)
}
#line 312 "inweb/Chapter 4/InC Support.w"
;
}
}
#line 47 "inweb/Chapter 4/InC Support.w"
}
}
#line 118 "inweb/Chapter 4/InC Support.w"
#line 287 "inweb/Chapter 4/InC Support.w"
#line 337 "inweb/Chapter 4/InC Support.w"
#line 368 "inweb/Chapter 4/InC Support.w"
int InCSupport__suppress_expansion(programming_language *self, text_stream *material) {
if ((Str__get_at(material, 0) == '/') && (Str__get_at(material, 1) == '/'))
return TRUE;
return FALSE;
}
#line 392 "inweb/Chapter 4/InC Support.w"
int InCSupport__special_tangle_command(programming_language *me, OUTPUT_STREAM, text_stream *data) {
if (Str__eq_wide_string(data, L"nonterminals")) {
WRITE("register_tangled_nonterminals();\n");
return TRUE;
}
if (Str__eq_wide_string(data, L"textliterals")) {
WRITE("register_tangled_text_literals();\n");
return TRUE;
}
return FALSE;
}
#line 416 "inweb/Chapter 4/InC Support.w"
void InCSupport__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) {
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if (L->preform_nonterminal_defined) {
preform_nonterminal *pnt = L->preform_nonterminal_defined;
LanguageMethods__insert_line_marker(OUT, W->main_language, L);
WRITE("nonterminal *%S = NULL;\n", pnt->as_C_identifier);
}
nonterminal_variable *ntv;
LOOP_OVER(ntv, nonterminal_variable)
WRITE("%S %S = %s;\n",
ntv->ntv_type, ntv->ntv_identifier,
(Str__eq_wide_string(ntv->ntv_type, L"int"))?"0":"NULL");
WRITE("void register_tangled_nonterminals(void);\n");
text_literal *tl;
LOOP_OVER(tl, text_literal)
WRITE("text_stream *%S = NULL;\n", tl->tl_identifier);
WRITE("void register_tangled_text_literals(void);\n");
}
#line 445 "inweb/Chapter 4/InC Support.w"
void InCSupport__gnabehs(programming_language *self, text_stream *OUT, web *W) {
WRITE("void register_tangled_nonterminals(void) {\n");
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if (L->preform_nonterminal_defined) {
preform_nonterminal *pnt = L->preform_nonterminal_defined;
LanguageMethods__insert_line_marker(OUT, W->main_language, L);
if (pnt->as_function) {
WRITE("\tINTERNAL_NONTERMINAL(L\"%S\", %S, %d, %d);\n",
pnt->nt_name, pnt->as_C_identifier,
pnt->min_word_count, pnt->max_word_count);
WRITE("\t%S->voracious = %d;\n",
pnt->as_C_identifier, pnt->voracious);
} else {
WRITE("\tREGISTER_NONTERMINAL(L\"%S\", %S);\n",
pnt->nt_name, pnt->as_C_identifier);
}
}
WRITE("}\n");
WRITE("void register_tangled_text_literals(void) {\n"); INDENT;
text_literal *tl;
LOOP_OVER(tl, text_literal)
WRITE("%S = Str__literal(L\"%S\");\n", tl->tl_identifier, tl->tl_content);
OUTDENT; WRITE("}\n");
}
#line 479 "inweb/Chapter 4/InC Support.w"
int InCSupport__will_insert_in_tangle(programming_language *self, source_line *L) {
if (L->category == PREFORM_LCAT) return TRUE;
return FALSE;
}
#line 500 "inweb/Chapter 4/InC Support.w"
void InCSupport__insert_in_tangle(programming_language *self, text_stream *OUT, source_line *L) {
preform_nonterminal *pnt = L->preform_nonterminal_defined;
if (pnt->as_function) {
WRITE("int %SR(wording W, int *X, void **XP) {\n",
pnt->as_C_identifier);
} else {
WRITE("int %SC(int *X, void **XP, int *R, void **RP, wording *FW, wording W) {\n",
pnt->as_C_identifier);
{
#line 557 "inweb/Chapter 4/InC Support.w"
int needs_collation = FALSE;
for (source_line *AL = L->next_line;
((AL) && (AL->category == PREFORM_GRAMMAR_LCAT));
AL = AL->next_line)
if (Str__len(AL->text_operand2) > 0)
needs_collation = TRUE;
if (needs_collation)
{
#line 575 "inweb/Chapter 4/InC Support.w"
WRITE("\tswitch(R[0]) {\n");
int c = 0;
for (source_line *AL = L->next_line;
((AL) && (AL->category == PREFORM_GRAMMAR_LCAT));
AL = AL->next_line, c++) {
text_stream *formula = AL->text_operand2;
if (Str__len(formula) > 0) {
LanguageMethods__insert_line_marker(OUT, AL->owning_section->sect_language, AL);
WRITE("\t\tcase %d: ", c);
{
#line 613 "inweb/Chapter 4/InC Support.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, formula, L"{ *(%c*?) *} *(%c*)")) {
TEMPORARY_TEXT(rewritten)
WRITE_TO(rewritten, "==");
WRITE_TO(rewritten, "> { %S }", mr.exp[0]);
InCSupport__tangle_line_inner(OUT, AL, pnt, rewritten);
InCSupport__expand_formula(OUT, AL, pnt, mr.exp[1], TRUE);
DISCARD_TEXT(rewritten)
} else {
if (!Regexp__match(&mr, formula, L"@<%c*")) {
if (pnt->takes_pointer_result) WRITE("*XP = ");
else WRITE("*X = ");
}
InCSupport__expand_formula(OUT, AL, pnt, formula, TRUE);
}
Regexp__dispose_of(&mr);
}
#line 584 "inweb/Chapter 4/InC Support.w"
;
WRITE(";\n");
WRITE("#pragma clang diagnostic push\n");
WRITE("#pragma clang diagnostic ignored \"-Wunreachable-code\"\n");
WRITE("break;\n");
WRITE("#pragma clang diagnostic pop\n");
}
}
WRITE("\t\tdefault: *X = R[0]; break;\n");
WRITE("\t}\n");
}
#line 563 "inweb/Chapter 4/InC Support.w"
else
{
#line 572 "inweb/Chapter 4/InC Support.w"
WRITE("\t*X = R[0];\n");
}
#line 564 "inweb/Chapter 4/InC Support.w"
;
WRITE("\treturn TRUE;\n");
}
#line 508 "inweb/Chapter 4/InC Support.w"
;
WRITE("}\n");
}
}
#line 633 "inweb/Chapter 4/InC Support.w"
void InCSupport__expand_formula(text_stream *OUT, source_line *AL, preform_nonterminal *pnt,
text_stream *formula, int full) {
TEMPORARY_TEXT(expanded)
for (int i=0; i < Str__len(formula); i++) {
if ((Str__get_at(formula, i) == 'W') && (Str__get_at(formula, i+1) == 'R') &&
(Str__get_at(formula, i+2) == '[') &&
(isdigit(Str__get_at(formula, i+3))) && (Str__get_at(formula, i+4) == ']')) {
if (pnt == NULL) {
Main__error_in_web(TL_IS_437, AL);
if (AL == NULL) WRITE_TO(STDERR, "%S\n", formula);
} else {
WRITE_TO(expanded,
"%S->range_result[%c]", pnt->as_C_identifier, Str__get_at(formula, i+3));
}
i += 4;
} else {
PUT_TO(expanded, Str__get_at(formula, i));
}
}
if (full) Tangler__tangle_line(OUT, expanded, AL->owning_section, AL);
else InCSupport__tangle_line_inner(OUT, AL, pnt, expanded);
DISCARD_TEXT(expanded)
}
#line 661 "inweb/Chapter 4/InC Support.w"
int InCSupport__tangle_line(programming_language *self, text_stream *OUT, text_stream *original) {
InCSupport__tangle_line_inner(OUT, NULL, NULL, original);
return TRUE;
}
void InCSupport__tangle_line_inner(text_stream *OUT, source_line *AL, preform_nonterminal *pnt, text_stream *original) {
int fcall_pos = -1;
for (int i = 0; i < Str__len(original); i++) {
{
#line 703 "inweb/Chapter 4/InC Support.w"
if ((i > 0) && (Str__get_at(original, i) == ':') && (Str__get_at(original, i+1) == ':') &&
(isalpha(Str__get_at(original, i+2))) && (isalnum(Str__get_at(original, i-1)))) {
WRITE("__"); i++;
continue;
}
}
#line 669 "inweb/Chapter 4/InC Support.w"
;
{
#line 715 "inweb/Chapter 4/InC Support.w"
if ((Str__get_at(original, i) == '=') &&
(Str__get_at(original, i+1) == '=') &&
(Str__get_at(original, i+2) == '>') &&
(Str__get_at(original, i+3) == ' ') &&
(Str__get_at(original, i+4) == '{')) {
int clauses, err = FALSE;
text_stream *clause[MAX_PREFORM_RESULT_CLAUSES];
{
#line 738 "inweb/Chapter 4/InC Support.w"
clauses = 1;
clause[0] = Str__new();
int bl = 0;
for (int j = i+5; j < Str__len(original); j++) {
wchar_t c = Str__get_at(original, j);
if ((c == ',') && (bl == 0)) {
if (clauses >= MAX_PREFORM_RESULT_CLAUSES) err = TRUE;
else { clause[clauses] = Str__new(); clauses++; }
continue;
}
if ((c == '}') && (bl == 0)) {
i = j; break;
}
switch (c) {
case '(': bl++; break;
case ')': bl--; if (bl < 0) err = TRUE; break;
}
PUT_TO(clause[clauses-1], c);
}
if (bl != 0) err = TRUE;
for (int c=0; c<clauses; c++) Str__trim_white_space(clause[c]);
}
#line 722 "inweb/Chapter 4/InC Support.w"
;
TEMPORARY_TEXT(extra)
if (clauses == 1)
{
#line 765 "inweb/Chapter 4/InC Support.w"
if (Str__eq(clause[0], TL_IS_439)) {
clause[1] = Str__new(); clauses = 2;
WRITE_TO(extra, "return FAIL_NONTERMINAL;");
Str__clear(clause[0]);
WRITE_TO(clause[0], "-");
WRITE_TO(clause[1], "-");
} else if (Str__eq(clause[0], TL_IS_440)) {
clause[1] = Str__new(); clauses = 2;
WRITE_TO(extra, "return FALSE;");
Str__clear(clause[0]);
WRITE_TO(clause[0], "-");
WRITE_TO(clause[1], "-");
} else if (Str__eq(clause[0], TL_IS_441)) {
clause[1] = Str__new(); clauses = 2;
WRITE_TO(extra, "return FALSE;");
Str__clear(clause[0]);
WRITE_TO(clause[0], "-");
WRITE_TO(clause[1], "-");
} else if (Str__prefix_eq(clause[0], TL_IS_442, 8)) {
clause[1] = Str__new(); clauses = 2;
WRITE_TO(extra, "return FAIL_NONTERMINAL + ");
Str__substr(extra, Str__at(clause[0], 8), Str__end(clause[0]));
WRITE_TO(extra, ";");
Str__clear(clause[0]);
WRITE_TO(clause[0], "0");
WRITE_TO(clause[1], "NULL");
} else if (Str__prefix_eq(clause[0], TL_IS_443, 5)) {
clause[1] = Str__new(); clauses = 2;
TEMPORARY_TEXT(from)
Str__substr(from, Str__at(clause[0], 5), Str__end(clause[0]));
Str__clear(clause[0]);
WRITE_TO(clause[0], "R[%S]", from);
WRITE_TO(clause[1], "RP[%S]", from);
DISCARD_TEXT(from)
} else if (Str__eq(clause[0], TL_IS_444)) {
clause[1] = Str__new(); clauses = 2;
Str__clear(clause[0]);
WRITE_TO(clause[0], "0");
WRITE_TO(clause[1], "NULL");
WRITE_TO(extra, "return preform_lookahead_mode;");
}
}
#line 724 "inweb/Chapter 4/InC Support.w"
;
if (clauses < 2) err = TRUE;
if (err == FALSE)
{
#line 815 "inweb/Chapter 4/InC Support.w"
for (int c=0; c<clauses; c++) {
if (Str__ne(clause[c], TL_IS_445)) {
switch (c) {
case 0: WRITE("*X = ");
InCSupport__expand_formula(OUT, AL, pnt, clause[c], FALSE);
WRITE(";"); break;
case 1: WRITE("*XP = ");
InCSupport__expand_formula(OUT, AL, pnt, clause[c], FALSE);
WRITE(";"); break;
default: {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, clause[c], L"<<(%P+)>> = *(%c*)")) {
text_stream *putative = mr.exp[0];
text_stream *pv_identifier =
InCSupport__nonterminal_variable_identifier(putative);
if (pv_identifier) {
WRITE("%S = ", pv_identifier);
InCSupport__expand_formula(OUT, AL, pnt, mr.exp[1], FALSE);
WRITE(";");
} else err = TRUE;
} else err = TRUE;
}
}
}
}
if (Str__ne(extra, TL_IS_446)) {
InCSupport__expand_formula(OUT, AL, pnt, extra, FALSE);
}
}
#line 726 "inweb/Chapter 4/InC Support.w"
;
if (err) {
Main__error_in_web(TL_IS_438, AL);
if (AL == NULL) WRITE_TO(STDERR, "%S\n", original);
}
continue;
}
}
#line 670 "inweb/Chapter 4/InC Support.w"
;
if (Str__get_at(original, i) == '<') {
if (Str__get_at(original, i+1) == '<') {
{
#line 850 "inweb/Chapter 4/InC Support.w"
match_results mr = Regexp__create_mr();
TEMPORARY_TEXT(check_this)
Str__substr(check_this, Str__at(original, i), Str__end(original));
if (Regexp__match(&mr, check_this, L"<<(%P+)>>%c*")) {
text_stream *putative = mr.exp[0];
text_stream *pv_identifier = InCSupport__nonterminal_variable_identifier(putative);
if (pv_identifier) {
WRITE("%S", pv_identifier);
i += Str__len(putative) + 3;
DISCARD_TEXT(check_this)
continue;
}
}
DISCARD_TEXT(check_this)
Regexp__dispose_of(&mr);
}
#line 673 "inweb/Chapter 4/InC Support.w"
;
} else {
{
#line 882 "inweb/Chapter 4/InC Support.w"
match_results mr = Regexp__create_mr();
TEMPORARY_TEXT(check_this)
Str__substr(check_this, Str__at(original, i), Str__end(original));
if (Regexp__match(&mr, check_this, L"(<%p+>)%c*")) {
text_stream *putative = mr.exp[0];
preform_nonterminal *pnt = InCSupport__nonterminal_by_name(putative);
if (pnt) {
i += Str__len(putative) - 1;
if (Str__get_at(original, i+1) == '(') {
int arity = 1;
for (int j = i+2, bl = 1; ((Str__get_at(original, j)) && (bl > 0)); j++) {
if (Str__get_at(original, j) == '(') bl++;
if (Str__get_at(original, j) == ')') { bl--; if (bl == 0) fcall_pos = j; }
if ((Str__get_at(original, j) == ',') && (bl == 1)) arity++;
}
WRITE("Preform__parse_nt_against_word_range(");
}
WRITE("%S", pnt->as_C_identifier);
if (fcall_pos >= 0) {
WRITE(", "); i++;
}
DISCARD_TEXT(check_this)
continue;
}
}
DISCARD_TEXT(check_this)
Regexp__dispose_of(&mr);
}
#line 675 "inweb/Chapter 4/InC Support.w"
;
}
}
if (i == fcall_pos) {
fcall_pos = -1;
WRITE(", NULL, NULL");
}
PUT(Str__get_at(original, i));
}
}
#line 916 "inweb/Chapter 4/InC Support.w"
preform_nonterminal *InCSupport__nonterminal_by_name(text_stream *name) {
preform_nonterminal *pnt;
LOOP_OVER(pnt, preform_nonterminal)
if (Str__eq(name, pnt->nt_name))
return pnt;
return NULL;
}
#line 930 "inweb/Chapter 4/InC Support.w"
text_stream *InCSupport__nonterminal_variable_identifier(text_stream *name) {
if (Str__eq_wide_string(name, L"r")) return TL_IS_447;
if (Str__eq_wide_string(name, L"rp")) return TL_IS_448;
nonterminal_variable *ntv;
LOOP_OVER(ntv, nonterminal_variable)
if (Str__eq(ntv->ntv_name, name))
return ntv->ntv_identifier;
return NULL;
}
#line 951 "inweb/Chapter 4/InC Support.w"
void InCSupport__additional_tangling(programming_language *self, web *W, tangle_target *target) {
if (NUMBER_CREATED(preform_nonterminal) > 0) {
pathname *P = Reader__tangled_folder(W);
filename *Syntax = Filenames__in(P, TL_IS_449);
text_stream TO_struct;
text_stream *OUT = &TO_struct;
if (STREAM_OPEN_TO_FILE(OUT, Syntax, ISO_ENC) == FALSE)
Errors__fatal_with_file("unable to write Preform file", Syntax);
WRITE_TO(STDOUT, "Writing Preform syntax to: %/f\n", Syntax);
WRITE("[Preform syntax generated by inweb: do not edit.]\n\n");
if (Bibliographic__data_exists(W->md, TL_IS_450))
WRITE("language %S\n", Bibliographic__get_datum(W->md, TL_IS_451));
{
#line 986 "inweb/Chapter 4/InC Support.w"
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, target)
if (L->category == PREFORM_LCAT) {
preform_nonterminal *pnt = L->preform_nonterminal_defined;
if (pnt->as_function)
WRITE("\n%S internal\n", pnt->nt_name);
else
WRITE("\n%S ::=\n", L->text_operand);
for (source_line *AL = L->next_line;
((AL) && (AL->category == PREFORM_GRAMMAR_LCAT));
AL = AL->next_line) {
WRITE("%S", AL->text_operand);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, AL->text_operand2, L"%c+Issue (%c+) problem%c+"))
WRITE("[issues %S]", mr.exp[0]);
WRITE("\n");
Regexp__dispose_of(&mr);
}
}
}
#line 968 "inweb/Chapter 4/InC Support.w"
;
STREAM_CLOSE(OUT);
}
}
#line 1014 "inweb/Chapter 4/InC Support.w"
void InCSupport__weave_grammar_index(OUTPUT_STREAM) {
WRITE("\\raggedright\\tolerance=10000");
preform_nonterminal *pnt;
for (pnt = alphabetical_list_of_nonterminals; pnt;
pnt = pnt->next_pnt_alphabetically) {
WRITE("\\line{\\nonterminal{%S}%s"
"\\leaders\\hbox to 1em{\\hss.\\hss}\\hfill {\\xreffont %S}}\n",
pnt->unangled_name,
(pnt->as_function)?" (internal)":"",
pnt->where_defined->owning_section->md->sect_range);
int said_something = FALSE;
{
#line 1061 "inweb/Chapter 4/InC Support.w"
section *S;
LOOP_OVER(S, section) S->scratch_flag = FALSE;
hash_table_entry *hte = Analyser__find_hash_entry_for_section(
pnt->where_defined->owning_section, pnt->unangled_name, FALSE);
hash_table_entry_usage *hteu;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if (hteu->form_of_usage & PREFORM_IN_GRAMMAR_USAGE)
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
int use_count = 0;
LOOP_OVER(S, section)
if (S->scratch_flag)
use_count++;
if (use_count > 0) {
said_something = TRUE;
WRITE("\\par\\hangindent=3em{\\it used by other nonterminals in} ");
int c = 0;
LOOP_OVER(S, section)
if (S->scratch_flag) {
if (c++ > 0) WRITE(", ");
WRITE("{\\xreffont %S}", S->md->sect_range);
}
WRITE("\n\n");
}
}
#line 1025 "inweb/Chapter 4/InC Support.w"
;
{
#line 1036 "inweb/Chapter 4/InC Support.w"
section *S;
LOOP_OVER(S, section) S->scratch_flag = FALSE;
hash_table_entry *hte = Analyser__find_hash_entry_for_section(
pnt->where_defined->owning_section, pnt->unangled_name, FALSE);
hash_table_entry_usage *hteu;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if (hteu->form_of_usage & PREFORM_IN_CODE_USAGE)
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
int use_count = 0;
LOOP_OVER(S, section)
if (S->scratch_flag)
use_count++;
if (use_count > 0) {
said_something = TRUE;
WRITE("\\par\\hangindent=3em{\\it called from} ");
int c = 0;
LOOP_OVER(S, section)
if (S->scratch_flag) {
if (c++ > 0) WRITE(", ");
WRITE("{\\xreffont %S}", S->md->sect_range);
}
WRITE("\n\n");
}
}
#line 1026 "inweb/Chapter 4/InC Support.w"
;
if (said_something == FALSE)
WRITE("\\par\\hangindent=3em{\\it unused}\n\n");
}
WRITE("\\penalty-1000\n");
WRITE("\\smallbreak\n");
WRITE("\\hrule\\smallbreak\n");
}
#line 1090 "inweb/Chapter 4/InC Support.w"
int skipping_internal = FALSE, preform_production_count = 0;
int InCSupport__skip_in_weaving(programming_language *self, weave_order *wv, source_line *L) {
if ((Preform_theme) && (wv->theme_match == Preform_theme)) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"}%c*")) {
skipping_internal = FALSE; Regexp__dispose_of(&mr); return TRUE; }
if (skipping_internal) { Regexp__dispose_of(&mr); return TRUE; }
if (Regexp__match(&mr, L->text, L"<%c*?> internal%c*")) skipping_internal = TRUE;
Regexp__dispose_of(&mr);
}
return FALSE;
}
#line 1107 "inweb/Chapter 4/InC Support.w"
int InCSupport__weave_code_line(programming_language *self, text_stream *OUT,
weave_order *wv, web *W, chapter *C, section *S, source_line *L,
text_stream *matter, text_stream *concluding_comment) {
if ((Preform_theme) && (wv->theme_match == Preform_theme))
return Formats__preform_document(OUT, wv, W, C, S, L,
matter, concluding_comment);
return FALSE;
}
#line 1121 "inweb/Chapter 4/InC Support.w"
void InCSupport__new_tag_declared(programming_language *self, theme_tag *tag) {
if (Str__eq_wide_string(tag->tag_name, L"Preform")) Preform_theme = tag;
}
#line 1128 "inweb/Chapter 4/InC Support.w"
void InCSupport__analyse_code(programming_language *self, web *W) {
preform_nonterminal *pnt;
LOOP_OVER(pnt, preform_nonterminal)
Analyser__find_hash_entry_for_section(pnt->where_defined->owning_section,
pnt->unangled_name, TRUE);
}
int InCSupport__share_element(programming_language *self, text_stream *elname) {
if (Str__eq_wide_string(elname, L"word_ref1")) return TRUE;
if (Str__eq_wide_string(elname, L"word_ref2")) return TRUE;
if (Str__eq_wide_string(elname, L"next")) return TRUE;
if (Str__eq_wide_string(elname, L"down")) return TRUE;
if (Str__eq_wide_string(elname, L"allocation_id")) return TRUE;
if (Str__eq_wide_string(elname, L"method_set")) return TRUE;
return FALSE;
}
#line 10 "inweb/Chapter 5/Weave Tree.w"
#line 15 "inweb/Chapter 5/Weave Tree.w"
#line 19 "inweb/Chapter 5/Weave Tree.w"
#line 24 "inweb/Chapter 5/Weave Tree.w"
#line 29 "inweb/Chapter 5/Weave Tree.w"
#line 34 "inweb/Chapter 5/Weave Tree.w"
#line 39 "inweb/Chapter 5/Weave Tree.w"
#line 44 "inweb/Chapter 5/Weave Tree.w"
#line 49 "inweb/Chapter 5/Weave Tree.w"
#line 54 "inweb/Chapter 5/Weave Tree.w"
#line 58 "inweb/Chapter 5/Weave Tree.w"
#line 62 "inweb/Chapter 5/Weave Tree.w"
#line 66 "inweb/Chapter 5/Weave Tree.w"
#line 72 "inweb/Chapter 5/Weave Tree.w"
#line 76 "inweb/Chapter 5/Weave Tree.w"
#line 83 "inweb/Chapter 5/Weave Tree.w"
#line 88 "inweb/Chapter 5/Weave Tree.w"
#line 94 "inweb/Chapter 5/Weave Tree.w"
#line 101 "inweb/Chapter 5/Weave Tree.w"
#line 107 "inweb/Chapter 5/Weave Tree.w"
#line 115 "inweb/Chapter 5/Weave Tree.w"
#line 123 "inweb/Chapter 5/Weave Tree.w"
#line 129 "inweb/Chapter 5/Weave Tree.w"
#line 134 "inweb/Chapter 5/Weave Tree.w"
#line 139 "inweb/Chapter 5/Weave Tree.w"
#line 144 "inweb/Chapter 5/Weave Tree.w"
#line 148 "inweb/Chapter 5/Weave Tree.w"
#line 154 "inweb/Chapter 5/Weave Tree.w"
#line 160 "inweb/Chapter 5/Weave Tree.w"
#line 166 "inweb/Chapter 5/Weave Tree.w"
#line 171 "inweb/Chapter 5/Weave Tree.w"
#line 178 "inweb/Chapter 5/Weave Tree.w"
#line 182 "inweb/Chapter 5/Weave Tree.w"
#line 187 "inweb/Chapter 5/Weave Tree.w"
#line 191 "inweb/Chapter 5/Weave Tree.w"
#line 197 "inweb/Chapter 5/Weave Tree.w"
#line 203 "inweb/Chapter 5/Weave Tree.w"
#line 210 "inweb/Chapter 5/Weave Tree.w"
#line 215 "inweb/Chapter 5/Weave Tree.w"
#line 220 "inweb/Chapter 5/Weave Tree.w"
#line 225 "inweb/Chapter 5/Weave Tree.w"
#line 230 "inweb/Chapter 5/Weave Tree.w"
#line 236 "inweb/Chapter 5/Weave Tree.w"
#line 240 "inweb/Chapter 5/Weave Tree.w"
#line 246 "inweb/Chapter 5/Weave Tree.w"
#line 251 "inweb/Chapter 5/Weave Tree.w"
#line 253 "inweb/Chapter 5/Weave Tree.w"
tree_type *weave_tree_type = NULL;
tree_node_type *weave_document_node_type = NULL;
tree_node_type *weave_head_node_type = NULL;
tree_node_type *weave_body_node_type = NULL;
tree_node_type *weave_tail_node_type = NULL;
tree_node_type *weave_chapter_header_node_type = NULL;
tree_node_type *weave_chapter_footer_node_type = NULL;
tree_node_type *weave_section_header_node_type = NULL;
tree_node_type *weave_section_footer_node_type = NULL;
tree_node_type *weave_section_purpose_node_type = NULL;
tree_node_type *weave_verbatim_node_type = NULL;
tree_node_type *weave_subheading_node_type = NULL;
tree_node_type *weave_bar_node_type = NULL;
tree_node_type *weave_pagebreak_node_type = NULL;
tree_node_type *weave_linebreak_node_type = NULL;
tree_node_type *weave_paragraph_heading_node_type = NULL;
tree_node_type *weave_endnote_node_type = NULL;
tree_node_type *weave_figure_node_type = NULL;
tree_node_type *weave_extract_node_type = NULL;
tree_node_type *weave_audio_node_type = NULL;
tree_node_type *weave_video_node_type = NULL;
tree_node_type *weave_download_node_type = NULL;
tree_node_type *weave_material_node_type = NULL;
tree_node_type *weave_embed_node_type = NULL;
tree_node_type *weave_pmac_node_type = NULL;
tree_node_type *weave_vskip_node_type = NULL;
tree_node_type *weave_chapter_node_type = NULL;
tree_node_type *weave_section_node_type = NULL;
tree_node_type *weave_code_line_node_type = NULL;
tree_node_type *weave_function_usage_node_type = NULL;
tree_node_type *weave_commentary_node_type = NULL;
tree_node_type *weave_carousel_slide_node_type = NULL;
tree_node_type *weave_toc_node_type = NULL;
tree_node_type *weave_toc_line_node_type = NULL;
tree_node_type *weave_chapter_title_page_node_type = NULL;
tree_node_type *weave_defn_node_type = NULL;
tree_node_type *weave_source_code_node_type = NULL;
tree_node_type *weave_url_node_type = NULL;
tree_node_type *weave_footnote_cue_node_type = NULL;
tree_node_type *weave_begin_footnote_text_node_type = NULL;
tree_node_type *weave_display_line_node_type = NULL;
tree_node_type *weave_function_defn_node_type = NULL;
tree_node_type *weave_item_node_type = NULL;
tree_node_type *weave_grammar_index_node_type = NULL;
tree_node_type *weave_inline_node_type = NULL;
tree_node_type *weave_locale_node_type = NULL;
tree_node_type *weave_maths_node_type = NULL;
heterogeneous_tree *WeaveTree__new_tree(weave_order *wv) {
if (weave_tree_type == NULL) {
weave_tree_type = Trees__new_type(TL_IS_452, NULL);
weave_document_node_type =
Trees__new_node_type(TL_IS_453, weave_document_node_CLASS, NULL);
weave_head_node_type =
Trees__new_node_type(TL_IS_454, weave_head_node_CLASS, NULL);
weave_body_node_type =
Trees__new_node_type(TL_IS_455, weave_body_node_CLASS, NULL);
weave_tail_node_type =
Trees__new_node_type(TL_IS_456, weave_tail_node_CLASS, NULL);
weave_chapter_footer_node_type =
Trees__new_node_type(TL_IS_457, weave_chapter_footer_node_CLASS, NULL);
weave_chapter_header_node_type =
Trees__new_node_type(TL_IS_458, weave_chapter_header_node_CLASS, NULL);
weave_section_footer_node_type =
Trees__new_node_type(TL_IS_459, weave_section_footer_node_CLASS, NULL);
weave_section_header_node_type =
Trees__new_node_type(TL_IS_460, weave_section_header_node_CLASS, NULL);
weave_section_purpose_node_type =
Trees__new_node_type(TL_IS_461, weave_section_purpose_node_CLASS, NULL);
weave_subheading_node_type =
Trees__new_node_type(TL_IS_462, weave_subheading_node_CLASS, NULL);
weave_bar_node_type =
Trees__new_node_type(TL_IS_463, weave_bar_node_CLASS, NULL);
weave_pagebreak_node_type =
Trees__new_node_type(TL_IS_464, weave_pagebreak_node_CLASS, NULL);
weave_linebreak_node_type =
Trees__new_node_type(TL_IS_465, weave_linebreak_node_CLASS, NULL);
weave_paragraph_heading_node_type =
Trees__new_node_type(TL_IS_466, weave_paragraph_heading_node_CLASS, NULL);
weave_endnote_node_type =
Trees__new_node_type(TL_IS_467, weave_endnote_node_CLASS, NULL);
weave_figure_node_type =
Trees__new_node_type(TL_IS_468, weave_figure_node_CLASS, NULL);
weave_extract_node_type =
Trees__new_node_type(TL_IS_469, weave_extract_node_CLASS, NULL);
weave_audio_node_type =
Trees__new_node_type(TL_IS_470, weave_audio_node_CLASS, NULL);
weave_video_node_type =
Trees__new_node_type(TL_IS_471, weave_video_node_CLASS, NULL);
weave_download_node_type =
Trees__new_node_type(TL_IS_472, weave_download_node_CLASS, NULL);
weave_material_node_type =
Trees__new_node_type(TL_IS_473, weave_material_node_CLASS, NULL);
weave_embed_node_type =
Trees__new_node_type(TL_IS_474, weave_embed_node_CLASS, NULL);
weave_pmac_node_type =
Trees__new_node_type(TL_IS_475, weave_pmac_node_CLASS, NULL);
weave_vskip_node_type =
Trees__new_node_type(TL_IS_476, weave_vskip_node_CLASS, NULL);
weave_chapter_node_type =
Trees__new_node_type(TL_IS_477, weave_chapter_node_CLASS, NULL);
weave_section_node_type =
Trees__new_node_type(TL_IS_478, weave_section_node_CLASS, NULL);
weave_code_line_node_type =
Trees__new_node_type(TL_IS_479, weave_code_line_node_CLASS, NULL);
weave_function_usage_node_type =
Trees__new_node_type(TL_IS_480, weave_function_usage_node_CLASS, NULL);
weave_commentary_node_type =
Trees__new_node_type(TL_IS_481, weave_commentary_node_CLASS, NULL);
weave_carousel_slide_node_type =
Trees__new_node_type(TL_IS_482, weave_carousel_slide_node_CLASS, NULL);
weave_toc_node_type =
Trees__new_node_type(TL_IS_483, weave_toc_node_CLASS, NULL);
weave_toc_line_node_type =
Trees__new_node_type(TL_IS_484, weave_toc_line_node_CLASS, NULL);
weave_chapter_title_page_node_type =
Trees__new_node_type(TL_IS_485, weave_chapter_title_page_node_CLASS, NULL);
weave_defn_node_type =
Trees__new_node_type(TL_IS_486, weave_defn_node_CLASS, NULL);
weave_source_code_node_type =
Trees__new_node_type(TL_IS_487, weave_source_code_node_CLASS, NULL);
weave_url_node_type =
Trees__new_node_type(TL_IS_488, weave_url_node_CLASS, NULL);
weave_footnote_cue_node_type =
Trees__new_node_type(TL_IS_489, weave_footnote_cue_node_CLASS, NULL);
weave_begin_footnote_text_node_type =
Trees__new_node_type(TL_IS_490, weave_begin_footnote_text_node_CLASS, NULL);
weave_display_line_node_type =
Trees__new_node_type(TL_IS_491, weave_display_line_node_CLASS, NULL);
weave_function_defn_node_type =
Trees__new_node_type(TL_IS_492, weave_function_defn_node_CLASS, NULL);
weave_item_node_type =
Trees__new_node_type(TL_IS_493, weave_item_node_CLASS, NULL);
weave_grammar_index_node_type =
Trees__new_node_type(TL_IS_494, weave_grammar_index_node_CLASS, NULL);
weave_inline_node_type =
Trees__new_node_type(TL_IS_495, weave_inline_node_CLASS, NULL);
weave_locale_node_type =
Trees__new_node_type(TL_IS_496, weave_locale_node_CLASS, NULL);
weave_maths_node_type =
Trees__new_node_type(TL_IS_497, weave_maths_node_CLASS, NULL);
weave_verbatim_node_type =
Trees__new_node_type(TL_IS_498, weave_verbatim_node_CLASS, NULL);
}
heterogeneous_tree *tree = Trees__new(weave_tree_type);
Trees__make_root(tree, WeaveTree__document(tree, wv));
return tree;
}
tree_node *WeaveTree__document(heterogeneous_tree *tree, weave_order *wv) {
weave_document_node *doc = CREATE(weave_document_node);
doc->wv = wv;
return Trees__new_node(tree, weave_document_node_type,
STORE_POINTER_weave_document_node(doc));
}
tree_node *WeaveTree__head(heterogeneous_tree *tree, text_stream *banner) {
weave_head_node *head = CREATE(weave_head_node);
head->banner = Str__duplicate(banner);
return Trees__new_node(tree, weave_head_node_type,
STORE_POINTER_weave_head_node(head));
}
tree_node *WeaveTree__body(heterogeneous_tree *tree) {
weave_body_node *body = CREATE(weave_body_node);
return Trees__new_node(tree, weave_body_node_type,
STORE_POINTER_weave_body_node(body));
}
tree_node *WeaveTree__tail(heterogeneous_tree *tree, text_stream *rennab) {
weave_tail_node *tail = CREATE(weave_tail_node);
tail->rennab = Str__duplicate(rennab);
return Trees__new_node(tree, weave_tail_node_type,
STORE_POINTER_weave_tail_node(tail));
}
tree_node *WeaveTree__verbatim(heterogeneous_tree *tree, text_stream *content) {
weave_verbatim_node *C = CREATE(weave_verbatim_node);
C->content = Str__duplicate(content);
return Trees__new_node(tree, weave_verbatim_node_type,
STORE_POINTER_weave_verbatim_node(C));
}
tree_node *WeaveTree__section_header(heterogeneous_tree *tree, section *S) {
weave_section_header_node *C = CREATE(weave_section_header_node);
C->sect = S;
return Trees__new_node(tree, weave_section_header_node_type,
STORE_POINTER_weave_section_header_node(C));
}
tree_node *WeaveTree__section_footer(heterogeneous_tree *tree, section *S) {
weave_section_footer_node *C = CREATE(weave_section_footer_node);
C->sect = S;
return Trees__new_node(tree, weave_section_footer_node_type,
STORE_POINTER_weave_section_footer_node(C));
}
tree_node *WeaveTree__chapter(heterogeneous_tree *tree, chapter *Ch) {
weave_chapter_node *C = CREATE(weave_chapter_node);
C->chap = Ch;
return Trees__new_node(tree, weave_chapter_node_type, STORE_POINTER_weave_chapter_node(C));
}
tree_node *WeaveTree__chapter_header(heterogeneous_tree *tree, chapter *Ch) {
weave_chapter_header_node *C = CREATE(weave_chapter_header_node);
C->chap = Ch;
return Trees__new_node(tree, weave_chapter_header_node_type,
STORE_POINTER_weave_chapter_header_node(C));
}
tree_node *WeaveTree__chapter_footer(heterogeneous_tree *tree, chapter *Ch) {
weave_chapter_footer_node *C = CREATE(weave_chapter_footer_node);
C->chap = Ch;
return Trees__new_node(tree, weave_chapter_footer_node_type,
STORE_POINTER_weave_chapter_footer_node(C));
}
tree_node *WeaveTree__purpose(heterogeneous_tree *tree, text_stream *P) {
weave_section_purpose_node *C = CREATE(weave_section_purpose_node);
C->purpose = Str__duplicate(P);
return Trees__new_node(tree, weave_section_purpose_node_type,
STORE_POINTER_weave_section_purpose_node(C));
}
tree_node *WeaveTree__subheading(heterogeneous_tree *tree, text_stream *P) {
weave_subheading_node *C = CREATE(weave_subheading_node);
C->text = Str__duplicate(P);
return Trees__new_node(tree, weave_subheading_node_type,
STORE_POINTER_weave_subheading_node(C));
}
tree_node *WeaveTree__pagebreak(heterogeneous_tree *tree) {
weave_pagebreak_node *C = CREATE(weave_pagebreak_node);
return Trees__new_node(tree, weave_pagebreak_node_type,
STORE_POINTER_weave_pagebreak_node(C));
}
tree_node *WeaveTree__linebreak(heterogeneous_tree *tree) {
weave_linebreak_node *C = CREATE(weave_linebreak_node);
return Trees__new_node(tree, weave_linebreak_node_type,
STORE_POINTER_weave_linebreak_node(C));
}
tree_node *WeaveTree__bar(heterogeneous_tree *tree) {
weave_bar_node *C = CREATE(weave_bar_node);
return Trees__new_node(tree, weave_bar_node_type,
STORE_POINTER_weave_bar_node(C));
}
tree_node *WeaveTree__paragraph_heading(heterogeneous_tree *tree, paragraph *P, int no_skip) {
weave_paragraph_heading_node *C = CREATE(weave_paragraph_heading_node);
C->para = P;
C->no_skip = no_skip;
return Trees__new_node(tree, weave_paragraph_heading_node_type,
STORE_POINTER_weave_paragraph_heading_node(C));
}
tree_node *WeaveTree__endnote(heterogeneous_tree *tree) {
weave_endnote_node *C = CREATE(weave_endnote_node);
return Trees__new_node(tree, weave_endnote_node_type,
STORE_POINTER_weave_endnote_node(C));
}
tree_node *WeaveTree__figure(heterogeneous_tree *tree,
text_stream *figname, int w, int h) {
weave_figure_node *C = CREATE(weave_figure_node);
C->figname = Str__duplicate(figname);
C->w = w;
C->h = h;
return Trees__new_node(tree, weave_figure_node_type,
STORE_POINTER_weave_figure_node(C));
}
tree_node *WeaveTree__raw_extract(heterogeneous_tree *tree,
text_stream *extract) {
weave_extract_node *C = CREATE(weave_extract_node);
C->extract = Str__duplicate(extract);
return Trees__new_node(tree, weave_extract_node_type,
STORE_POINTER_weave_extract_node(C));
}
tree_node *WeaveTree__audio(heterogeneous_tree *tree,
text_stream *audio_name, int w) {
weave_audio_node *C = CREATE(weave_audio_node);
C->audio_name = Str__duplicate(audio_name);
C->w = w;
return Trees__new_node(tree, weave_audio_node_type,
STORE_POINTER_weave_audio_node(C));
}
tree_node *WeaveTree__video(heterogeneous_tree *tree,
text_stream *video_name, int w, int h) {
weave_video_node *C = CREATE(weave_video_node);
C->video_name = Str__duplicate(video_name);
C->w = w;
return Trees__new_node(tree, weave_video_node_type,
STORE_POINTER_weave_video_node(C));
}
tree_node *WeaveTree__download(heterogeneous_tree *tree,
text_stream *download_name, text_stream *filetype) {
weave_download_node *C = CREATE(weave_download_node);
C->download_name = Str__duplicate(download_name);
C->filetype = Str__duplicate(filetype);
return Trees__new_node(tree, weave_download_node_type,
STORE_POINTER_weave_download_node(C));
}
tree_node *WeaveTree__material(heterogeneous_tree *tree, int material_type, int plainly,
programming_language *styling, text_stream *endnote) {
weave_material_node *C = CREATE(weave_material_node);
C->material_type = material_type;
C->plainly = plainly;
C->styling = styling;
C->endnote = Str__duplicate(endnote);
return Trees__new_node(tree, weave_material_node_type, STORE_POINTER_weave_material_node(C));
}
tree_node *WeaveTree__embed(heterogeneous_tree *tree,
text_stream *service, text_stream *ID, int w, int h) {
weave_embed_node *C = CREATE(weave_embed_node);
C->service = Str__duplicate(service);
C->ID = Str__duplicate(ID);
C->w = w;
C->h = h;
return Trees__new_node(tree, weave_embed_node_type, STORE_POINTER_weave_embed_node(C));
}
#line 588 "inweb/Chapter 5/Weave Tree.w"
tree_node *WeaveTree__pmac(heterogeneous_tree *tree, para_macro *pmac, int defn) {
weave_pmac_node *C = CREATE(weave_pmac_node);
C->pmac = pmac;
C->defn = defn;
return Trees__new_node(tree, weave_pmac_node_type, STORE_POINTER_weave_pmac_node(C));
}
#line 600 "inweb/Chapter 5/Weave Tree.w"
tree_node *WeaveTree__vskip(heterogeneous_tree *tree, int in_comment) {
weave_vskip_node *C = CREATE(weave_vskip_node);
C->in_comment = in_comment;
return Trees__new_node(tree, weave_vskip_node_type, STORE_POINTER_weave_vskip_node(C));
}
tree_node *WeaveTree__section(heterogeneous_tree *tree, section *sect) {
weave_section_node *C = CREATE(weave_section_node);
C->sect = sect;
return Trees__new_node(tree, weave_section_node_type, STORE_POINTER_weave_section_node(C));
}
tree_node *WeaveTree__code_line(heterogeneous_tree *tree) {
weave_code_line_node *C = CREATE(weave_code_line_node);
return Trees__new_node(tree, weave_code_line_node_type, STORE_POINTER_weave_code_line_node(C));
}
tree_node *WeaveTree__function_usage(heterogeneous_tree *tree,
text_stream *url, language_function *fn) {
weave_function_usage_node *C = CREATE(weave_function_usage_node);
C->url = Str__duplicate(url);
C->fn = fn;
return Trees__new_node(tree, weave_function_usage_node_type, STORE_POINTER_weave_function_usage_node(C));
}
tree_node *WeaveTree__commentary(heterogeneous_tree *tree, text_stream *text, int in_code) {
weave_commentary_node *C = CREATE(weave_commentary_node);
C->text = Str__duplicate(text);
C->in_code = in_code;
return Trees__new_node(tree, weave_commentary_node_type, STORE_POINTER_weave_commentary_node(C));
}
tree_node *WeaveTree__carousel_slide(heterogeneous_tree *tree, text_stream *caption, int c) {
weave_carousel_slide_node *C = CREATE(weave_carousel_slide_node);
C->caption = Str__duplicate(caption);
C->caption_command = c;
return Trees__new_node(tree, weave_carousel_slide_node_type, STORE_POINTER_weave_carousel_slide_node(C));
}
tree_node *WeaveTree__table_of_contents(heterogeneous_tree *tree, text_stream *text1) {
weave_toc_node *C = CREATE(weave_toc_node);
C->text1 = Str__duplicate(text1);
return Trees__new_node(tree, weave_toc_node_type, STORE_POINTER_weave_toc_node(C));
}
tree_node *WeaveTree__contents_line(heterogeneous_tree *tree,
text_stream *text1, text_stream *text2, paragraph *P) {
weave_toc_line_node *C = CREATE(weave_toc_line_node);
C->text1 = Str__duplicate(text1);
C->text2 = Str__duplicate(text2);
C->para = P;
return Trees__new_node(tree, weave_toc_line_node_type, STORE_POINTER_weave_toc_line_node(C));
}
tree_node *WeaveTree__weave_chapter_title_page_node(heterogeneous_tree *tree) {
weave_chapter_title_page_node *C = CREATE(weave_chapter_title_page_node);
return Trees__new_node(tree, weave_chapter_title_page_node_type, STORE_POINTER_weave_chapter_title_page_node(C));
}
tree_node *WeaveTree__weave_defn_node(heterogeneous_tree *tree, text_stream *keyword) {
weave_defn_node *C = CREATE(weave_defn_node);
C->keyword = Str__duplicate(keyword);
return Trees__new_node(tree, weave_defn_node_type, STORE_POINTER_weave_defn_node(C));
}
#line 676 "inweb/Chapter 5/Weave Tree.w"
tree_node *WeaveTree__source_code(heterogeneous_tree *tree,
text_stream *matter, text_stream *colouring) {
if (Str__len(colouring) != Str__len(matter)) internal_error("bad source segment");
for (int i=0; i<Str__len(matter); i++) {
wchar_t c = Str__get_at(matter, i);
if (c == '\t') {
Str__put_at(matter, i, ' ');
int extra_spaces =
SPACES_PER_TAB_IN_WOVEN_CODE - 1 - (i % SPACES_PER_TAB_IN_WOVEN_CODE);
if (extra_spaces > 0) {
for (int j=0; j<extra_spaces; j++) {
PUT_TO(matter, ' '); PUT_TO(colouring, PLAIN_COLOUR);
}
for (int j=Str__len(matter)-1; j >= i+extra_spaces; j--) {
Str__put_at(matter, j, Str__get_at(matter, j-extra_spaces));
Str__put_at(colouring, j, Str__get_at(colouring, j-extra_spaces));
}
for (int j=0; j<extra_spaces; j++) {
Str__put_at(matter, i+1+j, ' ');
Str__put_at(colouring, i+1+j, PLAIN_COLOUR);
}
}
}
}
weave_source_code_node *C = CREATE(weave_source_code_node);
C->matter = Str__duplicate(matter);
C->colouring = Str__duplicate(colouring);
return Trees__new_node(tree, weave_source_code_node_type, STORE_POINTER_weave_source_code_node(C));
}
tree_node *WeaveTree__url(heterogeneous_tree *tree, text_stream *url,
text_stream *content, int external) {
weave_url_node *C = CREATE(weave_url_node);
C->url = Str__duplicate(url);
C->content = Str__duplicate(content);
C->external = external;
return Trees__new_node(tree, weave_url_node_type, STORE_POINTER_weave_url_node(C));
}
tree_node *WeaveTree__footnote_cue(heterogeneous_tree *tree, text_stream *cue) {
weave_footnote_cue_node *C = CREATE(weave_footnote_cue_node);
C->cue_text = Str__duplicate(cue);
return Trees__new_node(tree, weave_footnote_cue_node_type, STORE_POINTER_weave_footnote_cue_node(C));
}
tree_node *WeaveTree__footnote(heterogeneous_tree *tree, text_stream *cue) {
weave_begin_footnote_text_node *C = CREATE(weave_begin_footnote_text_node);
C->cue_text = Str__duplicate(cue);
return Trees__new_node(tree, weave_begin_footnote_text_node_type, STORE_POINTER_weave_begin_footnote_text_node(C));
}
#line 733 "inweb/Chapter 5/Weave Tree.w"
tree_node *WeaveTree__function_defn(heterogeneous_tree *tree, language_function *fn) {
weave_function_defn_node *C = CREATE(weave_function_defn_node);
C->fn = fn;
return Trees__new_node(tree, weave_function_defn_node_type, STORE_POINTER_weave_function_defn_node(C));
}
#line 743 "inweb/Chapter 5/Weave Tree.w"
tree_node *WeaveTree__display_line(heterogeneous_tree *tree, text_stream *text) {
weave_display_line_node *C = CREATE(weave_display_line_node);
C->text = Str__duplicate(text);
return Trees__new_node(tree, weave_display_line_node_type, STORE_POINTER_weave_display_line_node(C));
}
#line 762 "inweb/Chapter 5/Weave Tree.w"
tree_node *WeaveTree__weave_item_node(heterogeneous_tree *tree, int depth, text_stream *label) {
weave_item_node *C = CREATE(weave_item_node);
C->depth = depth;
C->label = Str__duplicate(label);
return Trees__new_node(tree, weave_item_node_type, STORE_POINTER_weave_item_node(C));
}
tree_node *WeaveTree__grammar_index(heterogeneous_tree *tree) {
weave_grammar_index_node *C = CREATE(weave_grammar_index_node);
return Trees__new_node(tree, weave_grammar_index_node_type, STORE_POINTER_weave_grammar_index_node(C));
}
tree_node *WeaveTree__inline(heterogeneous_tree *tree) {
weave_inline_node *C = CREATE(weave_inline_node);
return Trees__new_node(tree, weave_inline_node_type, STORE_POINTER_weave_inline_node(C));
}
tree_node *WeaveTree__locale(heterogeneous_tree *tree, paragraph *par1, paragraph *par2) {
weave_locale_node *C = CREATE(weave_locale_node);
C->par1 = par1;
C->par2 = par2;
return Trees__new_node(tree, weave_locale_node_type, STORE_POINTER_weave_locale_node(C));
}
tree_node *WeaveTree__mathematics(heterogeneous_tree *tree, text_stream *content, int displayed) {
weave_maths_node *C = CREATE(weave_maths_node);
C->content = Str__duplicate(content);
C->displayed = displayed;
return Trees__new_node(tree, weave_maths_node_type, STORE_POINTER_weave_maths_node(C));
}
void WeaveTree__show(text_stream *OUT, heterogeneous_tree *T) {
WRITE("%S\n", T->type->name);
INDENT;
Debugging__render(NULL, OUT, T);
OUTDENT;
}
void WeaveTree__prune(heterogeneous_tree *T) {
Trees__prune_tree(T, &WeaveTree__prune_visit, NULL);
}
int WeaveTree__prune_visit(tree_node *N, void *state) {
if ((N->type->required_CLASS == weave_material_node_CLASS) && (N->child == NULL))
return TRUE;
if ((N->type->required_CLASS == weave_vskip_node_CLASS) && (N->next == NULL))
return TRUE;
if ((N->type->required_CLASS == weave_vskip_node_CLASS) &&
(N->next->type->required_CLASS == weave_item_node_CLASS))
return TRUE;
return FALSE;
}
#line 17 "inweb/Chapter 5/Format Methods.w"
weave_format *Formats__create_weave_format(text_stream *name, text_stream *ext) {
weave_format *wf = CREATE(weave_format);
wf->format_name = Str__duplicate(name);
wf->woven_extension = Str__duplicate(ext);
wf->methods = Methods__new_set();
return wf;
}
weave_format *Formats__find_by_name(text_stream *name) {
weave_format *wf;
LOOP_OVER(wf, weave_format)
if (Str__eq_insensitive(name, wf->format_name))
return wf;
return NULL;
}
#line 40 "inweb/Chapter 5/Format Methods.w"
text_stream *Formats__file_extension(weave_format *wf) {
return wf->woven_extension;
}
#line 48 "inweb/Chapter 5/Format Methods.w"
void Formats__create_weave_formats(void) {
Debugging__create();
TeX__create();
PlainText__create();
HTMLFormat__create();
}
#line 68 "inweb/Chapter 5/Format Methods.w"
#line 70 "inweb/Chapter 5/Format Methods.w"
INT_METHOD_TYPE(BEGIN_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern)
VOID_METHOD_TYPE(END_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern)
int Formats__begin_weaving(web *W, weave_pattern *pattern) {
int rv = FALSE;
INT_METHOD_CALL(rv, pattern->pattern_format, BEGIN_WEAVING_FOR_MTID, W, pattern);
if (rv) return rv;
return SWARM_OFF_SWM;
}
void Formats__end_weaving(web *W, weave_pattern *pattern) {
VOID_METHOD_CALL(pattern->pattern_format, END_WEAVING_FOR_MTID, W, pattern);
}
#line 92 "inweb/Chapter 5/Format Methods.w"
#line 94 "inweb/Chapter 5/Format Methods.w"
VOID_METHOD_TYPE(RENDER_FOR_MTID, weave_format *wf, text_stream *OUT, heterogeneous_tree *tree)
void Formats__render(text_stream *OUT, heterogeneous_tree *tree, filename *into) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
weave_format *wf = C->wv->format;
TEMPORARY_TEXT(template)
WRITE_TO(template, "template-body%S", wf->woven_extension);
filename *F = Patterns__find_template(C->wv->pattern, template);
TEMPORARY_TEXT(interior)
VOID_METHOD_CALL(wf, RENDER_FOR_MTID, interior, tree);
Bibliographic__set_datum(C->wv->weave_web->md, TL_IS_499, interior);
if (F) Collater__for_order(OUT, C->wv, F, into);
else WRITE("%S", interior);
DISCARD_TEXT(interior)
DISCARD_TEXT(template)
}
#line 115 "inweb/Chapter 5/Format Methods.w"
#line 117 "inweb/Chapter 5/Format Methods.w"
INT_METHOD_TYPE(PREFORM_DOCUMENT_FOR_MTID, weave_format *wf, text_stream *OUT,
weave_order *wv, web *W, chapter *C, section *S, source_line *L,
text_stream *matter, text_stream *concluding_comment)
int Formats__preform_document(OUTPUT_STREAM, weave_order *wv, web *W,
chapter *C, section *S, source_line *L, text_stream *matter,
text_stream *concluding_comment) {
weave_format *wf = wv->format;
int rv = FALSE;
INT_METHOD_CALL(rv, wf, PREFORM_DOCUMENT_FOR_MTID, OUT, wv, W, C, S, L, matter,
concluding_comment);
return rv;
}
#line 136 "inweb/Chapter 5/Format Methods.w"
#line 138 "inweb/Chapter 5/Format Methods.w"
VOID_METHOD_TYPE(POST_PROCESS_POS_MTID, weave_format *wf, weave_order *wv, int open_afterwards)
void Formats__post_process_weave(weave_order *wv, int open_afterwards) {
VOID_METHOD_CALL(wv->format, POST_PROCESS_POS_MTID, wv, open_afterwards);
}
#line 148 "inweb/Chapter 5/Format Methods.w"
#line 150 "inweb/Chapter 5/Format Methods.w"
VOID_METHOD_TYPE(POST_PROCESS_REPORT_POS_MTID, weave_format *wf, weave_order *wv)
void Formats__report_on_post_processing(weave_order *wv) {
TeXUtilities__report_on_post_processing(wv);
VOID_METHOD_CALL(wv->format, POST_PROCESS_REPORT_POS_MTID, wv);
}
#line 160 "inweb/Chapter 5/Format Methods.w"
#line 162 "inweb/Chapter 5/Format Methods.w"
INT_METHOD_TYPE(POST_PROCESS_SUBSTITUTE_POS_MTID, weave_format *wf, text_stream *OUT,
weave_order *wv, text_stream *detail, weave_pattern *pattern)
int Formats__substitute_post_processing_data(OUTPUT_STREAM, weave_order *wv,
text_stream *detail, weave_pattern *pattern) {
int rv = TeXUtilities__substitute_post_processing_data(OUT, wv, detail);
INT_METHOD_CALL(rv, wv->format, POST_PROCESS_SUBSTITUTE_POS_MTID, OUT, wv, detail, pattern);
return rv;
}
#line 9 "inweb/Chapter 5/Plain Text Format.w"
void PlainText__create(void) {
weave_format *wf = Formats__create_weave_format(TL_IS_500, TL_IS_501);
METHOD_ADD(wf, RENDER_FOR_MTID, PlainText__render);
}
#line 22 "inweb/Chapter 5/Plain Text Format.w"
void PlainText__render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) {
PlainText_render_state prs;
prs.OUT = OUT;
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
prs.wv = C->wv;
Trees__traverse_from(tree->root, &PlainText__render_visit, (void *) &prs, 0);
}
int PlainText__render_visit(tree_node *N, void *state, int L) {
PlainText_render_state *prs = (PlainText_render_state *) state;
text_stream *OUT = prs->OUT;
if ((N->type == weave_document_node_type) ||
(N->type == weave_head_node_type) ||
(N->type == weave_body_node_type) ||
(N->type == weave_tail_node_type) ||
(N->type == weave_chapter_title_page_node_type) ||
(N->type == weave_chapter_footer_node_type) ||
(N->type == weave_figure_node_type) ||
(N->type == weave_audio_node_type) ||
(N->type == weave_video_node_type) ||
(N->type == weave_download_node_type) ||
(N->type == weave_material_node_type) ||
(N->type == weave_chapter_node_type) ||
(N->type == weave_carousel_slide_node_type) ||
(N->type == weave_toc_node_type) ||
(N->type == weave_toc_line_node_type) ||
(N->type == weave_grammar_index_node_type) ||
(N->type == weave_inline_node_type))
{
#line 135 "inweb/Chapter 5/Plain Text Format.w"
;
}
#line 50 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_verbatim_node_type)
{
#line 131 "inweb/Chapter 5/Plain Text Format.w"
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
WRITE("%S", C->content);
}
#line 52 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_chapter_header_node_type)
{
#line 86 "inweb/Chapter 5/Plain Text Format.w"
weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content);
WRITE("%S\n\n", C->chap->md->ch_title);
section *S;
LOOP_OVER_LINKED_LIST(S, section, C->chap->sections)
WRITE(" %S\n %S\n",
S->md->sect_title, S->sect_purpose);
WRITE("\n");
}
#line 53 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_section_header_node_type)
{
#line 95 "inweb/Chapter 5/Plain Text Format.w"
weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content);
WRITE("%S\n\n", C->sect->md->sect_title);
}
#line 54 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_section_footer_node_type)
{
#line 99 "inweb/Chapter 5/Plain Text Format.w"
WRITE("\n\n");
}
#line 55 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_section_purpose_node_type)
{
#line 102 "inweb/Chapter 5/Plain Text Format.w"
weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content);
WRITE("%S\n\n", C->purpose);
}
#line 56 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_subheading_node_type)
{
#line 106 "inweb/Chapter 5/Plain Text Format.w"
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
WRITE("%S\n\n", C->text);
}
#line 57 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_bar_node_type)
{
#line 110 "inweb/Chapter 5/Plain Text Format.w"
WRITE("\n----------------------------------------------------------------------\n\n");
}
#line 58 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_pagebreak_node_type)
{
#line 113 "inweb/Chapter 5/Plain Text Format.w"
;
}
#line 59 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_linebreak_node_type)
{
#line 116 "inweb/Chapter 5/Plain Text Format.w"
WRITE("\n");
}
#line 60 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_paragraph_heading_node_type)
{
#line 119 "inweb/Chapter 5/Plain Text Format.w"
weave_paragraph_heading_node *C = RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
WRITE("\n");
WRITE("%S%S", C->para->ornament, C->para->paragraph_number);
if (Str__len(C->para->heading_text) > 0) WRITE(" %S", C->para->heading_text);
WRITE(". ");
}
#line 61 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_endnote_node_type)
{
#line 126 "inweb/Chapter 5/Plain Text Format.w"
{
#line 216 "inweb/Chapter 5/Plain Text Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &PlainText__render_visit, (void *) prs, L+1);
}
#line 126 "inweb/Chapter 5/Plain Text Format.w"
;
WRITE("\n");
return FALSE;
}
#line 62 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_embed_node_type)
{
#line 138 "inweb/Chapter 5/Plain Text Format.w"
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
WRITE("[See %S video with ID %S.]\n", C->service, C->ID);
}
#line 63 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_pmac_node_type)
{
#line 142 "inweb/Chapter 5/Plain Text Format.w"
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
WRITE("<%S (%S)>%s",
C->pmac->macro_name, C->pmac->defining_paragraph->paragraph_number,
(C->defn)?" =":"");
}
#line 64 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_vskip_node_type)
{
#line 148 "inweb/Chapter 5/Plain Text Format.w"
WRITE("\n");
}
#line 65 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_section_node_type)
{
#line 151 "inweb/Chapter 5/Plain Text Format.w"
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
LOG("It was %d\n", C->allocation_id);
}
#line 66 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_code_line_node_type)
{
#line 155 "inweb/Chapter 5/Plain Text Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &PlainText__render_visit, (void *) prs, L+1);
WRITE("\n");
return FALSE;
}
#line 67 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_function_usage_node_type)
{
#line 161 "inweb/Chapter 5/Plain Text Format.w"
weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content);
WRITE("%S", C->fn->function_name);
return FALSE;
}
#line 68 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_commentary_node_type)
{
#line 166 "inweb/Chapter 5/Plain Text Format.w"
weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content);
if (C->in_code) WRITE(" /* ");
WRITE("%S", C->text);
if (C->in_code) WRITE(" */ ");
}
#line 69 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_defn_node_type)
{
#line 172 "inweb/Chapter 5/Plain Text Format.w"
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
WRITE("%S ", C->keyword);
}
#line 70 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_source_code_node_type)
{
#line 176 "inweb/Chapter 5/Plain Text Format.w"
weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content);
WRITE("%S", C->matter);
}
#line 71 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_url_node_type)
{
#line 180 "inweb/Chapter 5/Plain Text Format.w"
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
WRITE("%S", C->url);
}
#line 72 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_footnote_cue_node_type)
{
#line 184 "inweb/Chapter 5/Plain Text Format.w"
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
WRITE("[%S]", C->cue_text);
}
#line 73 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_begin_footnote_text_node_type)
{
#line 188 "inweb/Chapter 5/Plain Text Format.w"
WRITE("\n");
}
#line 74 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_display_line_node_type)
{
#line 191 "inweb/Chapter 5/Plain Text Format.w"
weave_display_line_node *C = RETRIEVE_POINTER_weave_display_line_node(N->content);
WRITE(" %S\n", C->text);
}
#line 75 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_function_defn_node_type)
{
#line 195 "inweb/Chapter 5/Plain Text Format.w"
weave_function_defn_node *C = RETRIEVE_POINTER_weave_function_defn_node(N->content);
WRITE("%S", C->fn->function_name);
return TRUE;
}
#line 76 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_item_node_type)
{
#line 200 "inweb/Chapter 5/Plain Text Format.w"
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
for (int i=1; i<C->depth; i++) WRITE(" ");
WRITE("(%S) ", C->label);
}
#line 77 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_locale_node_type)
{
#line 205 "inweb/Chapter 5/Plain Text Format.w"
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
WRITE("%S%S", C->par1->ornament, C->par1->paragraph_number);
if (C->par2) WRITE("-%S", C->par2->paragraph_number);
}
#line 78 "inweb/Chapter 5/Plain Text Format.w"
else if (N->type == weave_maths_node_type)
{
#line 210 "inweb/Chapter 5/Plain Text Format.w"
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
if (C->displayed) WRITE("\n");
WRITE("%S", C->content);
if (C->displayed) WRITE("\n\n");
}
#line 79 "inweb/Chapter 5/Plain Text Format.w"
else internal_error("unable to render unknown node");
return TRUE;
}
#line 9 "inweb/Chapter 5/TeX Format.w"
void TeX__create(void) {
weave_format *wf = Formats__create_weave_format(TL_IS_502, TL_IS_503);
METHOD_ADD(wf, RENDER_FOR_MTID, TeX__render_TeX);
METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX__preform_document);
}
#line 23 "inweb/Chapter 5/TeX Format.w"
#line 25 "inweb/Chapter 5/TeX Format.w"
void TeX__render_TeX(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) {
TeX__render_inner(OUT, tree, PDFTEX_TEX_FORM);
}
#line 38 "inweb/Chapter 5/TeX Format.w"
void TeX__render_inner(text_stream *OUT, heterogeneous_tree *tree, int form) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
TeX_render_state trs;
trs.OUT = OUT;
trs.wv = C->wv;
trs.TeX_form = form;
Trees__traverse_from(tree->root, &TeX__render_visit, (void *) &trs, 0);
}
#line 51 "inweb/Chapter 5/TeX Format.w"
int TeX__render_visit(tree_node *N, void *state, int L) {
TeX_render_state *trs = (TeX_render_state *) state;
text_stream *OUT = trs->OUT;
if ((N->type == weave_document_node_type) ||
(N->type == weave_body_node_type) ||
(N->type == weave_chapter_title_page_node_type) ||
(N->type == weave_chapter_footer_node_type) ||
(N->type == weave_section_footer_node_type) ||
(N->type == weave_audio_node_type) ||
(N->type == weave_video_node_type) ||
(N->type == weave_download_node_type) ||
(N->type == weave_chapter_node_type) ||
(N->type == weave_carousel_slide_node_type) ||
(N->type == weave_begin_footnote_text_node_type))
{
#line 236 "inweb/Chapter 5/TeX Format.w"
;
}
#line 64 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_head_node_type)
{
#line 106 "inweb/Chapter 5/TeX Format.w"
weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content);
WRITE("%% %S\n", C->banner);
}
#line 66 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_tail_node_type)
{
#line 110 "inweb/Chapter 5/TeX Format.w"
weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content);
WRITE("%% %S\n", C->rennab);
WRITE("\\end\n");
}
#line 67 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_verbatim_node_type)
{
#line 232 "inweb/Chapter 5/TeX Format.w"
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
WRITE("%S", C->content);
}
#line 68 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_chapter_header_node_type)
{
#line 115 "inweb/Chapter 5/TeX Format.w"
weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content);
if (Str__ne(C->chap->md->ch_range, TL_IS_504)) {
TeX__general_heading(OUT, trs->wv,
FIRST_IN_LINKED_LIST(section, C->chap->sections), NULL, C->chap->md->ch_title,
3, FALSE);
WRITE("%S\\medskip\n", C->chap->md->rubric);
section *S;
LOOP_OVER_LINKED_LIST(S, section, C->chap->sections) {
WRITE("\\smallskip\\noindent ");
if (trs->wv->pattern->number_sections) WRITE("%d. ", S->printed_number);
WRITE("{\\it %S}\\qquad\n%S", S->md->sect_title, S->sect_purpose);
}
}
}
#line 69 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_section_header_node_type)
{
#line 130 "inweb/Chapter 5/TeX Format.w"
weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content);
TeX__general_heading(OUT, trs->wv, C->sect, NULL,
C->sect->md->sect_title, 2, FALSE);
}
#line 70 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_section_purpose_node_type)
{
#line 135 "inweb/Chapter 5/TeX Format.w"
weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content);
WRITE("\\smallskip\\par\\noindent{\\it %S}\\smallskip\\noindent\n", C->purpose);
}
#line 71 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_subheading_node_type)
{
#line 139 "inweb/Chapter 5/TeX Format.w"
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
WRITE("\\par\\noindent{\\bf %S}\\mark{%S}\\medskip\n", C->text, NULL);
}
#line 72 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_bar_node_type)
{
#line 143 "inweb/Chapter 5/TeX Format.w"
WRITE("\\par\\medskip\\noindent\\hrule\\medskip\\noindent\n");
}
#line 73 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_pagebreak_node_type)
{
#line 146 "inweb/Chapter 5/TeX Format.w"
WRITE("\\vfill\\eject\n");
}
#line 74 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_linebreak_node_type)
{
#line 149 "inweb/Chapter 5/TeX Format.w"
WRITE("\n");
}
#line 75 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_paragraph_heading_node_type)
{
#line 152 "inweb/Chapter 5/TeX Format.w"
weave_paragraph_heading_node *C =
RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
TeX__general_heading(OUT, trs->wv, C->para->under_section,
C->para, TL_IS_505, 0, FALSE);
}
#line 76 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_endnote_node_type)
{
#line 158 "inweb/Chapter 5/TeX Format.w"
WRITE("\\par\\noindent\\penalty10000\n");
WRITE("{\\usagefont ");
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 160 "inweb/Chapter 5/TeX Format.w"
;
WRITE("}\\smallskip\n");
return FALSE;
}
#line 77 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_figure_node_type)
{
#line 172 "inweb/Chapter 5/TeX Format.w"
weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content);
filename *F = Filenames__in(
Pathnames__down(trs->wv->weave_web->md->path_to_web, TL_IS_506),
C->figname);
WRITE("\\pdfximage");
if (C->w >= 0) WRITE(" width %d cm{%f}\n", C->w/POINTS_PER_CM, F);
else if (C->h >= 0) WRITE(" height %d cm{%f}\n", C->h/POINTS_PER_CM, F);
else WRITE("{%f}\n", F);
WRITE("\\smallskip\\noindent"
"\\hbox to\\hsize{\\hfill\\pdfrefximage \\pdflastximage\\hfill}"
"\\smallskip\n");
}
#line 78 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_material_node_type)
{
#line 185 "inweb/Chapter 5/TeX Format.w"
weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content);
paragraph *first_in_para = NULL;
if ((N == N->parent->child) &&
(N->parent->type == weave_paragraph_heading_node_type)) {
weave_paragraph_heading_node *PC =
RETRIEVE_POINTER_weave_paragraph_heading_node(N->parent->content);
first_in_para = PC->para;
}
if (C->material_type == COMMENTARY_MATERIAL)
{
#line 208 "inweb/Chapter 5/TeX Format.w"
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 208 "inweb/Chapter 5/TeX Format.w"
;
WRITE("\n");
}
#line 194 "inweb/Chapter 5/TeX Format.w"
else if (C->material_type == CODE_MATERIAL)
{
#line 212 "inweb/Chapter 5/TeX Format.w"
WRITE("\\beginlines\n");
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 213 "inweb/Chapter 5/TeX Format.w"
;
WRITE("\\endlines\n");
}
#line 196 "inweb/Chapter 5/TeX Format.w"
else if (C->material_type == FOOTNOTES_MATERIAL)
{
#line 217 "inweb/Chapter 5/TeX Format.w"
return FALSE;
}
#line 198 "inweb/Chapter 5/TeX Format.w"
else if (C->material_type == ENDNOTES_MATERIAL)
{
#line 220 "inweb/Chapter 5/TeX Format.w"
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 220 "inweb/Chapter 5/TeX Format.w"
;
}
#line 200 "inweb/Chapter 5/TeX Format.w"
else if (C->material_type == MACRO_MATERIAL)
{
#line 223 "inweb/Chapter 5/TeX Format.w"
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 223 "inweb/Chapter 5/TeX Format.w"
;
WRITE("\n");
}
#line 202 "inweb/Chapter 5/TeX Format.w"
else if (C->material_type == DEFINITION_MATERIAL)
{
#line 227 "inweb/Chapter 5/TeX Format.w"
WRITE("\\beginlines\n");
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 228 "inweb/Chapter 5/TeX Format.w"
;
WRITE("\\endlines\n");
}
#line 204 "inweb/Chapter 5/TeX Format.w"
;
return FALSE;
}
#line 79 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_embed_node_type)
{
#line 239 "inweb/Chapter 5/TeX Format.w"
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
LOG("It was %d\n", C->allocation_id);
}
#line 80 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_pmac_node_type)
{
#line 243 "inweb/Chapter 5/TeX Format.w"
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
TeX__para_macro(OUT, trs->wv, C->pmac, C->defn);
}
#line 81 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_vskip_node_type)
{
#line 247 "inweb/Chapter 5/TeX Format.w"
weave_vskip_node *C = RETRIEVE_POINTER_weave_vskip_node(N->content);
if (C->in_comment) WRITE("\\smallskip\\par\\noindent%%\n");
else WRITE("\\smallskip\n");
}
#line 82 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_section_node_type)
{
#line 252 "inweb/Chapter 5/TeX Format.w"
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
LOG("It was %d\n", C->allocation_id);
}
#line 83 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_code_line_node_type)
{
#line 256 "inweb/Chapter 5/TeX Format.w"
WRITE("\\smallskip\\par\\noindent ");
WRITE("|");
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 258 "inweb/Chapter 5/TeX Format.w"
;
WRITE("|");
WRITE("\n");
return FALSE;
}
#line 84 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_function_usage_node_type)
{
#line 264 "inweb/Chapter 5/TeX Format.w"
weave_function_usage_node *C =
RETRIEVE_POINTER_weave_function_usage_node(N->content);
WRITE("%S", C->fn->function_name);
return FALSE;
}
#line 85 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_commentary_node_type)
{
#line 270 "inweb/Chapter 5/TeX Format.w"
weave_commentary_node *C =
RETRIEVE_POINTER_weave_commentary_node(N->content);
if (C->in_code) WRITE(" |\\hfill{\\ttninepoint\\it ");
TeX__commentary_text(OUT, trs->wv, C->text);
if (C->in_code) WRITE("}|");
}
#line 86 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_toc_node_type)
{
#line 277 "inweb/Chapter 5/TeX Format.w"
WRITE("\\medskip\\hrule\\smallskip\\par\\noindent{\\usagefont ");
for (tree_node *M = N->child; M; M = M->next) {
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
if (M->next) WRITE("; ");
}
WRITE("}\\par\\medskip\\hrule\\bigskip\n");
return FALSE;
}
#line 87 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_toc_line_node_type)
{
#line 286 "inweb/Chapter 5/TeX Format.w"
weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content);
WRITE("%S~%S", C->text1, C->text2);
}
#line 88 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_defn_node_type)
{
#line 290 "inweb/Chapter 5/TeX Format.w"
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
WRITE("|{\\ninebf %S} |", C->keyword);
}
#line 89 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_source_code_node_type)
{
#line 294 "inweb/Chapter 5/TeX Format.w"
weave_source_code_node *C =
RETRIEVE_POINTER_weave_source_code_node(N->content);
int starts = FALSE;
if (N == N->parent->child) starts = TRUE;
TeX__source_code(OUT, trs->wv,
C->matter, C->colouring, starts);
}
#line 90 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_url_node_type)
{
#line 302 "inweb/Chapter 5/TeX Format.w"
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
WRITE("%S", C->url);
}
#line 91 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_footnote_cue_node_type)
{
#line 310 "inweb/Chapter 5/TeX Format.w"
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
WRITE("\\footnote{${}^{%S}$}{", C->cue_text);
tree_node *M = N;
while ((M) && (M->type != weave_paragraph_heading_node_type)) M = M->parent;
if (M == NULL) internal_error("tree without section nodes");
M = M->child;
int found = FALSE;
while (M) {
if (M->type == weave_material_node_type) {
weave_material_node *MC = RETRIEVE_POINTER_weave_material_node(M->content);
if (MC->material_type == FOOTNOTES_MATERIAL) {
tree_node *F = M->child;
while (F) {
if (F->type == weave_begin_footnote_text_node_type) {
weave_begin_footnote_text_node *FC =
RETRIEVE_POINTER_weave_begin_footnote_text_node(F->content);
if (Str__eq(FC->cue_text, C->cue_text))
{
#line 346 "inweb/Chapter 5/TeX Format.w"
for (tree_node *X = F->child->next; X; X = X->next)
Trees__traverse_from(X, &TeX__render_visit, (void *) trs, L+1);
found = TRUE;
}
#line 327 "inweb/Chapter 5/TeX Format.w"
;
}
F = F->next;
}
}
}
M = M->next;
}
WRITE("}");
if (found == FALSE) internal_error("cue without text");
}
#line 92 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_display_line_node_type)
{
#line 351 "inweb/Chapter 5/TeX Format.w"
weave_display_line_node *C =
RETRIEVE_POINTER_weave_display_line_node(N->content);
WRITE("\\quotesource{%S}\n", C->text);
}
#line 93 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_function_defn_node_type)
{
#line 356 "inweb/Chapter 5/TeX Format.w"
weave_function_defn_node *C =
RETRIEVE_POINTER_weave_function_defn_node(N->content);
TeX__change_colour_PDF(OUT, FUNCTION_COLOUR, TRUE);
WRITE("%S", C->fn->function_name);
TeX__change_colour_PDF(OUT, PLAIN_COLOUR, TRUE);
return FALSE;
}
#line 94 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_item_node_type)
{
#line 364 "inweb/Chapter 5/TeX Format.w"
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
if (Str__len(C->label) > 0) {
if (C->depth == 1) WRITE("\\item{(%S)}", C->label);
else WRITE("\\itemitem{(%S)}", C->label);
} else {
if (C->depth == 1) WRITE("\\item{}");
else WRITE("\\itemitem{}");
}
}
#line 95 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_grammar_index_node_type)
{
#line 374 "inweb/Chapter 5/TeX Format.w"
InCSupport__weave_grammar_index(OUT);
}
#line 96 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_inline_node_type)
{
#line 377 "inweb/Chapter 5/TeX Format.w"
WRITE("|");
{
#line 394 "inweb/Chapter 5/TeX Format.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &TeX__render_visit, (void *) trs, L+1);
}
#line 378 "inweb/Chapter 5/TeX Format.w"
;
WRITE("|");
return FALSE;
}
#line 97 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_locale_node_type)
{
#line 383 "inweb/Chapter 5/TeX Format.w"
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
WRITE("$\\%S$%S", C->par1->ornament, C->par1->paragraph_number);
if (C->par2) WRITE("-%S", C->par2->paragraph_number);
}
#line 98 "inweb/Chapter 5/TeX Format.w"
else if (N->type == weave_maths_node_type)
{
#line 388 "inweb/Chapter 5/TeX Format.w"
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
if (C->displayed) WRITE("$$"); else WRITE("$");
WRITE("%S", C->content);
if (C->displayed) WRITE("$$"); else WRITE("$");
}
#line 99 "inweb/Chapter 5/TeX Format.w"
else internal_error("unable to render unknown node");
return TRUE;
}
#line 398 "inweb/Chapter 5/TeX Format.w"
text_stream *P_literal = NULL;
void TeX__general_heading(text_stream *OUT, weave_order *wv,
section *S, paragraph *P, text_stream *heading_text, int weight, int no_skip) {
text_stream *TeX_macro = NULL;
{
#line 443 "inweb/Chapter 5/TeX Format.w"
switch (weight) {
case 0: TeX_macro = TL_IS_507; break;
case 1: TeX_macro = TL_IS_508; break;
case 2: TeX_macro = TL_IS_509; break;
default: TeX_macro = TL_IS_510; break;
}
if (wv->theme_match) {
switch (weight) {
case 0: TeX_macro = TL_IS_511; break;
case 1: TeX_macro = TL_IS_512; break;
case 2: TeX_macro = TL_IS_513; break;
default: TeX_macro = TL_IS_514; break;
}
}
if (no_skip) {
switch (weight) {
case 0: TeX_macro = TL_IS_515; break;
case 1: TeX_macro = TL_IS_516; break;
}
}
}
#line 402 "inweb/Chapter 5/TeX Format.w"
;
if (P_literal == NULL) P_literal = Str__new_from_wide_string(L"P");
text_stream *orn = (P)?(P->ornament):P_literal;
text_stream *N = (P)?(P->paragraph_number):NULL;
TEMPORARY_TEXT(mark)
{
#line 474 "inweb/Chapter 5/TeX Format.w"
text_stream *chaptermark = Str__new();
text_stream *sectionmark = Str__new();
if (weight == 3) {
Str__copy(chaptermark, S->owning_chapter->md->ch_title);
Str__clear(sectionmark);
}
if (weight == 2) {
Str__copy(sectionmark, S->md->sect_title);
Str__clear(chaptermark);
if (Str__len(chaptermark) > 0) {
Str__clear(sectionmark);
WRITE_TO(sectionmark, " - %S", S->md->sect_title);
}
}
WRITE_TO(mark, "%S%S\\quad$\\%S$%S", chaptermark, sectionmark, orn, N);
}
#line 408 "inweb/Chapter 5/TeX Format.w"
;
TEMPORARY_TEXT(modified)
Str__copy(modified, heading_text);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, modified, L"(%c*?): (%c*)")) {
Str__clear(modified);
WRITE_TO(modified, "{\\sinchhigh %S}\\quad %S", mr.exp[0], mr.exp[1]);
}
if (weight == 2)
WRITE("\\%S{%S}{%S}{%S}{\\%S}{%S}%%\n",
TeX_macro, N, modified, mark, orn, NULL);
else
WRITE("\\%S{%S}{%S}{%S}{\\%S}{%S}%%\n",
TeX_macro, N, modified, mark, orn, S->md->sect_range);
DISCARD_TEXT(mark)
DISCARD_TEXT(modified)
Regexp__dispose_of(&mr);
}
#line 496 "inweb/Chapter 5/TeX Format.w"
void TeX__source_code(text_stream *OUT, weave_order *wv,
text_stream *matter, text_stream *colouring, int starts) {
int current_colour = PLAIN_COLOUR, colour_wanted = PLAIN_COLOUR;
for (int i=0; i < Str__len(matter); i++) {
colour_wanted = Str__get_at(colouring, i);
{
#line 509 "inweb/Chapter 5/TeX Format.w"
if (colour_wanted != current_colour) {
TeX__change_colour_PDF(OUT, colour_wanted, TRUE);
current_colour = colour_wanted;
}
}
#line 501 "inweb/Chapter 5/TeX Format.w"
;
if (Str__get_at(matter, i) == '|') WRITE("|\\||");
else WRITE("%c", Str__get_at(matter, i));
}
colour_wanted = PLAIN_COLOUR;
{
#line 509 "inweb/Chapter 5/TeX Format.w"
if (colour_wanted != current_colour) {
TeX__change_colour_PDF(OUT, colour_wanted, TRUE);
current_colour = colour_wanted;
}
}
#line 505 "inweb/Chapter 5/TeX Format.w"
;
}
#line 515 "inweb/Chapter 5/TeX Format.w"
void TeX__change_colour_PDF(text_stream *OUT, int col, int in_code) {
char *inout = "";
if (in_code) inout = "|";
switch (col) {
case DEFINITION_COLOUR:
WRITE("%s\\pdfliteral direct{1 1 0 0 k}%s", inout, inout); break;
case FUNCTION_COLOUR:
WRITE("%s\\pdfliteral direct{0 1 1 0 k}%s", inout, inout); break;
case PLAIN_COLOUR:
WRITE("%s\\special{PDF:0 g}%s", inout, inout); break;
case EXTRACT_COLOUR:
WRITE("%s\\special{PDF:0 g}%s", inout, inout); break;
}
}
#line 538 "inweb/Chapter 5/TeX Format.w"
void TeX__para_macro(text_stream *OUT, weave_order *wv, para_macro *pmac, int defn) {
if (defn)
WRITE("|\\pdfdest num %d fit ",
pmac->allocation_id + 100);
else
WRITE("|\\pdfstartlink attr{/C [0.9 0 0] /Border [0 0 0]} goto num %d ",
pmac->allocation_id + 100);
WRITE("$\\langle${\\xreffont");
TeX__change_colour_PDF(OUT, DEFINITION_COLOUR, FALSE);
WRITE("%S ", pmac->macro_name);
WRITE("{\\sevenss %S}}", pmac->defining_paragraph->paragraph_number);
TeX__change_colour_PDF(OUT, PLAIN_COLOUR, FALSE);
WRITE("$\\rangle$ ");
if (defn)
WRITE("$\\equiv$|");
else
WRITE("\\pdfendlink|");
}
#line 558 "inweb/Chapter 5/TeX Format.w"
void TeX__commentary_text(text_stream *OUT, weave_order *wv, text_stream *id) {
int math_mode = FALSE;
for (int i=0; i < Str__len(id); i++) {
switch (Str__get_at(id, i)) {
case '$': math_mode = (math_mode)?FALSE:TRUE;
WRITE("%c", Str__get_at(id, i)); break;
case '_': if (math_mode) WRITE("_"); else WRITE("\\_"); break;
case '"':
if ((Str__get_at(id, i) == '"') &&
((i==0) || (Str__get_at(id, i-1) == ' ') ||
(Str__get_at(id, i-1) == '(')))
WRITE("``");
else
WRITE("''");
break;
default: WRITE("%c", Str__get_at(id, i));
break;
}
}
}
#line 583 "inweb/Chapter 5/TeX Format.w"
int TeX__preform_document(weave_format *self, text_stream *OUT, web *W,
weave_order *wv, chapter *C, section *S, source_line *L, text_stream *matter,
text_stream *concluding_comment) {
if (L->preform_nonterminal_defined) {
preform_production_count = 0;
{
#line 600 "inweb/Chapter 5/TeX Format.w"
WRITE("\\nonterminal{%S} |::=|",
L->preform_nonterminal_defined->unangled_name);
if (L->preform_nonterminal_defined->as_function) {
WRITE("\\quad{\\it internal definition");
if (L->preform_nonterminal_defined->voracious)
WRITE(" (voracious)");
else if (L->preform_nonterminal_defined->min_word_count ==
L->preform_nonterminal_defined->max_word_count)
WRITE(" (%d word%s)",
L->preform_nonterminal_defined->min_word_count,
(L->preform_nonterminal_defined->min_word_count != 1)?"s":"");
WRITE("}");
}
WRITE("\n");
}
#line 588 "inweb/Chapter 5/TeX Format.w"
;
return TRUE;
} else {
if (L->category == PREFORM_GRAMMAR_LCAT) {
{
#line 616 "inweb/Chapter 5/TeX Format.w"
TEMPORARY_TEXT(problem)
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, matter, L"Issue (%c*?) problem"))
Str__copy(problem, mr.exp[0]);
else if (Regexp__match(&mr, matter, L"FAIL_NONTERMINAL %+"))
WRITE_TO(problem, "fail and skip");
else if (Regexp__match(&mr, matter, L"FAIL_NONTERMINAL"))
WRITE_TO(problem, "fail");
preform_production_count++;
WRITE_TO(matter, "|%S|", L->text_operand);
while (Regexp__match(&mr, matter, L"(%c+?)|(%c+)")) {
Str__clear(matter);
WRITE_TO(matter, "%S___stroke___%S", mr.exp[0], mr.exp[1]);
}
while (Regexp__match(&mr, matter, L"(%c*?)___stroke___(%c*)")) {
Str__clear(matter);
WRITE_TO(matter, "%S|\\||%S", mr.exp[0], mr.exp[1]);
}
while (Regexp__match(&mr, matter, L"(%c*)<(%c*?)>(%c*)")) {
Str__clear(matter);
WRITE_TO(matter, "%S|\\nonterminal{%S}|%S",
mr.exp[0], mr.exp[1], mr.exp[2]);
}
TEMPORARY_TEXT(label)
int N = preform_production_count;
int L = ((N-1)%26) + 1;
if (N <= 26) WRITE_TO(label, "%c", 'a'+L-1);
else if (N <= 52) WRITE_TO(label, "%c%c", 'a'+L-1, 'a'+L-1);
else if (N <= 78) WRITE_TO(label, "%c%c%c", 'a'+L-1, 'a'+L-1, 'a'+L-1);
else {
int n = (N-1)/26;
WRITE_TO(label, "%c${}^{%d}$", 'a'+L-1, n);
}
WRITE("\\qquad {\\hbox to 0.4in{\\it %S\\hfil}}%S", label, matter);
if (Str__len(problem) > 0)
WRITE("\\hfill$\\longrightarrow$ {\\ttninepoint\\it %S}", problem);
else if (Str__len(concluding_comment) > 0) {
WRITE(" \\hfill{\\ttninepoint\\it ");
if (Str__len(concluding_comment) > 0)
TeX__commentary_text(OUT, wv, concluding_comment);
WRITE("}");
}
WRITE("\n");
DISCARD_TEXT(label)
DISCARD_TEXT(problem)
Regexp__dispose_of(&mr);
}
#line 592 "inweb/Chapter 5/TeX Format.w"
;
return TRUE;
}
}
return FALSE;
}
#line 9 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__create(void) {
{
#line 15 "inweb/Chapter 5/HTML Formats.w"
weave_format *wf = Formats__create_weave_format(TL_IS_517, TL_IS_518);
METHOD_ADD(wf, RENDER_FOR_MTID, HTMLFormat__render);
}
#line 10 "inweb/Chapter 5/HTML Formats.w"
;
{
#line 19 "inweb/Chapter 5/HTML Formats.w"
weave_format *wf = Formats__create_weave_format(TL_IS_519, TL_IS_520);
METHOD_ADD(wf, RENDER_FOR_MTID, HTMLFormat__render_EPUB);
METHOD_ADD(wf, BEGIN_WEAVING_FOR_MTID, HTMLFormat__begin_weaving_EPUB);
METHOD_ADD(wf, END_WEAVING_FOR_MTID, HTMLFormat__end_weaving_EPUB);
}
#line 11 "inweb/Chapter 5/HTML Formats.w"
;
}
#line 41 "inweb/Chapter 5/HTML Formats.w"
#line 45 "inweb/Chapter 5/HTML Formats.w"
HTML_render_state HTMLFormat__initial_state(text_stream *OUT, weave_order *wv,
int EPUB_mode, filename *into) {
HTML_render_state hrs;
hrs.OUT = OUT;
hrs.into_file = into;
hrs.wv = wv;
hrs.EPUB_flag = EPUB_mode;
hrs.popup_counter = 1;
hrs.carousel_number = 1;
hrs.slide_number = -1;
hrs.slide_of = -1;
hrs.copy_rule = Assets__new_rule(NULL, TL_IS_521, TL_IS_522, NULL);
Swarm__ensure_plugin(wv, TL_IS_523);
hrs.colours = Swarm__ensure_colour_scheme(wv, TL_IS_524, TL_IS_525);
return hrs;
}
#line 67 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
HTML__declare_as_HTML(OUT, FALSE);
HTML_render_state hrs = HTMLFormat__initial_state(OUT, C->wv, FALSE, C->wv->weave_to);
Trees__traverse_from(tree->root, &HTMLFormat__render_visit, (void *) &hrs, 0);
HTML__completed(OUT);
}
void HTMLFormat__render_EPUB(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
HTML__declare_as_HTML(OUT, TRUE);
HTML_render_state hrs = HTMLFormat__initial_state(OUT, C->wv, TRUE, C->wv->weave_to);
Trees__traverse_from(tree->root, &HTMLFormat__render_visit, (void *) &hrs, 0);
Epub__note_page(C->wv->weave_web->as_ebook, C->wv->weave_to, C->wv->booklet_title, TL_IS_526);
HTML__completed(OUT);
}
#line 86 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__render_visit(tree_node *N, void *state, int L) {
HTML_render_state *hrs = (HTML_render_state *) state;
text_stream *OUT = hrs->OUT;
if ((N->type == weave_document_node_type) ||
(N->type == weave_body_node_type) ||
(N->type == weave_chapter_header_node_type) ||
(N->type == weave_chapter_footer_node_type) ||
(N->type == weave_pagebreak_node_type) ||
(N->type == weave_chapter_node_type) ||
(N->type == weave_chapter_title_page_node_type) ||
(N->type == weave_grammar_index_node_type))
{
#line 907 "inweb/Chapter 5/HTML Formats.w"
;
}
#line 96 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_head_node_type)
{
#line 142 "inweb/Chapter 5/HTML Formats.w"
weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content);
HTML__comment(OUT, C->banner);
}
#line 98 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_tail_node_type)
{
#line 282 "inweb/Chapter 5/HTML Formats.w"
weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content);
HTML__comment(OUT, C->rennab);
}
#line 99 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_verbatim_node_type)
{
#line 867 "inweb/Chapter 5/HTML Formats.w"
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
WRITE("%S", C->content);
}
#line 100 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_section_header_node_type)
{
#line 146 "inweb/Chapter 5/HTML Formats.w"
if (hrs->EPUB_flag == FALSE) {
weave_section_header_node *C =
RETRIEVE_POINTER_weave_section_header_node(N->content);
Swarm__ensure_plugin(hrs->wv, TL_IS_527);
HTML_OPEN_WITH("div", "class=\"breadcrumbs\"");
HTML_OPEN_WITH("ul", "class=\"crumbs\"");
Colonies__drop_initial_breadcrumbs(OUT,
hrs->wv->weave_to, hrs->wv->breadcrumbs);
text_stream *bct = Bibliographic__get_datum(hrs->wv->weave_web->md, TL_IS_528);
if (Str__len(Bibliographic__get_datum(hrs->wv->weave_web->md, TL_IS_529)) > 0)
bct = Bibliographic__get_datum(hrs->wv->weave_web->md, TL_IS_530);
if (hrs->wv->self_contained == FALSE) {
Colonies__write_breadcrumb(OUT, bct, TL_IS_531);
if (hrs->wv->weave_web->md->chaptered) {
TEMPORARY_TEXT(chapter_link)
WRITE_TO(chapter_link, "index.html#%s%S",
(hrs->wv->weave_web->as_ebook)?"C":"",
C->sect->owning_chapter->md->ch_range);
Colonies__write_breadcrumb(OUT,
C->sect->owning_chapter->md->ch_title, chapter_link);
DISCARD_TEXT(chapter_link)
}
Colonies__write_breadcrumb(OUT, C->sect->md->sect_title, NULL);
} else {
Colonies__write_breadcrumb(OUT, bct, NULL);
}
HTML_CLOSE("ul");
HTML_CLOSE("div");
}
}
#line 101 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_section_footer_node_type)
{
#line 177 "inweb/Chapter 5/HTML Formats.w"
weave_section_footer_node *C =
RETRIEVE_POINTER_weave_section_footer_node(N->content);
int count = 0;
chapter *Ch;
section *next_S = NULL, *prev_S = NULL, *last = NULL;
LOOP_OVER_LINKED_LIST(Ch, chapter, hrs->wv->weave_web->chapters) {
if (Ch->md->imported == FALSE) {
section *S;
LOOP_OVER_LINKED_LIST(S, section, Ch->sections) {
count ++;
if (S == C->sect) prev_S = last;
if (last == C->sect) next_S = S;
last = S;
}
}
}
if (count >= 2) {
HTML_OPEN_WITH("nav", "role=\"progress\"");
HTML_OPEN_WITH("div", "class=\"progresscontainer\"");
HTML_OPEN_WITH("ul", "class=\"progressbar\"");
{
#line 260 "inweb/Chapter 5/HTML Formats.w"
if (prev_S) HTML_OPEN_WITH("li", "class=\"progressprev\"")
else HTML_OPEN_WITH("li", "class=\"progressprevoff\"");
TEMPORARY_TEXT(TEMP)
if (prev_S) Colonies__section_URL(TEMP, prev_S->md);
if (prev_S) HTML__begin_link(OUT, TEMP);
WRITE("&#10094;");
if (prev_S) HTML__end_link(OUT);
DISCARD_TEXT(TEMP)
HTML_CLOSE("li");
}
#line 197 "inweb/Chapter 5/HTML Formats.w"
;
chapter *Ch;
LOOP_OVER_LINKED_LIST(Ch, chapter, hrs->wv->weave_web->chapters) {
if (Ch->md->imported == FALSE) {
if (Str__ne(Ch->md->ch_range, TL_IS_532)) {
if (Ch == C->sect->owning_chapter) {
HTML_OPEN_WITH("li", "class=\"progresscurrentchapter\"");
} else {
HTML_OPEN_WITH("li", "class=\"progresschapter\"");
}
section *S = FIRST_IN_LINKED_LIST(section, Ch->sections);
if (S) {
TEMPORARY_TEXT(TEMP)
Colonies__section_URL(TEMP, S->md);
if (Ch != C->sect->owning_chapter) {
HTML__begin_link(OUT, TEMP);
}
WRITE("%S", Ch->md->ch_range);
if (Ch != C->sect->owning_chapter) {
HTML__end_link(OUT);
}
DISCARD_TEXT(TEMP)
}
HTML_CLOSE("li");
}
if (Ch == C->sect->owning_chapter) {
section *S;
LOOP_OVER_LINKED_LIST(S, section, Ch->sections) {
TEMPORARY_TEXT(label)
int on = FALSE;
LOOP_THROUGH_TEXT(pos, S->md->sect_range) {
if (Str__get(pos) == '/') on = TRUE;
else if (on) PUT_TO(label, Str__get(pos));
}
if (Str__eq(Bibliographic__get_datum(hrs->wv->weave_web->md,
TL_IS_533), TL_IS_534))
Str__delete_first_character(label);
if (S == C->sect) {
HTML_OPEN_WITH("li", "class=\"progresscurrent\"");
WRITE("%S", label);
HTML_CLOSE("li");
} else {
HTML_OPEN_WITH("li", "class=\"progresssection\"");
TEMPORARY_TEXT(TEMP)
Colonies__section_URL(TEMP, S->md);
HTML__begin_link(OUT, TEMP);
WRITE("%S", label);
HTML__end_link(OUT);
DISCARD_TEXT(TEMP)
HTML_CLOSE("li");
}
DISCARD_TEXT(label)
}
}
}
}
{
#line 271 "inweb/Chapter 5/HTML Formats.w"
if (next_S) HTML_OPEN_WITH("li", "class=\"progressnext\"")
else HTML_OPEN_WITH("li", "class=\"progressnextoff\"");
TEMPORARY_TEXT(TEMP)
if (next_S) Colonies__section_URL(TEMP, next_S->md);
if (next_S) HTML__begin_link(OUT, TEMP);
WRITE("&#10095;");
if (next_S) HTML__end_link(OUT);
DISCARD_TEXT(TEMP)
HTML_CLOSE("li");
}
#line 253 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("ul");
HTML_CLOSE("div");
HTML_CLOSE("nav");
}
}
#line 102 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_section_purpose_node_type)
{
#line 286 "inweb/Chapter 5/HTML Formats.w"
weave_section_purpose_node *C =
RETRIEVE_POINTER_weave_section_purpose_node(N->content);
HTML_OPEN_WITH("p", "class=\"purpose\"");
HTMLFormat__escape_text(OUT, C->purpose);
HTML_CLOSE("p"); WRITE("\n");
}
#line 103 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_subheading_node_type)
{
#line 293 "inweb/Chapter 5/HTML Formats.w"
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
HTML_OPEN("h3");
HTMLFormat__escape_text(OUT, C->text);
HTML_CLOSE("h3"); WRITE("\n");
}
#line 104 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_bar_node_type)
{
#line 299 "inweb/Chapter 5/HTML Formats.w"
HTML__hr(OUT, NULL);
}
#line 105 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_paragraph_heading_node_type)
{
#line 302 "inweb/Chapter 5/HTML Formats.w"
weave_paragraph_heading_node *C =
RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
paragraph *P = C->para;
if (P == NULL) internal_error("no para");
if (N->child == NULL) {
paragraph *first_in_para = P;
{
#line 460 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
HTML_CLOSE("p"); WRITE("\n");
first_in_para = NULL;
}
}
#line 308 "inweb/Chapter 5/HTML Formats.w"
;
}
}
#line 106 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_endnote_node_type)
{
#line 312 "inweb/Chapter 5/HTML Formats.w"
HTML_OPEN("li");
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 313 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("li");
return FALSE;
}
#line 107 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_figure_node_type)
{
#line 318 "inweb/Chapter 5/HTML Formats.w"
weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content);
filename *F = Filenames__in(
Pathnames__down(hrs->wv->weave_web->md->path_to_web, TL_IS_535),
C->figname);
filename *RF = Filenames__from_text(C->figname);
HTML_OPEN_WITH("p", "class=\"center-p\"");
HTML__image_to_dimensions(OUT, RF, C->w, C->h);
Assets__include_asset(OUT, hrs->copy_rule, hrs->wv->weave_web, F, NULL,
hrs->wv->pattern, hrs->wv->weave_to);
HTML_CLOSE("p");
WRITE("\n");
}
#line 108 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_extract_node_type)
{
#line 331 "inweb/Chapter 5/HTML Formats.w"
weave_extract_node *C = RETRIEVE_POINTER_weave_extract_node(N->content);
filename *F = Filenames__in(
Pathnames__down(hrs->wv->weave_web->md->path_to_web, TL_IS_536),
C->extract);
HTML_OPEN_WITH("div", "class=\"inweb-extract\"");
FILE *B = BinaryFiles__try_to_open_for_reading(F);
if (B == NULL) {
Main__error_in_web(TL_IS_537,
hrs->wv->current_weave_line);
} else {
while (TRUE) {
int c = getc(B);
if (c == EOF) break;
PUT((wchar_t) c);
}
BinaryFiles__close(B);
}
HTML_CLOSE("div");
WRITE("\n");
}
#line 109 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_audio_node_type)
{
#line 352 "inweb/Chapter 5/HTML Formats.w"
weave_audio_node *C = RETRIEVE_POINTER_weave_audio_node(N->content);
filename *F = Filenames__in(
Pathnames__down(hrs->wv->weave_web->md->path_to_web, TL_IS_538),
C->audio_name);
Assets__include_asset(OUT, hrs->copy_rule, hrs->wv->weave_web, F, NULL,
hrs->wv->pattern, hrs->wv->weave_to);
HTML_OPEN_WITH("p", "class=\"center-p\"");
WRITE("<audio controls>\n");
WRITE("<source src=\"%S\" type=\"audio/mpeg\">\n", C->audio_name);
WRITE("Your browser does not support the audio element.\n");
WRITE("</audio>\n");
HTML_CLOSE("p");
WRITE("\n");
}
#line 110 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_video_node_type)
{
#line 367 "inweb/Chapter 5/HTML Formats.w"
weave_video_node *C = RETRIEVE_POINTER_weave_video_node(N->content);
filename *F = Filenames__in(
Pathnames__down(hrs->wv->weave_web->md->path_to_web, TL_IS_539),
C->video_name);
Assets__include_asset(OUT, hrs->copy_rule, hrs->wv->weave_web, F, NULL,
hrs->wv->pattern, hrs->wv->weave_to);
HTML_OPEN_WITH("p", "class=\"center-p\"");
if ((C->w > 0) && (C->h > 0))
WRITE("<video width=\"%d\" height=\"%d\" controls>", C->w, C->h);
else if (C->w > 0)
WRITE("<video width=\"%d\" controls>", C->w);
else if (C->h > 0)
WRITE("<video height=\"%d\" controls>", C->h);
else
WRITE("<video controls>");
WRITE("<source src=\"%S\" type=\"video/mp4\">\n", C->video_name);
WRITE("Your browser does not support the video tag.\n");
WRITE("</video>\n");
HTML_CLOSE("p");
WRITE("\n");
}
#line 111 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_download_node_type)
{
#line 389 "inweb/Chapter 5/HTML Formats.w"
weave_download_node *C = RETRIEVE_POINTER_weave_download_node(N->content);
pathname *P = Pathnames__down(hrs->wv->weave_web->md->path_to_web, TL_IS_540);
filename *F = Filenames__in(P, C->download_name);
filename *TF = Patterns__find_file_in_subdirectory(hrs->wv->pattern, TL_IS_541,
TL_IS_542);
if (TF == NULL) {
Main__error_in_web(TL_IS_543, hrs->wv->current_weave_line);
} else {
Swarm__ensure_plugin(hrs->wv, TL_IS_544);
pathname *TOP =
Assets__include_asset(OUT, hrs->copy_rule, hrs->wv->weave_web, F, NULL,
hrs->wv->pattern, hrs->wv->weave_to);
if (TOP == NULL) TOP = Filenames__up(F);
TEMPORARY_TEXT(url)
TEMPORARY_TEXT(size)
Pathnames__relative_URL(url, Filenames__up(hrs->wv->weave_to), TOP);
WRITE_TO(url, "%S", Filenames__get_leafname(F));
int N = Filenames__size(F);
if (N > 0)
{
#line 423 "inweb/Chapter 5/HTML Formats.w"
WRITE_TO(size, " (");
if (Str__len(C->filetype) > 0) WRITE_TO(size, "%S, ", C->filetype);
int x = 0, y = 0;
text_stream *unit = TL_IS_549; x = N; y = 0;
if (N > 1) { unit = TL_IS_550; }
if (N >= 1024) { unit = TL_IS_551; x = 10*N/1024; y = x%10; x = x/10; }
if (N >= 1024*1024) { unit = TL_IS_552; x = 10*N/1024/1024; y = x%10; x = x/10; }
if (N >= 1024*1024*1024) { unit = TL_IS_553; x = 10*N/1024/1024/1024; y = x%10; x = x/10; }
WRITE_TO(size, "%d", x);
if (y > 0) WRITE_TO(size, ".%d", y);
WRITE_TO(size, "%S", unit);
WRITE_TO(size, ")");
}
#line 407 "inweb/Chapter 5/HTML Formats.w"
else Main__error_in_web(TL_IS_545,
hrs->wv->current_weave_line);
filename *D = Filenames__from_text(C->download_name);
Bibliographic__set_datum(hrs->wv->weave_web->md, TL_IS_546,
Filenames__get_leafname(D));
Bibliographic__set_datum(hrs->wv->weave_web->md, TL_IS_547, url);
Bibliographic__set_datum(hrs->wv->weave_web->md, TL_IS_548, size);
Collater__for_web_and_pattern(OUT, hrs->wv->weave_web, hrs->wv->pattern,
TF, hrs->into_file);
WRITE("\n");
DISCARD_TEXT(url)
DISCARD_TEXT(size)
}
}
#line 112 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_material_node_type)
{
#line 437 "inweb/Chapter 5/HTML Formats.w"
weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content);
paragraph *first_in_para = NULL;
if ((N == N->parent->child) &&
(N->parent->type == weave_paragraph_heading_node_type)) {
weave_paragraph_heading_node *PC =
RETRIEVE_POINTER_weave_paragraph_heading_node(N->parent->content);
first_in_para = PC->para;
}
if (C->material_type == COMMENTARY_MATERIAL)
{
#line 468 "inweb/Chapter 5/HTML Formats.w"
int item_depth = 0;
for (tree_node *M = N->child; M; M = M->next) {
if (M->type == weave_item_node_type) {
{
#line 460 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
HTML_CLOSE("p"); WRITE("\n");
first_in_para = NULL;
}
}
#line 471 "inweb/Chapter 5/HTML Formats.w"
;
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(M->content);
HTMLFormat__go_to_depth(hrs, item_depth, C->depth);
item_depth = C->depth;
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
continue;
}
if (HTMLFormat__interior_material(M))
{
#line 493 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
first_in_para = NULL;
} else {
if (item_depth == 0) HTML_OPEN_WITH("p", "class=\"commentary\"");
}
while (M) {
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
if ((M->next == NULL) || (HTMLFormat__interior_material(M->next) == FALSE)) break;
M = M->next;
}
if (item_depth == 0) { HTML_CLOSE("p"); WRITE("\n"); }
continue;
}
#line 478 "inweb/Chapter 5/HTML Formats.w"
;
{
#line 460 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
HTML_CLOSE("p"); WRITE("\n");
first_in_para = NULL;
}
}
#line 479 "inweb/Chapter 5/HTML Formats.w"
;
if (item_depth > 0) {
HTMLFormat__go_to_depth(hrs, item_depth, 0);
item_depth = 0;
}
if (M->type == weave_vskip_node_type) continue;
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
if (item_depth > 0) {
HTMLFormat__go_to_depth(hrs, item_depth, 0);
item_depth = 0;
}
}
#line 446 "inweb/Chapter 5/HTML Formats.w"
else if (C->material_type == CODE_MATERIAL)
{
#line 509 "inweb/Chapter 5/HTML Formats.w"
{
#line 460 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
HTML_CLOSE("p"); WRITE("\n");
first_in_para = NULL;
}
}
#line 509 "inweb/Chapter 5/HTML Formats.w"
;
if (C->styling) {
TEMPORARY_TEXT(csname)
WRITE_TO(csname, "%S-Colours", C->styling->language_name);
hrs->colours = Swarm__ensure_colour_scheme(hrs->wv,
csname, C->styling->language_name);
DISCARD_TEXT(csname)
}
TEMPORARY_TEXT(cl)
WRITE_TO(cl, "%S", hrs->colours->prefix);
if (C->plainly) WRITE_TO(cl, "undisplayed-code");
else WRITE_TO(cl, "displayed-code");
WRITE("<pre class=\"%S all-displayed-code code-font\">\n", cl);
DISCARD_TEXT(cl)
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 523 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("pre"); WRITE("\n");
if (Str__len(C->endnote) > 0) {
HTML_OPEN_WITH("ul", "class=\"endnotetexts\"");
HTML_OPEN("li");
HTMLFormat__escape_text(OUT, C->endnote);
HTML_CLOSE("li");
HTML_CLOSE("ul"); WRITE("\n");
}
}
#line 448 "inweb/Chapter 5/HTML Formats.w"
else if (C->material_type == FOOTNOTES_MATERIAL)
{
#line 534 "inweb/Chapter 5/HTML Formats.w"
{
#line 460 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
HTML_CLOSE("p"); WRITE("\n");
first_in_para = NULL;
}
}
#line 534 "inweb/Chapter 5/HTML Formats.w"
;
HTML_OPEN_WITH("ul", "class=\"footnotetexts\"");
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 536 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("ul"); WRITE("\n");
}
#line 450 "inweb/Chapter 5/HTML Formats.w"
else if (C->material_type == ENDNOTES_MATERIAL)
{
#line 540 "inweb/Chapter 5/HTML Formats.w"
{
#line 460 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
HTML_CLOSE("p"); WRITE("\n");
first_in_para = NULL;
}
}
#line 540 "inweb/Chapter 5/HTML Formats.w"
;
HTML_OPEN_WITH("ul", "class=\"endnotetexts\"");
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 542 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("ul"); WRITE("\n");
}
#line 452 "inweb/Chapter 5/HTML Formats.w"
else if (C->material_type == MACRO_MATERIAL)
{
#line 546 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
} else {
HTML_OPEN_WITH("p", "class=\"commentary\"");
}
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 552 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("p"); WRITE("\n");
}
#line 454 "inweb/Chapter 5/HTML Formats.w"
else if (C->material_type == DEFINITION_MATERIAL)
{
#line 556 "inweb/Chapter 5/HTML Formats.w"
{
#line 460 "inweb/Chapter 5/HTML Formats.w"
if (first_in_para) {
HTML_OPEN_WITH("p", "class=\"commentary firstcommentary\"");
HTMLFormat__paragraph_number(OUT, first_in_para);
HTML_CLOSE("p"); WRITE("\n");
first_in_para = NULL;
}
}
#line 556 "inweb/Chapter 5/HTML Formats.w"
;
HTML_OPEN_WITH("pre", "class=\"definitions code-font\"");
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 558 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("pre"); WRITE("\n");
}
#line 456 "inweb/Chapter 5/HTML Formats.w"
;
return FALSE;
}
#line 113 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_embed_node_type)
{
#line 566 "inweb/Chapter 5/HTML Formats.w"
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
text_stream *CH = TL_IS_554;
text_stream *CW = TL_IS_555;
if (C->w > 0) { Str__clear(CW); WRITE_TO(CW, "%d", C->w); }
if (C->h > 0) { Str__clear(CH); WRITE_TO(CH, "%d", C->h); }
TEMPORARY_TEXT(embed_leaf)
WRITE_TO(embed_leaf, "%S.html", C->service);
filename *F = Patterns__find_file_in_subdirectory(hrs->wv->pattern, TL_IS_556, embed_leaf);
DISCARD_TEXT(embed_leaf)
if (F == NULL) {
Main__error_in_web(TL_IS_557, hrs->wv->current_weave_line);
} else {
Bibliographic__set_datum(hrs->wv->weave_web->md, TL_IS_558, C->ID);
Bibliographic__set_datum(hrs->wv->weave_web->md, TL_IS_559, CW);
Bibliographic__set_datum(hrs->wv->weave_web->md, TL_IS_560, CH);
HTML_OPEN_WITH("p", "class=\"center-p\"");
Collater__for_web_and_pattern(OUT, hrs->wv->weave_web, hrs->wv->pattern,
F, hrs->into_file);
HTML_CLOSE("p");
WRITE("\n");
}
}
#line 114 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_pmac_node_type)
{
#line 589 "inweb/Chapter 5/HTML Formats.w"
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
paragraph *P = C->pmac->defining_paragraph;
HTML_OPEN_WITH("span", "class=\"named-paragraph-container code-font\"");
if (C->defn == FALSE) {
TEMPORARY_TEXT(url)
Colonies__paragraph_URL(url, P, hrs->wv->weave_to);
HTML__begin_link_with_class(OUT, TL_IS_561, url);
DISCARD_TEXT(url)
}
HTML_OPEN_WITH("span", "class=\"%s\"",
(C->defn)?"named-paragraph-defn":"named-paragraph");
HTMLFormat__escape_text(OUT, C->pmac->macro_name);
HTML_CLOSE("span");
HTML_OPEN_WITH("span", "class=\"named-paragraph-number\"");
HTMLFormat__escape_text(OUT, P->paragraph_number);
HTML_CLOSE("span");
if (C->defn == FALSE) HTML__end_link(OUT);
HTML_CLOSE("span");
if (C->defn) {
HTMLFormat__change_colour(OUT, COMMENT_COLOUR, hrs->colours);
WRITE(" =");
HTMLFormat__change_colour(OUT, -1, hrs->colours);
}
}
#line 115 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_vskip_node_type)
{
#line 614 "inweb/Chapter 5/HTML Formats.w"
WRITE("\n");
}
#line 116 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_section_node_type)
{
#line 617 "inweb/Chapter 5/HTML Formats.w"
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
LOG("It was %d\n", C->allocation_id);
}
#line 117 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_code_line_node_type)
{
#line 621 "inweb/Chapter 5/HTML Formats.w"
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 621 "inweb/Chapter 5/HTML Formats.w"
;
WRITE("\n");
return FALSE;
}
#line 118 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_function_usage_node_type)
{
#line 626 "inweb/Chapter 5/HTML Formats.w"
weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content);
HTML__begin_link_with_class(OUT, TL_IS_562, C->url);
HTMLFormat__change_colour(OUT, FUNCTION_COLOUR, hrs->colours);
WRITE("%S", C->fn->function_name);
HTMLFormat__change_colour(OUT, -1, hrs->colours);
HTML__end_link(OUT);
}
#line 119 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_commentary_node_type)
{
#line 634 "inweb/Chapter 5/HTML Formats.w"
weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content);
if (C->in_code) HTMLFormat__change_colour(OUT, COMMENT_COLOUR, hrs->colours);
for (int i=0; i < Str__len(C->text); i++) {
if (Str__get_at(C->text, i) == '&') WRITE("&amp;");
else if (Str__get_at(C->text, i) == '<') WRITE("&lt;");
else if (Str__get_at(C->text, i) == '>') WRITE("&gt;");
else if ((i == 0) && (Str__get_at(C->text, i) == '-') &&
(Str__get_at(C->text, i+1) == '-') &&
((Str__get_at(C->text, i+2) == ' ') || (Str__get_at(C->text, i+2) == 0))) {
WRITE("&mdash;"); i++;
} else if ((Str__get_at(C->text, i) == ' ') && (Str__get_at(C->text, i+1) == '-') &&
(Str__get_at(C->text, i+2) == '-') &&
((Str__get_at(C->text, i+3) == ' ') || (Str__get_at(C->text, i+3) == '\n') ||
(Str__get_at(C->text, i+3) == 0))) {
WRITE(" &mdash;"); i+=2;
} else PUT(Str__get_at(C->text, i));
}
if (C->in_code) HTMLFormat__change_colour(OUT, -1, hrs->colours);
}
#line 120 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_carousel_slide_node_type)
{
#line 654 "inweb/Chapter 5/HTML Formats.w"
weave_carousel_slide_node *C = RETRIEVE_POINTER_weave_carousel_slide_node(N->content);
Swarm__ensure_plugin(hrs->wv, TL_IS_563);
TEMPORARY_TEXT(carousel_id)
TEMPORARY_TEXT(carousel_dots_id)
text_stream *caption_class = NULL;
text_stream *slide_count_class = TL_IS_564;
switch (C->caption_command) {
case CAROUSEL_CMD: caption_class = TL_IS_565; break;
case CAROUSEL_ABOVE_CMD: caption_class = TL_IS_566;
slide_count_class = TL_IS_567; break;
case CAROUSEL_BELOW_CMD: caption_class = TL_IS_568;
slide_count_class = TL_IS_569; break;
}
WRITE_TO(carousel_id, "carousel-no-%d", hrs->carousel_number);
WRITE_TO(carousel_dots_id, "carousel-dots-no-%d", hrs->carousel_number);
if (hrs->slide_number == -1) {
hrs->slide_number = 1;
hrs->slide_of = 0;
for (tree_node *X = N; (X) && (X->type == N->type); X = X->next) hrs->slide_of++;
} else {
hrs->slide_number++;
if (hrs->slide_number > hrs->slide_of) internal_error("miscounted slides");
}
if (hrs->slide_number == 1) {
WRITE("<div class=\"carousel-container\" id=\"%S\">\n", carousel_id);
}
WRITE("<div class=\"carousel-slide fading-slide\"");
if (hrs->slide_number == 1) WRITE(" style=\"display: block;\"");
else WRITE(" style=\"display: none;\"");
WRITE(">\n");
if (C->caption_command == CAROUSEL_ABOVE_CMD) {
{
#line 727 "inweb/Chapter 5/HTML Formats.w"
if (C->caption_command != CAROUSEL_UNCAPTIONED_CMD)
WRITE("<div class=\"%S\">%S</div>\n", caption_class, C->caption);
}
#line 685 "inweb/Chapter 5/HTML Formats.w"
;
WRITE("<div class=\"%S\">%d / %d</div>\n",
slide_count_class, hrs->slide_number, hrs->slide_of);
} else {
WRITE("<div class=\"%S\">%d / %d</div>\n",
slide_count_class, hrs->slide_number, hrs->slide_of);
}
WRITE("<div class=\"carousel-content\">");
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 693 "inweb/Chapter 5/HTML Formats.w"
;
WRITE("</div>\n");
if (C->caption_command != CAROUSEL_ABOVE_CMD)
{
#line 727 "inweb/Chapter 5/HTML Formats.w"
if (C->caption_command != CAROUSEL_UNCAPTIONED_CMD)
WRITE("<div class=\"%S\">%S</div>\n", caption_class, C->caption);
}
#line 695 "inweb/Chapter 5/HTML Formats.w"
;
WRITE("</div>\n");
if (hrs->slide_number == hrs->slide_of) {
WRITE("<a class=\"carousel-prev-button\" ");
WRITE("onclick=\"carouselMoveSlide(&quot;%S&quot;, &quot;%S&quot;, -1)\"",
carousel_id, carousel_dots_id);
WRITE(">&#10094;</a>\n");
WRITE("<a class=\"carousel-next-button\" ");
WRITE("onclick=\"carouselMoveSlide(&quot;%S&quot;, &quot;%S&quot;, 1)\"",
carousel_id, carousel_dots_id);
WRITE(">&#10095;</a>\n");
WRITE("</div>\n");
WRITE("<div class=\"carousel-dots-container\" id=\"%S\">\n", carousel_dots_id);
for (int i=1; i<=hrs->slide_of; i++) {
if (i == 1)
WRITE("<span class=\"carousel-dot carousel-dot-active\" ");
else
WRITE("<span class=\"carousel-dot\" ");
WRITE("onclick=\"carouselSetSlide(&quot;%S&quot;, &quot;%S&quot;, %d)\"",
carousel_id, carousel_dots_id, i-1);
WRITE("></span>\n");
}
WRITE("</div>\n");
hrs->slide_number = -1;
hrs->slide_of = -1;
hrs->carousel_number++;
}
DISCARD_TEXT(carousel_id)
DISCARD_TEXT(carousel_dots_id)
return FALSE;
}
#line 121 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_toc_node_type)
{
#line 731 "inweb/Chapter 5/HTML Formats.w"
HTML_OPEN_WITH("ul", "class=\"toc\"");
for (tree_node *M = N->child; M; M = M->next) {
HTML_OPEN("li");
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
HTML_CLOSE("li");
}
HTML_CLOSE("ul");
HTML__hr(OUT, "tocbar");
WRITE("\n");
return FALSE;
}
#line 122 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_toc_line_node_type)
{
#line 743 "inweb/Chapter 5/HTML Formats.w"
weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content);
TEMPORARY_TEXT(TEMP)
Colonies__paragraph_URL(TEMP, C->para, hrs->wv->weave_to);
HTML__begin_link(OUT, TEMP);
DISCARD_TEXT(TEMP)
WRITE("%s%S", (Str__get_first_char(C->para->ornament) == 'S')?"&#167;":"&para;",
C->para->paragraph_number);
WRITE(". %S", C->text2);
HTML__end_link(OUT);
}
#line 123 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_defn_node_type)
{
#line 754 "inweb/Chapter 5/HTML Formats.w"
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
HTML_OPEN_WITH("span", "class=\"definition-keyword\"");
WRITE("%S", C->keyword);
HTML_CLOSE("span");
WRITE(" ");
}
#line 124 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_source_code_node_type)
{
#line 761 "inweb/Chapter 5/HTML Formats.w"
weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content);
int starts = FALSE;
if (N == N->parent->child) starts = TRUE;
int current_colour = -1, colour_wanted = PLAIN_COLOUR;
for (int i=0; i < Str__len(C->matter); i++) {
colour_wanted = Str__get_at(C->colouring, i);
if (colour_wanted != current_colour) {
if (current_colour >= 0) HTML_CLOSE("span");
HTMLFormat__change_colour(OUT, colour_wanted, hrs->colours);
current_colour = colour_wanted;
}
if (Str__get_at(C->matter, i) == '<') WRITE("&lt;");
else if (Str__get_at(C->matter, i) == '>') WRITE("&gt;");
else if (Str__get_at(C->matter, i) == '&') WRITE("&amp;");
else WRITE("%c", Str__get_at(C->matter, i));
}
if (current_colour >= 0) HTMLFormat__change_colour(OUT, -1, hrs->colours);
}
#line 125 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_url_node_type)
{
#line 780 "inweb/Chapter 5/HTML Formats.w"
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
HTML__begin_link_with_class(OUT, (C->external)?TL_IS_570:TL_IS_571, C->url);
WRITE("%S", C->content);
HTML__end_link(OUT);
}
#line 126 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_footnote_cue_node_type)
{
#line 786 "inweb/Chapter 5/HTML Formats.w"
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
text_stream *fn_plugin_name = hrs->wv->pattern->footnotes_plugin;
if (Str__len(fn_plugin_name) > 0)
Swarm__ensure_plugin(hrs->wv, fn_plugin_name);
if (hrs->EPUB_flag) {
if (N->parent->type != weave_begin_footnote_text_node_type)
WRITE("<a id=\"fnref%S\"></a>", C->cue_text);
WRITE("<sup><a href=\"#fn%S\" rel=\"footnote\">%S</a></sup>",
C->cue_text, C->cue_text);
} else
WRITE("<sup id=\"fnref:%S\"><a href=\"#fn:%S\" rel=\"footnote\">%S</a></sup>",
C->cue_text, C->cue_text, C->cue_text);
}
#line 127 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_begin_footnote_text_node_type)
{
#line 800 "inweb/Chapter 5/HTML Formats.w"
weave_begin_footnote_text_node *C =
RETRIEVE_POINTER_weave_begin_footnote_text_node(N->content);
text_stream *fn_plugin_name = hrs->wv->pattern->footnotes_plugin;
if ((Str__len(fn_plugin_name) > 0) && (hrs->EPUB_flag == FALSE))
Swarm__ensure_plugin(hrs->wv, fn_plugin_name);
if (hrs->EPUB_flag)
WRITE("<li class=\"footnote\" id=\"fn%S\"><p class=\"inwebfootnote\">",
C->cue_text);
else
WRITE("<li class=\"footnote\" id=\"fn:%S\"><p class=\"inwebfootnote\">",
C->cue_text);
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 811 "inweb/Chapter 5/HTML Formats.w"
;
if (hrs->EPUB_flag)
WRITE("<a href=\"#fnref%S\"> (return to text)</a></p></li>",
C->cue_text);
else
WRITE("<a href=\"#fnref:%S\" title=\"return to text\"> &#x21A9;</a></p></li>",
C->cue_text);
return FALSE;
}
#line 128 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_display_line_node_type)
{
#line 821 "inweb/Chapter 5/HTML Formats.w"
weave_display_line_node *C =
RETRIEVE_POINTER_weave_display_line_node(N->content);
HTML_OPEN("blockquote"); WRITE("\n"); INDENT;
HTML_OPEN("p");
HTMLFormat__escape_text(OUT, C->text);
HTML_CLOSE("p");
OUTDENT; HTML_CLOSE("blockquote"); WRITE("\n");
}
#line 129 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_function_defn_node_type)
{
#line 830 "inweb/Chapter 5/HTML Formats.w"
weave_function_defn_node *C =
RETRIEVE_POINTER_weave_function_defn_node(N->content);
if ((Functions__used_elsewhere(C->fn)) && (hrs->EPUB_flag == FALSE)) {
Swarm__ensure_plugin(hrs->wv, TL_IS_572);
HTMLFormat__change_colour(OUT, FUNCTION_COLOUR, hrs->colours);
WRITE("%S", C->fn->function_name);
WRITE("</span>");
WRITE("<button class=\"popup\" onclick=\"togglePopup('usagePopup%d')\">",
hrs->popup_counter);
HTMLFormat__change_colour(OUT, COMMENT_COLOUR, hrs->colours);
WRITE("?");
HTMLFormat__change_colour(OUT, -1, hrs->colours);
WRITE("<span class=\"popuptext\" id=\"usagePopup%d\">Usage of ", hrs->popup_counter);
HTML_OPEN_WITH("span", "class=\"code-font\"");
HTMLFormat__change_colour(OUT, FUNCTION_COLOUR, hrs->colours);
WRITE("%S", C->fn->function_name);
HTMLFormat__change_colour(OUT, -1, hrs->colours);
HTML_CLOSE("span");
WRITE(":<br/>");
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 849 "inweb/Chapter 5/HTML Formats.w"
;
HTMLFormat__change_colour(OUT, -1, hrs->colours);
WRITE("</button>");
hrs->popup_counter++;
} else {
HTMLFormat__change_colour(OUT, FUNCTION_COLOUR, hrs->colours);
WRITE("%S", C->fn->function_name);
HTMLFormat__change_colour(OUT, -1, hrs->colours);
}
return FALSE;
}
#line 130 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_item_node_type)
{
#line 861 "inweb/Chapter 5/HTML Formats.w"
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
if (Str__eq(C->label, TL_IS_573)) WRITE("&#9679; ");
else if (Str__len(C->label) > 0) WRITE("(%S) ", C->label);
else WRITE(" ");
}
#line 131 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_inline_node_type)
{
#line 871 "inweb/Chapter 5/HTML Formats.w"
HTML_OPEN_WITH("span", "class=\"extract\"");
{
#line 910 "inweb/Chapter 5/HTML Formats.w"
for (tree_node *M = N->child; M; M = M->next)
Trees__traverse_from(M, &HTMLFormat__render_visit, (void *) hrs, L+1);
}
#line 872 "inweb/Chapter 5/HTML Formats.w"
;
HTML_CLOSE("span");
return FALSE;
}
#line 132 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_locale_node_type)
{
#line 877 "inweb/Chapter 5/HTML Formats.w"
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
TEMPORARY_TEXT(TEMP)
Colonies__paragraph_URL(TEMP, C->par1, hrs->wv->weave_to);
HTML__begin_link(OUT, TEMP);
DISCARD_TEXT(TEMP)
WRITE("%s%S",
(Str__get_first_char(C->par1->ornament) == 'S')?"&#167;":"&para;",
C->par1->paragraph_number);
if (C->par2) WRITE("-%S", C->par2->paragraph_number);
HTML__end_link(OUT);
}
#line 133 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_maths_node_type)
{
#line 889 "inweb/Chapter 5/HTML Formats.w"
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
text_stream *plugin_name = hrs->wv->pattern->mathematics_plugin;
if ((Str__len(plugin_name) == 0) || (hrs->EPUB_flag)) {
TEMPORARY_TEXT(R)
TeXUtilities__remove_math_mode(R, C->content);
HTMLFormat__escape_text(OUT, R);
DISCARD_TEXT(R)
} else {
Swarm__ensure_plugin(hrs->wv, plugin_name);
if (C->displayed) WRITE("$$"); else WRITE("\\(");
HTMLFormat__escape_text(OUT, C->content);
if (C->displayed) WRITE("$$"); else WRITE("\\)");
}
}
#line 134 "inweb/Chapter 5/HTML Formats.w"
else if (N->type == weave_linebreak_node_type)
{
#line 904 "inweb/Chapter 5/HTML Formats.w"
WRITE("<br/>");
}
#line 135 "inweb/Chapter 5/HTML Formats.w"
else internal_error("unable to render unknown node");
return TRUE;
}
#line 917 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__interior_material(tree_node *N) {
if (N->type == weave_commentary_node_type) return TRUE;
if (N->type == weave_url_node_type) return TRUE;
if (N->type == weave_inline_node_type) return TRUE;
if (N->type == weave_locale_node_type) return TRUE;
if (N->type == weave_maths_node_type) return TRUE;
if (N->type == weave_footnote_cue_node_type) return TRUE;
return FALSE;
}
#line 931 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__go_to_depth(HTML_render_state *hrs, int from_depth, int to_depth) {
text_stream *OUT = hrs->OUT;
if (from_depth == to_depth) {
HTML_CLOSE("li");
} else {
while (from_depth < to_depth) {
HTML_OPEN_WITH("ul", "class=\"items\""); from_depth++;
}
while (from_depth > to_depth) {
HTML_CLOSE("li");
HTML_CLOSE("ul");
WRITE("\n"); from_depth--;
}
}
if (to_depth > 0) HTML_OPEN("li");
}
#line 949 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__paragraph_number(text_stream *OUT, paragraph *P) {
TEMPORARY_TEXT(TEMP)
Colonies__paragraph_anchor(TEMP, P);
HTML__anchor_with_class(OUT, TEMP, TL_IS_574);
DISCARD_TEXT(TEMP)
if (P->invisible == FALSE) {
HTML_OPEN("b");
WRITE("%s%S", (Str__get_first_char(P->ornament) == 'S')?"&#167;":"&para;",
P->paragraph_number);
WRITE(". %S%s ", P->heading_text, (Str__len(P->heading_text) > 0)?".":"");
HTML_CLOSE("b");
}
}
#line 964 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__change_colour(text_stream *OUT, int col, colour_scheme *cs) {
if (col == -1) {
HTML_CLOSE("span");
} else {
char *cl = "plain";
switch (col) {
case DEFINITION_COLOUR: cl = "definition-syntax"; break;
case FUNCTION_COLOUR: cl = "function-syntax"; break;
case IDENTIFIER_COLOUR: cl = "identifier-syntax"; break;
case ELEMENT_COLOUR: cl = "element-syntax"; break;
case RESERVED_COLOUR: cl = "reserved-syntax"; break;
case STRING_COLOUR: cl = "string-syntax"; break;
case CHARACTER_COLOUR: cl = "character-syntax"; break;
case CONSTANT_COLOUR: cl = "constant-syntax"; break;
case PLAIN_COLOUR: cl = "plain-syntax"; break;
case EXTRACT_COLOUR: cl = "extract-syntax"; break;
case COMMENT_COLOUR: cl = "comment-syntax"; break;
default: PRINT("col: %d\n", col); internal_error("bad colour"); break;
}
HTML_OPEN_WITH("span", "class=\"%S%s\"", cs->prefix, cl);
}
}
#line 988 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__escape_text(text_stream *OUT, text_stream *id) {
for (int i=0; i < Str__len(id); i++) {
if (Str__get_at(id, i) == '&') WRITE("&amp;");
else if (Str__get_at(id, i) == '<') WRITE("&lt;");
else if (Str__get_at(id, i) == '>') WRITE("&gt;");
else PUT(Str__get_at(id, i));
}
}
#line 1000 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) {
TEMPORARY_TEXT(T)
WRITE_TO(T, "%S", Bibliographic__get_datum(W->md, TL_IS_575));
W->as_ebook = Epub__new(T, "P");
filename *CSS = Patterns__find_file_in_subdirectory(pattern, TL_IS_576, TL_IS_577);
Epub__use_CSS_throughout(W->as_ebook, CSS);
Epub__attach_metadata(W->as_ebook, L"identifier", T);
DISCARD_TEXT(T)
pathname *P = Reader__woven_folder(W);
W->redirect_weaves_to = Epub__begin_construction(W->as_ebook, P, NULL);
Shell__copy(CSS, W->redirect_weaves_to, "");
return SWARM_SECTIONS_SWM;
}
void HTMLFormat__end_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) {
Epub__end_construction(W->as_ebook);
}
#line 9 "inweb/Chapter 5/Debugging Format.w"
void Debugging__create(void) {
weave_format *wf = Formats__create_weave_format(TL_IS_578, TL_IS_579);
METHOD_ADD(wf, RENDER_FOR_MTID, Debugging__render);
}
#line 22 "inweb/Chapter 5/Debugging Format.w"
void Debugging__render(weave_format *self, text_stream *OUT, heterogeneous_tree *tree) {
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(tree->root->content);
debugging_render_state drs;
drs.OUT = OUT;
drs.wv = C->wv;
Trees__traverse_from(tree->root, &Debugging__render_visit, (void *) &drs, 0);
}
int Debugging__render_visit(tree_node *N, void *state, int L) {
debugging_render_state *drs = (debugging_render_state *) state;
text_stream *OUT = drs->OUT;
for (int i=0; i<L; i++) WRITE(" ");
WRITE("%S", N->type->node_type_name);
if (N->type == weave_document_node_type)
{
#line 87 "inweb/Chapter 5/Debugging Format.w"
weave_document_node *C = RETRIEVE_POINTER_weave_document_node(N->content);
WRITE(" weave order %d", C->wv->allocation_id);
}
#line 36 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_head_node_type)
{
#line 91 "inweb/Chapter 5/Debugging Format.w"
weave_head_node *C = RETRIEVE_POINTER_weave_head_node(N->content);
WRITE(" banner <%S>", C->banner);
}
#line 37 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_body_node_type)
{
#line 95 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 38 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_tail_node_type)
{
#line 98 "inweb/Chapter 5/Debugging Format.w"
weave_tail_node *C = RETRIEVE_POINTER_weave_tail_node(N->content);
WRITE(" rennab <%S>", C->rennab);
}
#line 39 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_verbatim_node_type)
{
#line 102 "inweb/Chapter 5/Debugging Format.w"
weave_verbatim_node *C = RETRIEVE_POINTER_weave_verbatim_node(N->content);
Debugging__show_text(OUT, C->content, 80);
}
#line 40 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_chapter_header_node_type)
{
#line 114 "inweb/Chapter 5/Debugging Format.w"
weave_chapter_header_node *C = RETRIEVE_POINTER_weave_chapter_header_node(N->content);
WRITE(" <%S>", C->chap->md->ch_title);
}
#line 41 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_chapter_footer_node_type)
{
#line 118 "inweb/Chapter 5/Debugging Format.w"
weave_chapter_footer_node *C = RETRIEVE_POINTER_weave_chapter_footer_node(N->content);
WRITE(" <%S>", C->chap->md->ch_title);
}
#line 42 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_section_header_node_type)
{
#line 106 "inweb/Chapter 5/Debugging Format.w"
weave_section_header_node *C = RETRIEVE_POINTER_weave_section_header_node(N->content);
WRITE(" <%S>", C->sect->md->sect_title);
}
#line 43 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_section_footer_node_type)
{
#line 110 "inweb/Chapter 5/Debugging Format.w"
weave_section_footer_node *C = RETRIEVE_POINTER_weave_section_footer_node(N->content);
WRITE(" <%S>", C->sect->md->sect_title);
}
#line 44 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_section_purpose_node_type)
{
#line 122 "inweb/Chapter 5/Debugging Format.w"
weave_section_purpose_node *C = RETRIEVE_POINTER_weave_section_purpose_node(N->content);
WRITE(" <%S>", C->purpose);
}
#line 45 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_subheading_node_type)
{
#line 126 "inweb/Chapter 5/Debugging Format.w"
weave_subheading_node *C = RETRIEVE_POINTER_weave_subheading_node(N->content);
WRITE(" <%S>", C->text);
}
#line 46 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_bar_node_type)
{
#line 130 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 47 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_pagebreak_node_type)
{
#line 133 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 48 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_linebreak_node_type)
{
#line 136 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 49 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_paragraph_heading_node_type)
{
#line 139 "inweb/Chapter 5/Debugging Format.w"
weave_paragraph_heading_node *C = RETRIEVE_POINTER_weave_paragraph_heading_node(N->content);
Debugging__show_para(OUT, C->para);
if (C->no_skip) WRITE(" (no skip)");
}
#line 50 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_endnote_node_type)
{
#line 144 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 51 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_figure_node_type)
{
#line 147 "inweb/Chapter 5/Debugging Format.w"
weave_figure_node *C = RETRIEVE_POINTER_weave_figure_node(N->content);
WRITE(" <%S> %d by %d", C->figname, C->w, C->h);
}
#line 52 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_audio_node_type)
{
#line 151 "inweb/Chapter 5/Debugging Format.w"
weave_audio_node *C = RETRIEVE_POINTER_weave_audio_node(N->content);
WRITE(" <%S> %d", C->audio_name, C->w);
}
#line 53 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_video_node_type)
{
#line 155 "inweb/Chapter 5/Debugging Format.w"
weave_video_node *C = RETRIEVE_POINTER_weave_video_node(N->content);
WRITE(" <%S> %d", C->video_name, C->w);
}
#line 54 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_download_node_type)
{
#line 159 "inweb/Chapter 5/Debugging Format.w"
weave_download_node *C = RETRIEVE_POINTER_weave_download_node(N->content);
WRITE(" <%S> %S", C->download_name, C->filetype);
}
#line 55 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_material_node_type)
{
#line 163 "inweb/Chapter 5/Debugging Format.w"
weave_material_node *C = RETRIEVE_POINTER_weave_material_node(N->content);
WRITE(" ");
Debugging__show_mat(OUT, C->material_type);
if (C->material_type == CODE_MATERIAL) WRITE(": %S", C->styling->language_name);
if (C->plainly) WRITE(" (plainly)");
}
#line 56 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_embed_node_type)
{
#line 170 "inweb/Chapter 5/Debugging Format.w"
weave_embed_node *C = RETRIEVE_POINTER_weave_embed_node(N->content);
WRITE(" service <%S> ID <%S> %d by %d", C->service, C->ID, C->w, C->h);
}
#line 57 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_pmac_node_type)
{
#line 174 "inweb/Chapter 5/Debugging Format.w"
weave_pmac_node *C = RETRIEVE_POINTER_weave_pmac_node(N->content);
WRITE(" <%S>", C->pmac->macro_name);
if (C->defn) WRITE(" (definition)");
}
#line 58 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_vskip_node_type)
{
#line 179 "inweb/Chapter 5/Debugging Format.w"
weave_vskip_node *C = RETRIEVE_POINTER_weave_vskip_node(N->content);
if (C->in_comment) WRITE(" (in comment)");
}
#line 59 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_chapter_node_type)
{
#line 183 "inweb/Chapter 5/Debugging Format.w"
weave_chapter_node *C = RETRIEVE_POINTER_weave_chapter_node(N->content);
WRITE(" <%S>", C->chap->md->ch_title);
}
#line 60 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_section_node_type)
{
#line 187 "inweb/Chapter 5/Debugging Format.w"
weave_section_node *C = RETRIEVE_POINTER_weave_section_node(N->content);
WRITE(" <%S>", C->sect->md->sect_title);
}
#line 61 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_code_line_node_type)
{
#line 191 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 62 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_function_usage_node_type)
{
#line 194 "inweb/Chapter 5/Debugging Format.w"
weave_function_usage_node *C = RETRIEVE_POINTER_weave_function_usage_node(N->content);
WRITE(" <%S>", C->fn->function_name);
}
#line 63 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_commentary_node_type)
{
#line 198 "inweb/Chapter 5/Debugging Format.w"
weave_commentary_node *C = RETRIEVE_POINTER_weave_commentary_node(N->content);
Debugging__show_text(OUT, C->text, 80);
if (C->in_code) WRITE(" (code)");
}
#line 64 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_carousel_slide_node_type)
{
#line 203 "inweb/Chapter 5/Debugging Format.w"
weave_carousel_slide_node *C = RETRIEVE_POINTER_weave_carousel_slide_node(N->content);
WRITE(" caption <%S>", C->caption);
}
#line 65 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_toc_node_type)
{
#line 207 "inweb/Chapter 5/Debugging Format.w"
weave_toc_node *C = RETRIEVE_POINTER_weave_toc_node(N->content);
WRITE(" - <%S>", C->text1);
}
#line 66 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_toc_line_node_type)
{
#line 211 "inweb/Chapter 5/Debugging Format.w"
weave_toc_line_node *C = RETRIEVE_POINTER_weave_toc_line_node(N->content);
WRITE(" - <%S, %S>", C->text1, C->text2);
if (C->para) Debugging__show_para(OUT, C->para);
}
#line 67 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_chapter_title_page_node_type)
{
#line 216 "inweb/Chapter 5/Debugging Format.w"
weave_chapter_title_page_node *C = RETRIEVE_POINTER_weave_chapter_title_page_node(N->content);
WRITE(" - something %d", C->allocation_id);
}
#line 68 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_defn_node_type)
{
#line 220 "inweb/Chapter 5/Debugging Format.w"
weave_defn_node *C = RETRIEVE_POINTER_weave_defn_node(N->content);
WRITE(" <%S>", C->keyword);
}
#line 69 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_source_code_node_type)
{
#line 224 "inweb/Chapter 5/Debugging Format.w"
weave_source_code_node *C = RETRIEVE_POINTER_weave_source_code_node(N->content);
WRITE(" <%S>\n", C->matter);
for (int i=0; i<L; i++) WRITE(" ");
WRITE(" ");
WRITE(" _%S_", C->colouring);
}
#line 70 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_url_node_type)
{
#line 231 "inweb/Chapter 5/Debugging Format.w"
weave_url_node *C = RETRIEVE_POINTER_weave_url_node(N->content);
WRITE(" content <%S> url <%S>", C->content, C->url);
}
#line 71 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_footnote_cue_node_type)
{
#line 235 "inweb/Chapter 5/Debugging Format.w"
weave_footnote_cue_node *C = RETRIEVE_POINTER_weave_footnote_cue_node(N->content);
WRITE(" [%S]", C->cue_text);
}
#line 72 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_begin_footnote_text_node_type)
{
#line 239 "inweb/Chapter 5/Debugging Format.w"
weave_begin_footnote_text_node *C = RETRIEVE_POINTER_weave_begin_footnote_text_node(N->content);
WRITE(" [%S]", C->cue_text);
}
#line 73 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_display_line_node_type)
{
#line 243 "inweb/Chapter 5/Debugging Format.w"
weave_display_line_node *C = RETRIEVE_POINTER_weave_display_line_node(N->content);
WRITE(" <%S>", C->text);
}
#line 74 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_function_defn_node_type)
{
#line 247 "inweb/Chapter 5/Debugging Format.w"
weave_function_defn_node *C = RETRIEVE_POINTER_weave_function_defn_node(N->content);
WRITE(" <%S>", C->fn->function_name);
}
#line 75 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_item_node_type)
{
#line 251 "inweb/Chapter 5/Debugging Format.w"
weave_item_node *C = RETRIEVE_POINTER_weave_item_node(N->content);
WRITE(" depth %d label <%S>", C->depth, C->label);
}
#line 76 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_grammar_index_node_type)
{
#line 255 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 77 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_inline_node_type)
{
#line 258 "inweb/Chapter 5/Debugging Format.w"
;
}
#line 78 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_locale_node_type)
{
#line 261 "inweb/Chapter 5/Debugging Format.w"
weave_locale_node *C = RETRIEVE_POINTER_weave_locale_node(N->content);
Debugging__show_para(OUT, C->par1);
if (C->par2) {
WRITE(" to ");
Debugging__show_para(OUT, C->par2);
}
}
#line 79 "inweb/Chapter 5/Debugging Format.w"
else if (N->type == weave_maths_node_type)
{
#line 269 "inweb/Chapter 5/Debugging Format.w"
weave_maths_node *C = RETRIEVE_POINTER_weave_maths_node(N->content);
WRITE(" <%S>", C->content);
if (C->displayed) WRITE(" (displayed)");
}
#line 80 "inweb/Chapter 5/Debugging Format.w"
else WRITE("Unknown node");
WRITE("\n");
return TRUE;
}
#line 274 "inweb/Chapter 5/Debugging Format.w"
void Debugging__show_text(text_stream *OUT, text_stream *text, int limit) {
WRITE(" <");
for (int i=0; (i<limit) && (i<Str__len(text)); i++)
if (Str__get_at(text, i) == '\n')
WRITE("\\n");
else
PUT(Str__get_at(text, i));
WRITE(">");
if (Str__len(text) > limit) WRITE(" ... continues to %d chars", Str__len(text));
}
void Debugging__show_para(text_stream *OUT, paragraph *P) {
WRITE(" P%S", P->paragraph_number);
if (Str__len(P->heading_text) > 0) WRITE("'%S'", P->heading_text);
}
void Debugging__show_mat(text_stream *OUT, int m) {
switch (m) {
case COMMENTARY_MATERIAL: WRITE("discussion"); break;
case MACRO_MATERIAL: WRITE("paragraph macro"); break;
case DEFINITION_MATERIAL: WRITE("definition"); break;
case CODE_MATERIAL: WRITE("code"); break;
case ENDNOTES_MATERIAL: WRITE("endnotes"); break;
case FOOTNOTES_MATERIAL: WRITE("footnotes"); break;
default: WRITE("unknown"); break;
}
}
#line 28 "inweb/Chapter 5/TeX Utilities.w"
#line 30 "inweb/Chapter 5/TeX Utilities.w"
tex_results *TeXUtilities__new_results(weave_order *wv, filename *CF) {
tex_results *res = CREATE(tex_results);
res->overfull_hbox_count = 0;
res->tex_error_count = 0;
res->page_count = 0;
res->pdf_size = 0;
res->PDF_filename = Filenames__set_extension(CF, TL_IS_580);
return res;
}
#line 44 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__post_process_weave(weave_order *wv, filename *CF) {
wv->post_processing_results = TeXUtilities__new_results(wv, CF);
TextFiles__read(CF, FALSE,
"can't open console file", TRUE, TeXUtilities__scan_console_line, NULL,
(void *) wv->post_processing_results);
}
#line 52 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__scan_console_line(text_stream *line, text_file_position *tfp,
void *res_V) {
tex_results *res = (tex_results *) res_V;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line,
L"Output written %c*? %((%d+) page%c*?(%d+) bytes%).")) {
res->page_count = Str__atoi(mr.exp[0], 0);
res->pdf_size = Str__atoi(mr.exp[1], 0);
}
if (Regexp__match(&mr, line, L"%c+verfull \\hbox%c+"))
res->overfull_hbox_count++;
else if (Str__get_first_char(line) == '!') {
res->tex_error_count++;
}
Regexp__dispose_of(&mr);
}
#line 72 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__report_on_post_processing(weave_order *wv) {
tex_results *res = wv->post_processing_results;
if (res) {
PRINT(": %dpp %dK", res->page_count, res->pdf_size/1024);
if (res->overfull_hbox_count > 0)
PRINT(", %d overfull hbox(es)", res->overfull_hbox_count);
if (res->tex_error_count > 0)
PRINT(", %d error(s)", res->tex_error_count);
}
}
#line 86 "inweb/Chapter 5/TeX Utilities.w"
int TeXUtilities__substitute_post_processing_data(text_stream *to, weave_order *wv,
text_stream *detail) {
if (wv) {
tex_results *res = wv->post_processing_results;
if (res) {
if (Str__eq_wide_string(detail, L"PDF Size")) {
WRITE_TO(to, "%dKB", res->pdf_size/1024);
} else if (Str__eq_wide_string(detail, L"Extent")) {
WRITE_TO(to, "%dpp", res->page_count);
} else if (Str__eq_wide_string(detail, L"Leafname")) {
Str__copy(to, Filenames__get_leafname(res->PDF_filename));
} else if (Str__eq_wide_string(detail, L"Errors")) {
Str__clear(to);
if ((res->overfull_hbox_count > 0) || (res->tex_error_count > 0))
WRITE_TO(to, ": ");
if (res->overfull_hbox_count > 0)
WRITE_TO(to, "%d overfull line%s",
res->overfull_hbox_count,
(res->overfull_hbox_count>1)?"s":"");
if ((res->overfull_hbox_count > 0) && (res->tex_error_count > 0))
WRITE_TO(to, ", ");
if (res->tex_error_count > 0)
WRITE_TO(to, "%d TeX error%s",
res->tex_error_count,
(res->tex_error_count>1)?"s":"");
} else return FALSE;
return TRUE;
}
}
return FALSE;
}
#line 126 "inweb/Chapter 5/TeX Utilities.w"
void TeXUtilities__remove_math_mode(OUTPUT_STREAM, text_stream *text) {
TEMPORARY_TEXT(math_matter)
TeXUtilities__remove_math_mode_range(math_matter, text, 0, Str__len(text)-1);
WRITE("%S", math_matter);
DISCARD_TEXT(math_matter)
}
void TeXUtilities__remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) {
for (int i=from; i <= to; i++) {
{
#line 157 "inweb/Chapter 5/TeX Utilities.w"
if ((Str__get_at(text, i) == '\\') &&
(Str__get_at(text, i+1) == 'o') && (Str__get_at(text, i+2) == 'v') &&
(Str__get_at(text, i+3) == 'e') && (Str__get_at(text, i+4) == 'r') &&
(Str__get_at(text, i+5) == '{')) {
int bl = 1;
int j = i-1;
for (; j >= from; j--) {
wchar_t c = Str__get_at(text, j);
if (c == '{') {
bl--;
if (bl == 0) break;
}
if (c == '}') bl++;
}
TeXUtilities__remove_math_mode_range(OUT, text, from, j-1);
WRITE("((");
TeXUtilities__remove_math_mode_range(OUT, text, j+2, i-2);
WRITE(") / (");
j=i+6; bl = 1;
for (; j <= to; j++) {
wchar_t c = Str__get_at(text, j);
if (c == '}') {
bl--;
if (bl == 0) break;
}
if (c == '{') bl++;
}
TeXUtilities__remove_math_mode_range(OUT, text, i+6, j-1);
WRITE("))");
TeXUtilities__remove_math_mode_range(OUT, text, j+2, to);
return;
}
}
#line 135 "inweb/Chapter 5/TeX Utilities.w"
;
}
for (int i=from; i <= to; i++) {
{
#line 193 "inweb/Chapter 5/TeX Utilities.w"
if ((Str__get_at(text, i) == '{') && (Str__get_at(text, i+1) == '\\') &&
(((Str__get_at(text, i+2) == 'r') && (Str__get_at(text, i+3) == 'm')) ||
((Str__get_at(text, i+2) == 'i') && (Str__get_at(text, i+3) == 't'))) &&
(Str__get_at(text, i+4) == ' ')) {
TeXUtilities__remove_math_mode_range(OUT, text, from, i-1);
int j=i+5;
for (; j <= to; j++)
if (Str__get_at(text, j) == '}')
break;
TeXUtilities__remove_math_mode_range(OUT, text, i+5, j-1);
TeXUtilities__remove_math_mode_range(OUT, text, j+1, to);
return;
}
}
#line 138 "inweb/Chapter 5/TeX Utilities.w"
;
{
#line 211 "inweb/Chapter 5/TeX Utilities.w"
if ((Str__get_at(text, i) == '\\') &&
(Str__get_at(text, i+1) == 's') && (Str__get_at(text, i+2) == 'q') &&
(Str__get_at(text, i+3) == 'r') && (Str__get_at(text, i+4) == 't') &&
(Str__get_at(text, i+5) == '{')) {
if ((Str__get_at(text, i-4) == '{') &&
(Str__get_at(text, i-3) == '}') &&
(Str__get_at(text, i-2) == '^') &&
(Str__get_at(text, i-1) == '3')) {
TeXUtilities__remove_math_mode_range(OUT, text, from, i-5);
WRITE(" curt(");
} else {
TeXUtilities__remove_math_mode_range(OUT, text, from, i-1);
WRITE(" sqrt(");
}
int j=i+6, bl = 1;
for (; j <= to; j++) {
wchar_t c = Str__get_at(text, j);
if (c == '}') {
bl--;
if (bl == 0) break;
}
if (c == '{') bl++;
}
TeXUtilities__remove_math_mode_range(OUT, text, i+6, j-1);
WRITE(")");
TeXUtilities__remove_math_mode_range(OUT, text, j+1, to);
return;
}
}
#line 139 "inweb/Chapter 5/TeX Utilities.w"
;
}
int math_mode = FALSE;
for (int i=from; i <= to; i++) {
switch (Str__get_at(text, i)) {
case '$':
if (Str__get_at(text, i+1) == '$') i++;
math_mode = (math_mode)?FALSE:TRUE; break;
case '~': if (math_mode) WRITE(" "); else WRITE("~"); break;
case '\\':
{
#line 241 "inweb/Chapter 5/TeX Utilities.w"
TEMPORARY_TEXT(macro)
i++;
while ((i < Str__len(text)) && (Characters__isalpha(Str__get_at(text, i))))
PUT_TO(macro, Str__get_at(text, i++));
if (Str__eq(macro, TL_IS_581))
{
#line 364 "inweb/Chapter 5/TeX Utilities.w"
if (Str__get_at(text, i) == '\\') {
Str__clear(macro);
i++;
while ((i < Str__len(text)) && (Characters__isalpha(Str__get_at(text, i))))
PUT_TO(macro, Str__get_at(text, i++));
if (Str__eq(macro, TL_IS_677)) PUT((wchar_t) 0x2204);
else if (Str__eq(macro, TL_IS_678)) { PUT((wchar_t) 0x00AC); PUT((wchar_t) 0x2200); }
else {
PRINT("Don't know how to apply '\\not' to '\\%S'\n", macro);
}
} else {
PRINT("Don't know how to apply '\\not' here\n");
}
}
#line 245 "inweb/Chapter 5/TeX Utilities.w"
else
{
#line 251 "inweb/Chapter 5/TeX Utilities.w"
if (Str__eq(macro, TL_IS_582)) WRITE("<=");
else if (Str__eq(macro, TL_IS_583)) WRITE(">=");
else if (Str__eq(macro, TL_IS_584)) WRITE("~");
else if (Str__eq(macro, TL_IS_585)) WRITE("");
else if (Str__eq(macro, TL_IS_586)) WRITE("");
else if (Str__eq(macro, TL_IS_587)) WRITE("");
else if (Str__eq(macro, TL_IS_588)) WRITE("=>");
else if (Str__eq(macro, TL_IS_589)) WRITE("<=>");
else if (Str__eq(macro, TL_IS_590)) WRITE("-->");
else if (Str__eq(macro, TL_IS_591)) WRITE("-->");
else if (Str__eq(macro, TL_IS_592)) WRITE("-->");
else if (Str__eq(macro, TL_IS_593)) WRITE("<--");
else if (Str__eq(macro, TL_IS_594)) WRITE("<--");
else if (Str__eq(macro, TL_IS_595)) WRITE("{");
else if (Str__eq(macro, TL_IS_596)) WRITE("|");
else if (Str__eq(macro, TL_IS_597)) WRITE("}");
else if (Str__eq(macro, TL_IS_598)) WRITE(".");
else if (Str__eq(macro, TL_IS_599)) WRITE("...");
else if (Str__eq(macro, TL_IS_600)) WRITE("...");
else if (Str__eq(macro, TL_IS_601)) WRITE("*");
else if (Str__eq(macro, TL_IS_602)) WRITE(" ");
else if (Str__eq(macro, TL_IS_603)) WRITE(" ");
else if (Str__eq(macro, TL_IS_604)) WRITE("TeX");
else if (Str__eq(macro, TL_IS_605)) WRITE("!=");
else if (Str__eq(macro, TL_IS_606)) WRITE("!=");
else if (Str__eq(macro, TL_IS_607)) WRITE("l");
else if (Str__eq(macro, TL_IS_608)) WRITE("log");
else if (Str__eq(macro, TL_IS_609)) WRITE("exp");
else if (Str__eq(macro, TL_IS_610)) WRITE("sin");
else if (Str__eq(macro, TL_IS_611)) WRITE("cos");
else if (Str__eq(macro, TL_IS_612)) WRITE("tan");
else if (Str__eq(macro, TL_IS_613)) WRITE("T");
else if (Str__eq(macro, TL_IS_614)) PUT((wchar_t) 0x0391);
else if (Str__eq(macro, TL_IS_615)) PUT((wchar_t) 0x0392);
else if (Str__eq(macro, TL_IS_616)) PUT((wchar_t) 0x0393);
else if (Str__eq(macro, TL_IS_617)) PUT((wchar_t) 0x0394);
else if (Str__eq(macro, TL_IS_618)) PUT((wchar_t) 0x0395);
else if (Str__eq(macro, TL_IS_619)) PUT((wchar_t) 0x0396);
else if (Str__eq(macro, TL_IS_620)) PUT((wchar_t) 0x0397);
else if (Str__eq(macro, TL_IS_621)) PUT((wchar_t) 0x0398);
else if (Str__eq(macro, TL_IS_622)) PUT((wchar_t) 0x0399);
else if (Str__eq(macro, TL_IS_623)) PUT((wchar_t) 0x039A);
else if (Str__eq(macro, TL_IS_624)) PUT((wchar_t) 0x039B);
else if (Str__eq(macro, TL_IS_625)) PUT((wchar_t) 0x039C);
else if (Str__eq(macro, TL_IS_626)) PUT((wchar_t) 0x039D);
else if (Str__eq(macro, TL_IS_627)) PUT((wchar_t) 0x039E);
else if (Str__eq(macro, TL_IS_628)) PUT((wchar_t) 0x039F);
else if (Str__eq(macro, TL_IS_629)) PUT((wchar_t) 0x03A0);
else if (Str__eq(macro, TL_IS_630)) PUT((wchar_t) 0x03A1);
else if (Str__eq(macro, TL_IS_631)) PUT((wchar_t) 0x03A2);
else if (Str__eq(macro, TL_IS_632)) PUT((wchar_t) 0x03A3);
else if (Str__eq(macro, TL_IS_633)) PUT((wchar_t) 0x03A4);
else if (Str__eq(macro, TL_IS_634)) PUT((wchar_t) 0x03A5);
else if (Str__eq(macro, TL_IS_635)) PUT((wchar_t) 0x03A6);
else if (Str__eq(macro, TL_IS_636)) PUT((wchar_t) 0x03A7);
else if (Str__eq(macro, TL_IS_637)) PUT((wchar_t) 0x03A8);
else if (Str__eq(macro, TL_IS_638)) PUT((wchar_t) 0x03A9);
else if (Str__eq(macro, TL_IS_639)) PUT((wchar_t) 0x03B1);
else if (Str__eq(macro, TL_IS_640)) PUT((wchar_t) 0x03B2);
else if (Str__eq(macro, TL_IS_641)) PUT((wchar_t) 0x03B3);
else if (Str__eq(macro, TL_IS_642)) PUT((wchar_t) 0x03B4);
else if (Str__eq(macro, TL_IS_643)) PUT((wchar_t) 0x03B5);
else if (Str__eq(macro, TL_IS_644)) PUT((wchar_t) 0x03B6);
else if (Str__eq(macro, TL_IS_645)) PUT((wchar_t) 0x03B7);
else if (Str__eq(macro, TL_IS_646)) PUT((wchar_t) 0x03B8);
else if (Str__eq(macro, TL_IS_647)) PUT((wchar_t) 0x03B9);
else if (Str__eq(macro, TL_IS_648)) PUT((wchar_t) 0x03BA);
else if (Str__eq(macro, TL_IS_649)) PUT((wchar_t) 0x03BB);
else if (Str__eq(macro, TL_IS_650)) PUT((wchar_t) 0x03BC);
else if (Str__eq(macro, TL_IS_651)) PUT((wchar_t) 0x03BD);
else if (Str__eq(macro, TL_IS_652)) PUT((wchar_t) 0x03BE);
else if (Str__eq(macro, TL_IS_653)) PUT((wchar_t) 0x03BF);
else if (Str__eq(macro, TL_IS_654)) PUT((wchar_t) 0x03C0);
else if (Str__eq(macro, TL_IS_655)) PUT((wchar_t) 0x03C1);
else if (Str__eq(macro, TL_IS_656)) PUT((wchar_t) 0x03C2);
else if (Str__eq(macro, TL_IS_657)) PUT((wchar_t) 0x03C3);
else if (Str__eq(macro, TL_IS_658)) PUT((wchar_t) 0x03C4);
else if (Str__eq(macro, TL_IS_659)) PUT((wchar_t) 0x03C5);
else if (Str__eq(macro, TL_IS_660)) PUT((wchar_t) 0x03C6);
else if (Str__eq(macro, TL_IS_661)) PUT((wchar_t) 0x03C7);
else if (Str__eq(macro, TL_IS_662)) PUT((wchar_t) 0x03C8);
else if (Str__eq(macro, TL_IS_663)) PUT((wchar_t) 0x03C9);
else if (Str__eq(macro, TL_IS_664)) PUT((wchar_t) 0x2203);
else if (Str__eq(macro, TL_IS_665)) PUT((wchar_t) 0x2208);
else if (Str__eq(macro, TL_IS_666)) PUT((wchar_t) 0x2200);
else if (Str__eq(macro, TL_IS_667)) PUT((wchar_t) 0x2229);
else if (Str__eq(macro, TL_IS_668)) PUT((wchar_t) 0x2205);
else if (Str__eq(macro, TL_IS_669)) PUT((wchar_t) 0x2286);
else if (Str__eq(macro, TL_IS_670)) PUT((wchar_t) 0x2227);
else if (Str__eq(macro, TL_IS_671)) PUT((wchar_t) 0x2228);
else if (Str__eq(macro, TL_IS_672)) PUT((wchar_t) 0x00AC);
else if (Str__eq(macro, TL_IS_673)) PUT((wchar_t) 0x03A3);
else if (Str__eq(macro, TL_IS_674)) PUT((wchar_t) 0x03A0);
else {
if (Str__len(macro) > 0) {
int suspect = TRUE;
LOOP_THROUGH_TEXT(pos, macro) {
wchar_t c = Str__get(pos);
if ((c >= 'A') && (c <= 'Z')) continue;
if ((c >= 'a') && (c <= 'z')) continue;
suspect = FALSE;
}
if (Str__eq(macro, TL_IS_675)) suspect = FALSE;
if (Str__eq(macro, TL_IS_676)) suspect = FALSE;
if (suspect)
PRINT("[Passing through unknown TeX macro \\%S:\n %S\n", macro, text);
}
WRITE("\\%S", macro);
}
}
#line 246 "inweb/Chapter 5/TeX Utilities.w"
;
DISCARD_TEXT(macro)
i--;
}
#line 148 "inweb/Chapter 5/TeX Utilities.w"
; break;
default: PUT(Str__get_at(text, i)); break;
}
}
}
#line 12 "inweb/Chapter 6/Makefiles.w"
void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I,
text_stream *platform) {
linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
Preprocessor__new_macro(L,
TL_IS_679, NULL,
Makefiles__platform_settings_expander, NULL);
Preprocessor__new_macro(L,
TL_IS_680, NULL,
Makefiles__identity_settings_expander, NULL);
preprocessor_macro *mf = Preprocessor__new_macro(L,
TL_IS_681, TL_IS_682,
Makefiles__modify_filenames_expander, NULL);
Preprocessor__do_not_suppress_whitespace(mf);
Preprocessor__new_macro(L,
TL_IS_683, TL_IS_684,
Makefiles__component_expander, NULL);
Preprocessor__new_macro(L,
TL_IS_685, TL_IS_686,
Makefiles__dependent_files_expander, NULL);
Preprocessor__new_loop_macro(L,
TL_IS_687, TL_IS_688,
Makefiles__components_expander, NULL);
makefile_specifics *specifics = CREATE(makefile_specifics);
{
#line 62 "inweb/Chapter 6/Makefiles.w"
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;
specifics->which_platform = platform;
}
#line 36 "inweb/Chapter 6/Makefiles.w"
;
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);
Preprocessor__preprocess(prototype, F, header, L,
STORE_POINTER_makefile_specifics(specifics), '#', ISO_ENC);
}
#line 60 "inweb/Chapter 6/Makefiles.w"
#line 72 "inweb/Chapter 6/Makefiles.w"
void Makefiles__identity_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, 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), TL_IS_689);
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;
}
}
#line 94 "inweb/Chapter 6/Makefiles.w"
void Makefiles__platform_settings_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics);
text_stream *INWEBPLATFORM = Str__duplicate(specifics->which_platform);
if (Str__len(INWEBPLATFORM) == 0) {
filename *ps = Filenames__in(path_to_inweb, TL_IS_690);
TextFiles__read(ps, 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, TL_IS_691);
P = Pathnames__down(P, TL_IS_692);
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__seek_INWEBPLATFORM(text_stream *line, text_file_position *tfp, void *X) {
text_stream *OUT = (text_stream *) X;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L" *INWEBPLATFORM = (%C+) *")) WRITE("%S", mr.exp[0]);
Regexp__dispose_of(&mr);
}
#line 129 "inweb/Chapter 6/Makefiles.w"
void Makefiles__modify_filenames_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
text_stream *OUT = PPS->dest;
text_stream *original = parameter_values[0];
text_stream *suffix = parameter_values[1];
text_stream *prefix = parameter_values[2];
wchar_t previous = 'X'; int quoted = FALSE, boundary = FALSE;
TEMPORARY_TEXT(captured)
LOOP_THROUGH_TEXT(pos, original) {
wchar_t c = Str__get(pos);
if (c == '\'') { quoted = quoted?FALSE:TRUE; }
if (Characters__is_whitespace(c)) {
if ((previous != '\\') && (quoted == FALSE)) boundary = TRUE;
} else {
if (boundary)
{
#line 156 "inweb/Chapter 6/Makefiles.w"
Str__trim_white_space(captured);
if (Str__len(captured) > 0) {
int in_quotes = FALSE;
if ((Str__get_first_char(captured) == '\'') && (Str__get_last_char(captured) == '\'')) {
Str__delete_first_character(captured);
Str__delete_last_character(captured);
in_quotes = TRUE;
}
if (in_quotes) WRITE("'");
int last_slash = -1;
for (int i=0; i<Str__len(captured); i++)
if (Str__get_at(captured, i) == '/')
last_slash = i;
int last_dot = Str__len(captured);
for (int i=last_slash+1; i<Str__len(captured); i++)
if (Str__get_at(captured, i) == '.')
last_dot = i;
for (int i=0; i<=last_slash; i++) PUT(Str__get_at(captured, i));
WRITE("%S", prefix);
for (int i=last_slash+1; i<last_dot; i++) PUT(Str__get_at(captured, i));
WRITE("%S", suffix);
for (int i=last_dot; i<Str__len(captured); i++) PUT(Str__get_at(captured, i));
if (in_quotes) WRITE("'");
Str__clear(captured);
}
}
#line 145 "inweb/Chapter 6/Makefiles.w"
;
boundary = FALSE;
}
PUT_TO(captured, c);
previous = c;
}
{
#line 156 "inweb/Chapter 6/Makefiles.w"
Str__trim_white_space(captured);
if (Str__len(captured) > 0) {
int in_quotes = FALSE;
if ((Str__get_first_char(captured) == '\'') && (Str__get_last_char(captured) == '\'')) {
Str__delete_first_character(captured);
Str__delete_last_character(captured);
in_quotes = TRUE;
}
if (in_quotes) WRITE("'");
int last_slash = -1;
for (int i=0; i<Str__len(captured); i++)
if (Str__get_at(captured, i) == '/')
last_slash = i;
int last_dot = Str__len(captured);
for (int i=last_slash+1; i<Str__len(captured); i++)
if (Str__get_at(captured, i) == '.')
last_dot = i;
for (int i=0; i<=last_slash; i++) PUT(Str__get_at(captured, i));
WRITE("%S", prefix);
for (int i=last_slash+1; i<last_dot; i++) PUT(Str__get_at(captured, i));
WRITE("%S", suffix);
for (int i=last_dot; i<Str__len(captured); i++) PUT(Str__get_at(captured, i));
if (in_quotes) WRITE("'");
Str__clear(captured);
}
}
#line 151 "inweb/Chapter 6/Makefiles.w"
DISCARD_TEXT(captured)
}
#line 185 "inweb/Chapter 6/Makefiles.w"
void Makefiles__component_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics);
text_stream *OUT = PPS->dest;
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];
if (Str__eq(category, TL_IS_693)) {
int marker = MAKEFILE_TOOL_MOM;
dictionary *D = specifics->tools_dictionary;
{
#line 218 "inweb/Chapter 6/Makefiles.w"
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);
}
#line 199 "inweb/Chapter 6/Makefiles.w"
;
{
#line 227 "inweb/Chapter 6/Makefiles.w"
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);
}
#line 200 "inweb/Chapter 6/Makefiles.w"
;
} else if (Str__eq(category, TL_IS_694)) {
int marker = MAKEFILE_WEB_MOM;
dictionary *D = specifics->webs_dictionary;
{
#line 218 "inweb/Chapter 6/Makefiles.w"
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);
}
#line 204 "inweb/Chapter 6/Makefiles.w"
;
{
#line 227 "inweb/Chapter 6/Makefiles.w"
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);
}
#line 205 "inweb/Chapter 6/Makefiles.w"
;
} else if (Str__eq(category, TL_IS_695)) {
int marker = MAKEFILE_MODULE_MOM;
dictionary *D = specifics->modules_dictionary;
{
#line 218 "inweb/Chapter 6/Makefiles.w"
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);
}
#line 209 "inweb/Chapter 6/Makefiles.w"
;
{
#line 227 "inweb/Chapter 6/Makefiles.w"
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);
}
#line 210 "inweb/Chapter 6/Makefiles.w"
;
} else {
Errors__in_text_file("category should be 'tool', 'module' or 'web'", tfp);
}
PPS->last_line_was_blank = FALSE;
}
#line 235 "inweb/Chapter 6/Makefiles.w"
void Makefiles__components_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
Preprocessor__set_loop_var_name(loop, TL_IS_696);
text_stream *category = parameter_values[0];
text_stream *set = parameter_values[1];
if (Str__len(set) == 0) set = TL_IS_697;
if (Str__eq(category, TL_IS_698)) {
int marker = MAKEFILE_TOOL_MOM;
{
#line 256 "inweb/Chapter 6/Makefiles.w"
module *M;
LOOP_OVER(M, module) {
if ((M->origin_marker == marker) &&
((Str__eq(set, TL_IS_701)) || (Str__eq(set, M->module_tag)))) {
text_stream *value = M->module_name;
Preprocessor__add_loop_iteration(loop, value);
}
}
}
#line 243 "inweb/Chapter 6/Makefiles.w"
;
} else if (Str__eq(category, TL_IS_699)) {
int marker = MAKEFILE_WEB_MOM;
{
#line 256 "inweb/Chapter 6/Makefiles.w"
module *M;
LOOP_OVER(M, module) {
if ((M->origin_marker == marker) &&
((Str__eq(set, TL_IS_701)) || (Str__eq(set, M->module_tag)))) {
text_stream *value = M->module_name;
Preprocessor__add_loop_iteration(loop, value);
}
}
}
#line 246 "inweb/Chapter 6/Makefiles.w"
;
} else if (Str__eq(category, TL_IS_700)) {
int marker = MAKEFILE_MODULE_MOM;
{
#line 256 "inweb/Chapter 6/Makefiles.w"
module *M;
LOOP_OVER(M, module) {
if ((M->origin_marker == marker) &&
((Str__eq(set, TL_IS_701)) || (Str__eq(set, M->module_tag)))) {
text_stream *value = M->module_name;
Preprocessor__add_loop_iteration(loop, value);
}
}
}
#line 249 "inweb/Chapter 6/Makefiles.w"
;
} else {
Errors__in_text_file("category should be 'tool', 'module' or 'web'", tfp);
}
}
#line 268 "inweb/Chapter 6/Makefiles.w"
void Makefiles__dependent_files_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
makefile_specifics *specifics = RETRIEVE_POINTER_makefile_specifics(PPS->specifics);
text_stream *OUT = PPS->dest;
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 {
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(specifics->modules_dictionary, modules)) {
web_md *Wm = Dictionaries__read_value(specifics->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(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;
}
#line 324 "inweb/Chapter 6/Makefiles.w"
void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) {
dictionary *patterns_done = Dictionaries__new(16, TRUE);
if (F)
{
#line 335 "inweb/Chapter 6/Makefiles.w"
pathname *P = Filenames__up(F);
TEMPORARY_TEXT(leaf_pattern)
WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P));
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, leaf_pattern, L"Chapter %d*")) {
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Chapter*");
} else if (Regexp__match(&mr, leaf_pattern, L"Appendix %C")) {
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Appendix*");
}
Regexp__dispose_of(&mr);
TEMPORARY_TEXT(tester)
WRITE_TO(tester, "%p/%S/*", Pathnames__up(P), leaf_pattern);
DISCARD_TEXT(leaf_pattern)
Filenames__write_extension(tester, F);
if (Dictionaries__find(patterns_done, tester) == NULL) {
WRITE_TO(Dictionaries__create_text(patterns_done, tester), "got this");
WRITE(" ");
LOOP_THROUGH_TEXT(pos, tester) {
wchar_t c = Str__get(pos);
if (c == ' ') PUT('\\');
PUT(c);
}
}
DISCARD_TEXT(tester)
}
#line 326 "inweb/Chapter 6/Makefiles.w"
;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Sm, section_md, L) {
filename *F = Sm->source_file_for_section;
{
#line 335 "inweb/Chapter 6/Makefiles.w"
pathname *P = Filenames__up(F);
TEMPORARY_TEXT(leaf_pattern)
WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P));
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, leaf_pattern, L"Chapter %d*")) {
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Chapter*");
} else if (Regexp__match(&mr, leaf_pattern, L"Appendix %C")) {
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Appendix*");
}
Regexp__dispose_of(&mr);
TEMPORARY_TEXT(tester)
WRITE_TO(tester, "%p/%S/*", Pathnames__up(P), leaf_pattern);
DISCARD_TEXT(leaf_pattern)
Filenames__write_extension(tester, F);
if (Dictionaries__find(patterns_done, tester) == NULL) {
WRITE_TO(Dictionaries__create_text(patterns_done, tester), "got this");
WRITE(" ");
LOOP_THROUGH_TEXT(pos, tester) {
wchar_t c = Str__get(pos);
if (c == ' ') PUT('\\');
PUT(c);
}
}
DISCARD_TEXT(tester)
}
#line 330 "inweb/Chapter 6/Makefiles.w"
;
}
}
#line 365 "inweb/Chapter 6/Makefiles.w"
void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) {
TEMPORARY_TEXT(PT)
WRITE_TO(PT, "%p", P);
LOOP_THROUGH_TEXT(pos, PT) {
wchar_t c = Str__get(pos);
if (c == ' ') WRITE("\\ ");
else PUT(c);
}
DISCARD_TEXT(PT)
}
#line 8 "inweb/Chapter 6/Git Support.w"
void Git__write_gitignore(web *W, filename *prototype, filename *F) {
linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
Preprocessor__new_macro(L, TL_IS_702, NULL, Git__basics_expander, NULL);
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, NULL_GENERAL_POINTER, '#', ISO_ENC);
}
#line 22 "inweb/Chapter 6/Git Support.w"
void Git__basics_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
filename *prototype = Filenames__in(path_to_inweb_materials, TL_IS_703);
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");
}
#line 35 "inweb/Chapter 6/Ctags Support.w"
void Ctags__write(web *W, filename *F) {
text_stream ctags_file;
pathname *P = NULL;
if (F) {
P = Filenames__up(F);
} else {
P = W->md->path_to_web;
F = Filenames__in(P, TL_IS_704);
}
text_stream *OUT = &ctags_file;
if (STREAM_OPEN_TO_FILE(OUT, F, UTF8_ENC) == FALSE)
Errors__fatal_with_file("unable to write ctags file", F);
{
#line 82 "inweb/Chapter 6/Ctags Support.w"
WRITE("!_TAG_FILE_FORMAT\t2\t/extended format; --format=1 will not append ;\" to lines/\n");
WRITE("!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/\n");
WRITE("!_TAG_PROGRAM_AUTHOR\tGraham Nelson\t/graham.nelson@mod-langs.ox.ac.uk/\n");
WRITE("!_TAG_PROGRAM_NAME\tinweb\t//\n");
WRITE("!_TAG_PROGRAM_VERSION\t7.2.0\t/built 20 August 2022/\n");
}
#line 47 "inweb/Chapter 6/Ctags Support.w"
;
{
#line 94 "inweb/Chapter 6/Ctags Support.w"
defined_constant *str;
LOOP_OVER(str, defined_constant)
if (str->at->owning_section->owning_web == W) {
WRITE("%S\t", str->name);
Ctags__write_line_ref(OUT, str->at, P);
WRITE(";\"\t");
WRITE("d");
WRITE("\n");
}
}
#line 48 "inweb/Chapter 6/Ctags Support.w"
;
{
#line 109 "inweb/Chapter 6/Ctags Support.w"
language_type *str;
LOOP_OVER(str, language_type)
if (str->structure_header_at->owning_section->owning_web == W) {
WRITE("%S\t", str->structure_name);
Ctags__write_line_ref(OUT, str->structure_header_at, P);
WRITE(";\"\t");
WRITE("t\ttyperef:struct:%S", str->structure_name);
WRITE("\n");
}
}
#line 49 "inweb/Chapter 6/Ctags Support.w"
;
{
#line 122 "inweb/Chapter 6/Ctags Support.w"
language_function *fn;
LOOP_OVER(fn, language_function)
if (fn->function_header_at->owning_section->owning_web == W) {
WRITE("%S\t", fn->function_name);
Ctags__write_line_ref(OUT, fn->function_header_at, P);
WRITE(";\"\t");
WRITE("f");
WRITE("\n");
}
}
#line 50 "inweb/Chapter 6/Ctags Support.w"
;
STREAM_CLOSE(OUT);
}
#line 146 "inweb/Chapter 6/Ctags Support.w"
void Ctags__write_line_ref(OUTPUT_STREAM, source_line *L, pathname *P) {
TEMPORARY_TEXT(fn)
WRITE_TO(fn, "%f", L->owning_section->md->source_file_for_section);
if (Platform__is_folder_separator(Str__get_first_char(fn)) == FALSE) {
Str__clear(fn);
Filenames__to_text_relative(fn, L->owning_section->md->source_file_for_section, P);
}
WRITE("%S\t/^", fn);
DISCARD_TEXT(fn)
for (int i = 0; i < Str__len(L->text); i++) {
wchar_t c = Str__get_at(L->text, i);
switch (c) {
case '/': PUT('\\'); PUT(c); break;
case '^': if (i == 0) PUT('\\'); PUT(c); break;
case '$': if (i < Str__len(L->text) - 1) PUT('\\'); PUT(c); break;
default: PUT(c); break;
}
}
WRITE("$/");
}
#line 178 "inweb/Chapter 6/Ctags Support.w"
#line 182 "inweb/Chapter 6/Ctags Support.w"
void Ctags__note_defined_constant(source_line *L, text_stream *name) {
defined_constant *dc = CREATE(defined_constant);
dc->name = Str__duplicate(name);
dc->at = L;
}
#line 10 "inweb/Chapter 6/Readme Writeme.w"
void Readme__write(filename *prototype, filename *F) {
linked_list *L = NEW_LINKED_LIST(preprocessor_macro);
preprocessor_macro *mm = Preprocessor__new_macro(L,
TL_IS_705, TL_IS_706,
Readme__bibliographic_expander, NULL);
Preprocessor__do_not_suppress_whitespace(mm);
WRITE_TO(STDOUT, "(Read script from %f)\n", prototype);
Preprocessor__preprocess(prototype, F, NULL, L, NULL_GENERAL_POINTER, '/', ISO_ENC);
}
#line 23 "inweb/Chapter 6/Readme Writeme.w"
void Readme__bibliographic_expander(preprocessor_macro *mm, preprocessor_state *PPS,
text_stream **parameter_values, preprocessor_loop *loop, text_file_position *tfp) {
text_stream *datum = parameter_values[0];
text_stream *asset_name = parameter_values[1];
text_stream *OUT = PPS->dest;
writeme_asset *A = Readme__find_asset(asset_name);
if (A->if_web) WRITE("%S", Bibliographic__get_datum(A->if_web, datum));
else if (Str__eq(datum, TL_IS_707)) WRITE("%S", A->date);
else if (Str__eq(datum, TL_IS_708)) WRITE("%S", A->version);
}
#line 49 "inweb/Chapter 6/Readme Writeme.w"
void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) {
writeme_asset *A = Readme__find_asset(program);
if (A->if_web) WRITE("%S", Bibliographic__get_datum(A->if_web, datum));
else if (Str__eq(datum, TL_IS_709)) WRITE("%S", A->date);
else if (Str__eq(datum, TL_IS_710)) WRITE("%S", A->version);
}
#line 60 "inweb/Chapter 6/Readme Writeme.w"
writeme_asset *Readme__find_asset(text_stream *program) {
writeme_asset *A;
LOOP_OVER(A, writeme_asset) if (Str__eq(program, A->name)) return A;
A = CREATE(writeme_asset);
A->name = Str__duplicate(program);
A->if_web = NULL;
A->date = Str__new();
A->version = Str__new();
A->next_is_version = FALSE;
{
#line 74 "inweb/Chapter 6/Readme Writeme.w"
if (Str__ends_with_wide_string(program, L".i7x")) {
{
#line 93 "inweb/Chapter 6/Readme Writeme.w"
TextFiles__read(Filenames__from_text(program), FALSE, "unable to read extension", TRUE,
&Readme__extension_harvester, NULL, A);
}
#line 75 "inweb/Chapter 6/Readme Writeme.w"
;
} else {
if (WebMetadata__directory_looks_like_a_web(Pathnames__from_text(program))) {
A->if_web = WebMetadata__get_without_modules(Pathnames__from_text(program), NULL);
} else {
filename *I6_vn = Filenames__in(
Pathnames__down(Pathnames__from_text(program), TL_IS_711), TL_IS_712);
if (TextFiles__exists(I6_vn))
{
#line 97 "inweb/Chapter 6/Readme Writeme.w"
TextFiles__read(I6_vn, FALSE, "unable to read header file from I6 source", TRUE,
&Readme__header_harvester, NULL, A);
}
#line 82 "inweb/Chapter 6/Readme Writeme.w"
;
filename *template_vn = Filenames__in(Pathnames__from_text(program), TL_IS_713);
if (TextFiles__exists(template_vn))
{
#line 101 "inweb/Chapter 6/Readme Writeme.w"
TextFiles__read(template_vn, FALSE, "unable to read manifest file from website template", TRUE,
&Readme__template_harvester, NULL, A);
}
#line 84 "inweb/Chapter 6/Readme Writeme.w"
;
filename *rmt_vn = Filenames__in(Pathnames__from_text(program), TL_IS_714);
if (TextFiles__exists(rmt_vn))
{
#line 105 "inweb/Chapter 6/Readme Writeme.w"
TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE,
&Readme__readme_harvester, NULL, A);
}
#line 86 "inweb/Chapter 6/Readme Writeme.w"
;
rmt_vn = Filenames__in(Pathnames__from_text(program), TL_IS_715);
if (TextFiles__exists(rmt_vn))
{
#line 105 "inweb/Chapter 6/Readme Writeme.w"
TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE,
&Readme__readme_harvester, NULL, A);
}
#line 88 "inweb/Chapter 6/Readme Writeme.w"
;
}
}
}
#line 69 "inweb/Chapter 6/Readme Writeme.w"
;
return A;
}
#line 111 "inweb/Chapter 6/Readme Writeme.w"
void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) {
writeme_asset *A = (writeme_asset *) state;
match_results mr = Regexp__create_mr();
if (Str__len(text) == 0) return;
if (Regexp__match(&mr, text, L" *Version (%c*?) of %c*begins here. *"))
A->version = Str__duplicate(mr.exp[0]);
Regexp__dispose_of(&mr);
}
#line 123 "inweb/Chapter 6/Readme Writeme.w"
void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) {
writeme_asset *A = (writeme_asset *) state;
match_results mr = Regexp__create_mr();
if (Str__len(text) == 0) return;
if (Regexp__match(&mr, text, L"#define RELEASE_NUMBER (%c*?) *"))
A->version = Str__duplicate(mr.exp[0]);
if (Regexp__match(&mr, text, L"#define RELEASE_DATE \"(%c*?)\" *"))
A->date = Str__duplicate(mr.exp[0]);
Regexp__dispose_of(&mr);
}
#line 137 "inweb/Chapter 6/Readme Writeme.w"
void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) {
writeme_asset *A = (writeme_asset *) state;
match_results mr = Regexp__create_mr();
if (Str__len(text) == 0) return;
if (Regexp__match(&mr, text, L"%[INTERPRETERVERSION%]")) {
A->next_is_version = TRUE;
} else if (A->next_is_version) {
A->version = Str__duplicate(text);
A->next_is_version = FALSE;
}
Regexp__dispose_of(&mr);
}
#line 153 "inweb/Chapter 6/Readme Writeme.w"
void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) {
writeme_asset *A = (writeme_asset *) state;
match_results mr = Regexp__create_mr();
if (Str__len(text) == 0) return;
if ((Regexp__match(&mr, text, L"CheapGlk Library: version (%c*?) *")) ||
(Regexp__match(&mr, text, L"- Version (%c*?) *")))
A->version = Str__duplicate(mr.exp[0]);
Regexp__dispose_of(&mr);
}
#line 28 "inweb/Chapter 6/Colonies.w"
#line 52 "inweb/Chapter 6/Colonies.w"
#line 65 "inweb/Chapter 6/Colonies.w"
void Colonies__load(filename *F) {
colony *C = CREATE(colony);
C->members = NEW_LINKED_LIST(colony_member);
C->home = TL_IS_716;
C->assets_path = NULL;
C->patterns_path = NULL;
colony_reader_state crs;
crs.province = C;
crs.nav = NULL;
crs.crumbs = NEW_LINKED_LIST(breadcrumb_request);
crs.pattern = NULL;
TextFiles__read(F, FALSE, "can't open colony file",
TRUE, Colonies__read_line, NULL, (void *) &crs);
}
#line 84 "inweb/Chapter 6/Colonies.w"
void Colonies__read_line(text_stream *line, text_file_position *tfp, void *v_crs) {
colony_reader_state *crs = (colony_reader_state *) v_crs;
colony *C = crs->province;
Str__trim_white_space(line); /* ignore trailing space */
if (Str__len(line) == 0) return; /* ignore blank lines */
if (Str__get_first_char(line) == '#') return; /* lines opening with |#| are comments */
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c*?): \"*(%C+)\" at \"(%c*)\" in \"(%c*)\"")) {
colony_member *CM = CREATE(colony_member);
if (Str__eq(mr.exp[0], TL_IS_717)) CM->web_rather_than_module = TRUE;
else if (Str__eq(mr.exp[0], TL_IS_718)) CM->web_rather_than_module = FALSE;
else {
CM->web_rather_than_module = FALSE;
Errors__in_text_file("text before ':' must be 'web' or 'module'", tfp);
}
CM->name = Str__duplicate(mr.exp[1]);
CM->path = Str__duplicate(mr.exp[2]);
CM->home_leaf = Str__new();
if (Str__suffix_eq(CM->path, TL_IS_719, 6)) {
filename *F = Filenames__from_text(CM->path);
Filenames__write_unextended_leafname(CM->home_leaf, F);
WRITE_TO(CM->home_leaf, ".html");
} else {
WRITE_TO(CM->home_leaf, "index.html");
}
CM->weave_path = Pathnames__from_text(mr.exp[3]);
CM->loaded = NULL;
CM->navigation = crs->nav;
CM->breadcrumb_tail = crs->crumbs;
CM->default_weave_pattern = Str__duplicate(crs->pattern);
ADD_TO_LINKED_LIST(CM, colony_member, C->members);
} else if (Regexp__match(&mr, line, L"home: *(%c*)")) {
C->home = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, line, L"assets: *(%c*)")) {
C->assets_path = Pathnames__from_text(mr.exp[0]);
} else if (Regexp__match(&mr, line, L"patterns: *(%c*)")) {
C->patterns_path = Pathnames__from_text(mr.exp[0]);
} else if (Regexp__match(&mr, line, L"pattern: none")) {
crs->pattern = NULL;
} else if (Regexp__match(&mr, line, L"pattern: *(%c*)")) {
crs->pattern = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, line, L"navigation: none")) {
crs->nav = NULL;
} else if (Regexp__match(&mr, line, L"navigation: *(%c*)")) {
crs->nav = Filenames__from_text(mr.exp[0]);
} else if (Regexp__match(&mr, line, L"breadcrumbs: none")) {
crs->crumbs = NEW_LINKED_LIST(breadcrumb_request);
} else if (Regexp__match(&mr, line, L"breadcrumbs: *(%c*)")) {
crs->crumbs = NEW_LINKED_LIST(breadcrumb_request);
match_results mr2 = Regexp__create_mr();
while (Regexp__match(&mr2, mr.exp[0], L"(\"%c*?\") > (%c*)")) {
Colonies__add_crumb(crs->crumbs, mr2.exp[0], tfp);
Str__clear(mr.exp[0]); Str__copy(mr.exp[0], mr2.exp[1]);
}
Colonies__add_crumb(crs->crumbs, mr.exp[0], tfp);
} else {
Errors__in_text_file("unable to read colony member", tfp);
}
Regexp__dispose_of(&mr);
}
#line 151 "inweb/Chapter 6/Colonies.w"
void Colonies__add_crumb(linked_list *L, text_stream *spec, text_file_position *tfp) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, spec, L"\"(%c*?)\"") == FALSE) {
Errors__in_text_file("each crumb must be in double-quotes", tfp);
return;
}
spec = mr.exp[0];
breadcrumb_request *br = Colonies__request_breadcrumb(spec);
ADD_TO_LINKED_LIST(br, breadcrumb_request, L);
Regexp__dispose_of(&mr);
}
#line 168 "inweb/Chapter 6/Colonies.w"
breadcrumb_request *Colonies__request_breadcrumb(text_stream *arg) {
breadcrumb_request *BR = CREATE(breadcrumb_request);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, arg, L"(%c*?): *(%c*)")) {
BR->breadcrumb_text = Str__duplicate(mr.exp[0]);
BR->breadcrumb_link = Str__duplicate(mr.exp[1]);
} else {
BR->breadcrumb_text = Str__duplicate(arg);
BR->breadcrumb_link = Str__duplicate(arg);
WRITE_TO(BR->breadcrumb_link, ".html");
}
Regexp__dispose_of(&mr);
return BR;
}
void Colonies__drop_initial_breadcrumbs(OUTPUT_STREAM, filename *F, linked_list *crumbs) {
breadcrumb_request *BR;
LOOP_OVER_LINKED_LIST(BR, breadcrumb_request, crumbs) {
TEMPORARY_TEXT(url)
Colonies__link_URL(url, BR->breadcrumb_link, F);
Colonies__write_breadcrumb(OUT, BR->breadcrumb_text, url);
DISCARD_TEXT(url)
}
}
void Colonies__write_breadcrumb(OUTPUT_STREAM, text_stream *text, text_stream *link) {
if (link) {
HTML_OPEN("li");
HTML__begin_link(OUT, link);
WRITE("%S", text);
HTML__end_link(OUT);
HTML_CLOSE("li");
} else {
HTML_OPEN("li");
HTML_OPEN("b");
WRITE("%S", text);
HTML_CLOSE("b");
HTML_CLOSE("li");
}
}
#line 215 "inweb/Chapter 6/Colonies.w"
colony_member *Colonies__find(text_stream *T) {
colony *C;
LOOP_OVER(C, colony) {
colony_member *CM;
LOOP_OVER_LINKED_LIST(CM, colony_member, C->members)
if (Str__eq_insensitive(T, CM->name))
return CM;
}
return NULL;
}
#line 233 "inweb/Chapter 6/Colonies.w"
module *Colonies__as_module(colony_member *CM, source_line *L, web_md *Wm) {
if (CM->loaded == NULL)
{
#line 242 "inweb/Chapter 6/Colonies.w"
if ((Wm) && (Str__eq_insensitive(Wm->as_module->module_name, CM->name)))
CM->loaded = Wm;
}
#line 234 "inweb/Chapter 6/Colonies.w"
;
if (CM->loaded == NULL)
{
#line 246 "inweb/Chapter 6/Colonies.w"
if (Wm) {
module *M;
LOOP_OVER_LINKED_LIST(M, module, Wm->as_module->dependencies)
if (Str__eq_insensitive(M->module_name, CM->name))
CM->loaded = Wm;
}
}
#line 235 "inweb/Chapter 6/Colonies.w"
;
if (CM->loaded == NULL)
{
#line 254 "inweb/Chapter 6/Colonies.w"
filename *F = NULL;
pathname *P = NULL;
if (Str__suffix_eq(CM->path, TL_IS_720, 6))
F = Filenames__from_text(CM->path);
else
P = Pathnames__from_text(CM->path);
CM->loaded = WebMetadata__get_without_modules(P, F);
}
#line 236 "inweb/Chapter 6/Colonies.w"
;
if (CM->loaded == NULL)
{
#line 263 "inweb/Chapter 6/Colonies.w"
TEMPORARY_TEXT(err)
WRITE_TO(err, "unable to load '%S'", CM->name);
Main__error_in_web(err, L);
}
#line 237 "inweb/Chapter 6/Colonies.w"
;
return CM->loaded->as_module;
}
#line 270 "inweb/Chapter 6/Colonies.w"
text_stream *Colonies__home(void) {
colony *C;
LOOP_OVER(C, colony)
return C->home;
return TL_IS_721;
}
pathname *Colonies__assets_path(void) {
colony *C;
LOOP_OVER(C, colony)
return C->assets_path;
return NULL;
}
pathname *Colonies__patterns_path(void) {
colony *C;
LOOP_OVER(C, colony)
return C->patterns_path;
return NULL;
}
#line 310 "inweb/Chapter 6/Colonies.w"
int Colonies__resolve_reference_in_weave(text_stream *url, text_stream *title,
filename *for_HTML_file, text_stream *text, web_md *Wm, source_line *L, int *ext) {
int r = 0;
if (ext) *ext = FALSE;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, text, L"(%c+?) -> (%c+)")) {
r = Colonies__resolve_reference_in_weave_inner(url, NULL,
for_HTML_file, mr.exp[1], Wm, L, ext);
WRITE_TO(title, "%S", mr.exp[0]);
} else {
r = Colonies__resolve_reference_in_weave_inner(url, title,
for_HTML_file, text, Wm, L, ext);
}
Regexp__dispose_of(&mr);
return r;
}
int Colonies__resolve_reference_in_weave_inner(text_stream *url, text_stream *title,
filename *for_HTML_file, text_stream *text, web_md *Wm, source_line *L, int *ext) {
module *from_M = (Wm)?(Wm->as_module):NULL;
module *search_M = from_M;
colony_member *search_CM = NULL;
int external = FALSE;
{
#line 378 "inweb/Chapter 6/Colonies.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, text, L"https*://%c*")) {
WRITE_TO(url, "%S", text);
WRITE_TO(title, "%S", text);
Regexp__dispose_of(&mr);
if (ext) *ext = TRUE;
return TRUE;
}
Regexp__dispose_of(&mr);
}
#line 334 "inweb/Chapter 6/Colonies.w"
;
{
#line 389 "inweb/Chapter 6/Colonies.w"
search_CM = Colonies__find(text);
if (search_CM) {
module *found_M = Colonies__as_module(search_CM, L, Wm);
section_md *found_Sm = FIRST_IN_LINKED_LIST(section_md, found_M->sections_md);
int bare_module_name = TRUE;
WRITE_TO(title, "%S", search_CM->name);
{
#line 437 "inweb/Chapter 6/Colonies.w"
if (found_M == NULL) internal_error("could not locate M");
if (search_CM)
{
#line 443 "inweb/Chapter 6/Colonies.w"
pathname *from = Filenames__up(for_HTML_file);
pathname *to = search_CM->weave_path;
Pathnames__relative_URL(url, from, to);
if (bare_module_name) WRITE_TO(url, "%S", search_CM->home_leaf);
else if (found_Sm) Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", search_CM->name);
}
#line 438 "inweb/Chapter 6/Colonies.w"
else
{
#line 456 "inweb/Chapter 6/Colonies.w"
if (found_M == from_M) {
Colonies__section_URL(url, found_Sm);
} else {
WRITE_TO(url, "../%S-module/", found_M->module_name);
Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", found_M->module_name);
}
}
#line 439 "inweb/Chapter 6/Colonies.w"
;
return TRUE;
}
#line 395 "inweb/Chapter 6/Colonies.w"
;
}
}
#line 335 "inweb/Chapter 6/Colonies.w"
;
{
#line 399 "inweb/Chapter 6/Colonies.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, text, L"(%c*?): (%c*)")) {
search_CM = Colonies__find(mr.exp[0]);
if (search_CM) {
module *found_M = Colonies__as_module(search_CM, L, Wm);
if (found_M) {
search_M = found_M;
if (LinkedLists__len(found_M->dependencies) == 0)
text = Str__duplicate(mr.exp[1]);
external = TRUE;
}
}
}
Regexp__dispose_of(&mr);
}
#line 336 "inweb/Chapter 6/Colonies.w"
;
module *found_M = NULL;
section_md *found_Sm = NULL;
int bare_module_name = FALSE;
/* find how many hits (N), and how many which are sections (NS) */
int N = WebModules__named_reference(&found_M, &found_Sm, &bare_module_name,
NULL, search_M, text, FALSE, FALSE);
found_M = NULL; found_Sm = NULL; bare_module_name = FALSE;
int NS = WebModules__named_reference(&found_M, &found_Sm, &bare_module_name,
NULL, search_M, text, FALSE, TRUE);
int sections_only = FALSE;
if ((N > 1) && (NS == 1)) sections_only = TRUE;
/* now perform the definitive search */
found_M = NULL; found_Sm = NULL; bare_module_name = FALSE;
N = WebModules__named_reference(&found_M, &found_Sm, &bare_module_name,
title, search_M, text, FALSE, sections_only);
if (N == 0) {
if ((L) && (external == FALSE)) {
{
#line 415 "inweb/Chapter 6/Colonies.w"
language_function *fn;
LOOP_OVER(fn, language_function) {
if (Str__eq_insensitive(fn->function_name, text)) {
Colonies__paragraph_URL(url, fn->function_header_at->owning_paragraph,
for_HTML_file);
WRITE_TO(title, "%S", fn->function_name);
return TRUE;
}
}
}
#line 358 "inweb/Chapter 6/Colonies.w"
;
{
#line 426 "inweb/Chapter 6/Colonies.w"
language_type *str;
LOOP_OVER(str, language_type) {
if (Str__eq_insensitive(str->structure_name, text)) {
Colonies__paragraph_URL(url, str->structure_header_at->owning_paragraph,
for_HTML_file);
WRITE_TO(title, "%S", str->structure_name);
return TRUE;
}
}
}
#line 359 "inweb/Chapter 6/Colonies.w"
;
}
TEMPORARY_TEXT(err)
WRITE_TO(err, "Can't find the cross-reference '%S'", text);
Main__error_in_web(err, L);
DISCARD_TEXT(err)
return FALSE;
}
if (N > 1) {
Main__error_in_web(TL_IS_722, L);
WebModules__named_reference(&found_M, &found_Sm, &bare_module_name,
title, search_M, text, TRUE, FALSE);
return FALSE;
}
{
#line 437 "inweb/Chapter 6/Colonies.w"
if (found_M == NULL) internal_error("could not locate M");
if (search_CM)
{
#line 443 "inweb/Chapter 6/Colonies.w"
pathname *from = Filenames__up(for_HTML_file);
pathname *to = search_CM->weave_path;
Pathnames__relative_URL(url, from, to);
if (bare_module_name) WRITE_TO(url, "%S", search_CM->home_leaf);
else if (found_Sm) Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", search_CM->name);
}
#line 438 "inweb/Chapter 6/Colonies.w"
else
{
#line 456 "inweb/Chapter 6/Colonies.w"
if (found_M == from_M) {
Colonies__section_URL(url, found_Sm);
} else {
WRITE_TO(url, "../%S-module/", found_M->module_name);
Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", found_M->module_name);
}
}
#line 439 "inweb/Chapter 6/Colonies.w"
;
return TRUE;
}
#line 373 "inweb/Chapter 6/Colonies.w"
;
return TRUE;
}
#line 468 "inweb/Chapter 6/Colonies.w"
void Colonies__link_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, link_text, L" *//(%c+)// *"))
Colonies__reference_URL(OUT, mr.exp[0], F);
else
WRITE("%S", link_text);
Regexp__dispose_of(&mr);
}
void Colonies__reference_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) {
TEMPORARY_TEXT(title)
TEMPORARY_TEXT(url)
if (Colonies__resolve_reference_in_weave(url, title, F, link_text, NULL, NULL, NULL))
WRITE("%S", url);
else
PRINT("Warning: unable to resolve reference '%S' in navigation\n", link_text);
DISCARD_TEXT(title)
DISCARD_TEXT(url)
}
void Colonies__section_URL(OUTPUT_STREAM, section_md *Sm) {
if (Sm == NULL) internal_error("unwoven section");
LOOP_THROUGH_TEXT(pos, Sm->sect_range)
if ((Str__get(pos) == '/') || (Str__get(pos) == ' '))
PUT('-');
else
PUT(Str__get(pos));
WRITE(".html");
}
void Colonies__paragraph_URL(OUTPUT_STREAM, paragraph *P, filename *from) {
if (from == NULL) internal_error("no from file");
if (P == NULL) internal_error("no para");
section *to_S = P->under_section;
module *to_M = to_S->md->owning_module;
if (Str__ne(to_M->module_name, TL_IS_723)) {
colony_member *to_C = Colonies__find(to_M->module_name);
if (to_C) {
pathname *from_path = Filenames__up(from);
pathname *to_path = to_C->weave_path;
Pathnames__relative_URL(OUT, from_path, to_path);
} else {
PRINT("Warning: a link in the weave will work only if '%S' appears in the colony file\n",
to_M->module_name);
}
}
Colonies__section_URL(OUT, to_S->md);
WRITE("#");
Colonies__paragraph_anchor(OUT, P);
}
void Colonies__paragraph_anchor(OUTPUT_STREAM, paragraph *P) {
if (P == NULL) internal_error("no para");
WRITE("%S", P->ornament);
WRITE("P");
text_stream *N = P->paragraph_number;
LOOP_THROUGH_TEXT(pos, N)
if (Str__get(pos) == '.') WRITE("_");
else PUT(Str__get(pos));
}
void register_tangled_nonterminals(void) {
}
void register_tangled_text_literals(void) {
TL_IS_0 = Str__literal(L"INVOCATION");
TL_IS_1 = Str__literal(L"debug-log.txt");
TL_IS_2 = Str__literal(L"Tangled");
TL_IS_3 = Str__literal(L"NAME");
TL_IS_4 = Str__literal(L"");
TL_IS_5 = Str__literal(L"repeat");
TL_IS_6 = Str__literal(L"with: WITH in: IN");
TL_IS_7 = Str__literal(L"set");
TL_IS_8 = Str__literal(L"name: NAME value: VALUE");
TL_IS_9 = Str__literal(L"mismatched '[' ... ']'");
TL_IS_10 = Str__literal(L"mismatched '{' ... '}'");
TL_IS_11 = Str__literal(L"mismatched quotation marks");
TL_IS_12 = Str__literal(L"true");
TL_IS_13 = Str__literal(L"false");
TL_IS_14 = Str__literal(L"null");
TL_IS_15 = Str__literal(L"unknown JSON value");
TL_IS_16 = Str__literal(L"whitespace where JSON value expected");
TL_IS_17 = Str__literal(L"object body ends with comma");
TL_IS_18 = Str__literal(L"key does not begin with quotation mark");
TL_IS_19 = Str__literal(L"key does not end with quotation mark");
TL_IS_20 = Str__literal(L"key is not followed by ':'");
TL_IS_21 = Str__literal(L"duplicate key");
TL_IS_22 = Str__literal(L"whitespace where number expected");
TL_IS_23 = Str__literal(L"number is not a decimal integer");
TL_IS_24 = Str__literal(L"number is not allowed to be NaN");
TL_IS_25 = Str__literal(L"unescaped control character");
TL_IS_26 = Str__literal(L"bad '\\' escape in string");
TL_IS_27 = Str__literal(L"incomplete '\\u' escape");
TL_IS_28 = Str__literal(L"garbled '\\u' escape");
TL_IS_29 = Str__literal(L"array");
TL_IS_30 = Str__literal(L"object");
TL_IS_31 = Str__literal(L"erroneous JSON value from parsing bad text");
TL_IS_32 = Str__literal(L"unexpected array entry");
TL_IS_33 = Str__literal(L"mismatched '(' ... ')'");
TL_IS_34 = Str__literal(L"whitespace where requirement expected");
TL_IS_35 = Str__literal(L"mismatched '[' ... ']'");
TL_IS_36 = Str__literal(L"mismatched '{' ... '}'");
TL_IS_37 = Str__literal(L"mismatched '<' ... '>'");
TL_IS_38 = Str__literal(L"unknown '<name>'");
TL_IS_39 = Str__literal(L"'<' ... '>' not allowed");
TL_IS_40 = Str__literal(L"true");
TL_IS_41 = Str__literal(L"false");
TL_IS_42 = Str__literal(L"null");
TL_IS_43 = Str__literal(L"number");
TL_IS_44 = Str__literal(L"double");
TL_IS_45 = Str__literal(L"string");
TL_IS_46 = Str__literal(L"boolean");
TL_IS_47 = Str__literal(L"key does not begin with quotation mark");
TL_IS_48 = Str__literal(L"key does not end with quotation mark");
TL_IS_49 = Str__literal(L"key is not followed by ':'");
TL_IS_50 = Str__literal(L"duplicate key");
TL_IS_51 = Str__literal(L"spurious text before first requirement");
TL_IS_52 = Str__literal(L"CONTENT BEGINS");
TL_IS_53 = Str__literal(L"CONTENT ENDS");
TL_IS_54 = Str__literal(L"inform:/doc_images/ornament_flower.png");
TL_IS_55 = Str__literal(L"ePub");
TL_IS_56 = Str__literal(L"OEBPS");
TL_IS_57 = Str__literal(L"mimetype");
TL_IS_58 = Str__literal(L"META-INF");
TL_IS_59 = Str__literal(L"container.xml");
TL_IS_60 = Str__literal(L"cover.html");
TL_IS_61 = Str__literal(L"Cover");
TL_IS_62 = Str__literal(L"cover");
TL_IS_63 = Str__literal(L"content.opf");
TL_IS_64 = Str__literal(L"toc.ncx");
TL_IS_65 = Str__literal(L"..");
TL_IS_66 = Str__literal(L"A");
TL_IS_67 = Str__literal(L"Sequential Section Ranges");
TL_IS_68 = Str__literal(L"On");
TL_IS_69 = Str__literal(L"Web Syntax Version: 1");
TL_IS_70 = Str__literal(L"Web Syntax Version: 2");
TL_IS_71 = Str__literal(L"S");
TL_IS_72 = Str__literal(L"Sections");
TL_IS_73 = Str__literal(L"All");
TL_IS_74 = Str__literal(L"Headers");
TL_IS_75 = Str__literal(L"single-file webs cannot Import modules");
TL_IS_76 = Str__literal(L"Language");
TL_IS_77 = Str__literal(L"Language");
TL_IS_78 = Str__literal(L"Contents.w");
TL_IS_79 = Str__literal(L"Title");
TL_IS_80 = Str__literal(L"Author");
TL_IS_81 = Str__literal(L"Language");
TL_IS_82 = Str__literal(L"None");
TL_IS_83 = Str__literal(L"Purpose");
TL_IS_84 = Str__literal(L"");
TL_IS_85 = Str__literal(L"License");
TL_IS_86 = Str__literal(L"Licence");
TL_IS_87 = Str__literal(L"Short Title");
TL_IS_88 = Str__literal(L"Capitalized Title");
TL_IS_89 = Str__literal(L"Build Date");
TL_IS_90 = Str__literal(L"Build Number");
TL_IS_91 = Str__literal(L"Prerelease");
TL_IS_92 = Str__literal(L"Semantic Version Number");
TL_IS_93 = Str__literal(L"Version Number");
TL_IS_94 = Str__literal(L"1");
TL_IS_95 = Str__literal(L"Version Name");
TL_IS_96 = Str__literal(L"Index Template");
TL_IS_97 = Str__literal(L"Preform Language");
TL_IS_98 = Str__literal(L"Declare Section Usage");
TL_IS_99 = Str__literal(L"Off");
TL_IS_100 = Str__literal(L"Namespaces");
TL_IS_101 = Str__literal(L"Off");
TL_IS_102 = Str__literal(L"Sequential Section Ranges");
TL_IS_103 = Str__literal(L"Off");
TL_IS_104 = Str__literal(L"Strict Usage Rules");
TL_IS_105 = Str__literal(L"Off");
TL_IS_106 = Str__literal(L"TeX Mathematics Notation");
TL_IS_107 = Str__literal(L"$");
TL_IS_108 = Str__literal(L"TeX Mathematics Displayed Notation");
TL_IS_109 = Str__literal(L"$$");
TL_IS_110 = Str__literal(L"Footnote Begins Notation");
TL_IS_111 = Str__literal(L"[");
TL_IS_112 = Str__literal(L"Footnote Ends Notation");
TL_IS_113 = Str__literal(L"]");
TL_IS_114 = Str__literal(L"Code In Commentary Notation");
TL_IS_115 = Str__literal(L"|");
TL_IS_116 = Str__literal(L"Code In Code Comments Notation");
TL_IS_117 = Str__literal(L"|");
TL_IS_118 = Str__literal(L"Cross-References Notation");
TL_IS_119 = Str__literal(L"//");
TL_IS_120 = Str__literal(L"Web Syntax Version");
TL_IS_121 = Str__literal(L"Paragraph Numbers Visibility");
TL_IS_122 = Str__literal(L"On");
TL_IS_123 = Str__literal(L"Capitalized Title");
TL_IS_124 = Str__literal(L"miscellaneous");
TL_IS_125 = Str__literal(L"(main)");
TL_IS_126 = Str__literal(L"build.txt");
TL_IS_127 = Str__literal(L"build.txt");
TL_IS_128 = Str__literal(L"Prerelease");
TL_IS_129 = Str__literal(L"Build Number");
TL_IS_130 = Str__literal(L"Build Date");
TL_IS_131 = Str__literal(L"Semantic Version Number");
TL_IS_132 = Str__literal(L"Version Number");
TL_IS_133 = Str__literal(L"Prerelease");
TL_IS_134 = Str__literal(L"Build Number");
TL_IS_135 = Str__literal(L"Semantic Version Number");
TL_IS_136 = Str__literal(L"Sections");
TL_IS_137 = Str__literal(L"inweb");
TL_IS_138 = Str__literal(L"Patterns");
TL_IS_139 = Str__literal(L"Materials");
TL_IS_140 = Str__literal(L"script.mkscript");
TL_IS_141 = Str__literal(L"script.giscript");
TL_IS_142 = Str__literal(L"script.rmscript");
TL_IS_143 = Str__literal(L"Short Title");
TL_IS_144 = Str__literal(L"Short Title");
TL_IS_145 = Str__literal(L"Title");
TL_IS_146 = Str__literal(L"0");
TL_IS_147 = Str__literal(L"for locating programming language definitions");
TL_IS_148 = Str__literal(L"for analysing a web");
TL_IS_149 = Str__literal(L"for weaving a web");
TL_IS_150 = Str__literal(L"for tangling a web");
TL_IS_151 = Str__literal(L"for dealing with colonies of webs together");
TL_IS_152 = Str__literal(L".inweb");
TL_IS_153 = Str__literal(L"0");
TL_IS_154 = Str__literal(L"Title");
TL_IS_155 = Str__literal(L"Booklet Title");
TL_IS_156 = Str__literal(L"Colours");
TL_IS_157 = Str__literal(L"Colours");
TL_IS_158 = Str__literal(L"");
TL_IS_159 = Str__literal(L"Version Number");
TL_IS_160 = Str__literal(L"Version Number");
TL_IS_161 = Str__literal(L" ");
TL_IS_162 = Str__literal(L"template-index.html");
TL_IS_163 = Str__literal(L"index.html");
TL_IS_164 = Str__literal(L"Index");
TL_IS_165 = Str__literal(L"index");
TL_IS_166 = Str__literal(L"0");
TL_IS_167 = Str__literal(L"pattern.txt");
TL_IS_168 = Str__literal(L"Patterns");
TL_IS_169 = Str__literal(L"pattern.txt");
TL_IS_170 = Str__literal(L"pattern.txt");
TL_IS_171 = Str__literal(L"name");
TL_IS_172 = Str__literal(L"plugin");
TL_IS_173 = Str__literal(L"format");
TL_IS_174 = Str__literal(L"number sections");
TL_IS_175 = Str__literal(L"default range");
TL_IS_176 = Str__literal(L"initial extension");
TL_IS_177 = Str__literal(L"mathematics plugin");
TL_IS_178 = Str__literal(L"footnotes plugin");
TL_IS_179 = Str__literal(L"block template");
TL_IS_180 = Str__literal(L"command");
TL_IS_181 = Str__literal(L"bibliographic data");
TL_IS_182 = Str__literal(L"assets");
TL_IS_183 = Str__literal(L"yes");
TL_IS_184 = Str__literal(L"no");
TL_IS_185 = Str__literal(L"none");
TL_IS_186 = Str__literal(L"WOVENPATH");
TL_IS_187 = Str__literal(L"WOVEN");
TL_IS_188 = Str__literal(L"PROCESS ");
TL_IS_189 = Str__literal(L"Colouring");
TL_IS_190 = Str__literal(L"Coloring");
TL_IS_191 = Str__literal(L"Colouring");
TL_IS_192 = Str__literal(L"Coloring");
TL_IS_193 = Str__literal(L"");
TL_IS_194 = Str__literal(L"copy");
TL_IS_195 = Str__literal(L"copy");
TL_IS_196 = Str__literal(L"private copy");
TL_IS_197 = Str__literal(L"embed");
TL_IS_198 = Str__literal(L"collate");
TL_IS_199 = Str__literal(L"prefix");
TL_IS_200 = Str__literal(L"suffix");
TL_IS_201 = Str__literal(L"transform names");
TL_IS_202 = Str__literal(L"");
TL_IS_203 = Str__literal(L"URL");
TL_IS_204 = Str__literal(L"URL");
TL_IS_205 = Str__literal(L"Inweb Version");
TL_IS_206 = Str__literal(L"Language");
TL_IS_207 = Str__literal(L"Purpose");
TL_IS_208 = Str__literal(L"Woven");
TL_IS_209 = Str__literal(L"Tangled");
TL_IS_210 = Str__literal(L"Title");
TL_IS_211 = Str__literal(L"");
TL_IS_212 = Str__literal(L"=");
TL_IS_213 = Str__literal(L"@");
TL_IS_214 = Str__literal(L"Figures");
TL_IS_215 = Str__literal(L"unknown [[command]]");
TL_IS_216 = Str__literal(L"<...> definition begins outside of a paragraph");
TL_IS_217 = Str__literal(L"(very early code)");
TL_IS_218 = Str__literal(L"(early code)");
TL_IS_219 = Str__literal(L"Extracts");
TL_IS_220 = Str__literal(L"Figures");
TL_IS_221 = Str__literal(L"HTML");
TL_IS_222 = Str__literal(L"Audio");
TL_IS_223 = Str__literal(L"Video");
TL_IS_224 = Str__literal(L"Download");
TL_IS_225 = Str__literal(L"Download");
TL_IS_226 = Str__literal(L"Carousels");
TL_IS_227 = Str__literal(L"Carousels");
TL_IS_228 = Str__literal(L"Carousels");
TL_IS_229 = Str__literal(L"Carousels");
TL_IS_230 = Str__literal(L"Carousels");
TL_IS_231 = Str__literal(L"Videos");
TL_IS_232 = Str__literal(L"unknown bracketed annotation");
TL_IS_233 = Str__literal(L"unknown material after '='");
TL_IS_234 = Str__literal(L"undisplayed");
TL_IS_235 = Str__literal(L"hyperlinked");
TL_IS_236 = Str__literal(L"only 'undisplayed' and/or 'hyperlinked' can precede 'text' here");
TL_IS_237 = Str__literal(L"=");
TL_IS_238 = Str__literal(L"don't understand @command");
TL_IS_239 = Str__literal(L"Purpose used after bar");
TL_IS_240 = Str__literal(L"Interface used after bar");
TL_IS_241 = Str__literal(L"Definitions used after bar");
TL_IS_242 = Str__literal(L"second bar in the same section");
TL_IS_243 = Str__literal(L"enumeration constants can't supply a value");
TL_IS_244 = Str__literal(L"Paragraph Numbers Visibility");
TL_IS_245 = Str__literal(L"Off");
TL_IS_246 = Str__literal(L"P");
TL_IS_247 = Str__literal(L"S");
TL_IS_248 = Str__literal(L"Footnote Begins Notation");
TL_IS_249 = Str__literal(L"Footnote Ends Notation");
TL_IS_250 = Str__literal(L"Off");
TL_IS_251 = Str__literal(L"ifdef-");
TL_IS_252 = Str__literal(L"ifndef-");
TL_IS_253 = Str__literal(L".");
TL_IS_254 = Str__literal(L"This paragraph is used only if ");
TL_IS_255 = Str__literal(L" and if ");
TL_IS_256 = Str__literal(L" and ");
TL_IS_257 = Str__literal(L" is");
TL_IS_258 = Str__literal(L" are");
TL_IS_259 = Str__literal(L" defined");
TL_IS_260 = Str__literal(L" undefined");
TL_IS_261 = Str__literal(L"enumeration constants must belong to a _FAMILY");
TL_IS_262 = Str__literal(L"this enumeration _FAMILY is unknown");
TL_IS_263 = Str__literal(L"this enumeration _FAMILY already exists");
TL_IS_264 = Str__literal(L"unrecognised interface line");
TL_IS_265 = Str__literal(L".");
TL_IS_266 = Str__literal(L"..");
TL_IS_267 = Str__literal(L"web");
TL_IS_268 = Str__literal(L"default.mkscript");
TL_IS_269 = Str__literal(L".");
TL_IS_270 = Str__literal(L"..");
TL_IS_271 = Str__literal(L"web");
TL_IS_272 = Str__literal(L"default.giscript");
TL_IS_273 = Str__literal(L"");
TL_IS_274 = Str__literal(L"Chapters");
TL_IS_275 = Str__literal(L"Modules");
TL_IS_276 = Str__literal(L"Module Page");
TL_IS_277 = Str__literal(L"Module Purpose");
TL_IS_278 = Str__literal(L"Purpose");
TL_IS_279 = Str__literal(L"Chapter Purpose");
TL_IS_280 = Str__literal(L"Section Purpose");
TL_IS_281 = Str__literal(L"Purpose");
TL_IS_282 = Str__literal(L"index.html");
TL_IS_283 = Str__literal(L"inweb");
TL_IS_284 = Str__literal(L"inweb");
TL_IS_285 = Str__literal(L"inweb");
TL_IS_286 = Str__literal(L"End of weave");
TL_IS_287 = Str__literal(L"Definitions");
TL_IS_288 = Str__literal(L"bad start to paragraph");
TL_IS_289 = Str__literal(L"");
TL_IS_290 = Str__literal(L"");
TL_IS_291 = Str__literal(L"footnote never cued");
TL_IS_292 = Str__literal(L"Preform");
TL_IS_293 = Str__literal(L"Preform");
TL_IS_294 = Str__literal(L"define");
TL_IS_295 = Str__literal(L"default");
TL_IS_296 = Str__literal(L"enum");
TL_IS_297 = Str__literal(L"Preform");
TL_IS_298 = Str__literal(L"This is ");
TL_IS_299 = Str__literal(L"words: About Preform");
TL_IS_300 = Str__literal(L"Preform grammar");
TL_IS_301 = Str__literal(L"Preform grammar");
TL_IS_302 = Str__literal(L", not regular C code.");
TL_IS_303 = Str__literal(L"This code is ");
TL_IS_304 = Str__literal(L"never used");
TL_IS_305 = Str__literal(L", ");
TL_IS_306 = Str__literal(L" and ");
TL_IS_307 = Str__literal(L"used in ");
TL_IS_308 = Str__literal(L" (twice)");
TL_IS_309 = Str__literal(L" (three times)");
TL_IS_310 = Str__literal(L" (four times)");
TL_IS_311 = Str__literal(L" (five times)");
TL_IS_312 = Str__literal(L".");
TL_IS_313 = Str__literal(L"The structure ");
TL_IS_314 = Str__literal(L" is private to this section");
TL_IS_315 = Str__literal(L" is accessed in ");
TL_IS_316 = Str__literal(L", ");
TL_IS_317 = Str__literal(L" and here");
TL_IS_318 = Str__literal(L".");
TL_IS_319 = Str__literal(L"The function ");
TL_IS_320 = Str__literal(L" appears nowhere else");
TL_IS_321 = Str__literal(L"none");
TL_IS_322 = Str__literal(L")");
TL_IS_323 = Str__literal(L".");
TL_IS_324 = Str__literal(L" is used in ");
TL_IS_325 = Str__literal(L"), ");
TL_IS_326 = Str__literal(L", ");
TL_IS_327 = Str__literal(L" (");
TL_IS_328 = Str__literal(L" - ");
TL_IS_329 = Str__literal(L", ");
TL_IS_330 = Str__literal(L"Code In Code Comments Notation");
TL_IS_331 = Str__literal(L"Code In Commentary Notation");
TL_IS_332 = Str__literal(L"Off");
TL_IS_333 = Str__literal(L"TeX Mathematics Displayed Notation");
TL_IS_334 = Str__literal(L"Off");
TL_IS_335 = Str__literal(L"TeX Mathematics Notation");
TL_IS_336 = Str__literal(L"Off");
TL_IS_337 = Str__literal(L"Cross-References Notation");
TL_IS_338 = Str__literal(L"Off");
TL_IS_339 = Str__literal(L"http://");
TL_IS_340 = Str__literal(L"https://");
TL_IS_341 = Str__literal(L"this is a cue for a missing note");
TL_IS_342 = Str__literal(L"Cross-References Notation");
TL_IS_343 = Str__literal(L"Off");
TL_IS_344 = Str__literal(L"http://");
TL_IS_345 = Str__literal(L"https://");
TL_IS_346 = Str__literal(L"misplaced definition");
TL_IS_347 = Str__literal(L"unknown macro");
TL_IS_348 = Str__literal(L"Dialects");
TL_IS_349 = Str__literal(L"C");
TL_IS_350 = Str__literal(L"Languages");
TL_IS_351 = Str__literal(L"InC");
TL_IS_352 = Str__literal(L"Name");
TL_IS_353 = Str__literal(L"Details");
TL_IS_354 = Str__literal(L"Extension");
TL_IS_355 = Str__literal(L"Line Comment");
TL_IS_356 = Str__literal(L"Whole Line Comment");
TL_IS_357 = Str__literal(L"Multiline Comment Open");
TL_IS_358 = Str__literal(L"Multiline Comment Close");
TL_IS_359 = Str__literal(L"String Literal");
TL_IS_360 = Str__literal(L"String Literal Escape");
TL_IS_361 = Str__literal(L"Character Literal");
TL_IS_362 = Str__literal(L"Character Literal Escape");
TL_IS_363 = Str__literal(L"Binary Literal Prefix");
TL_IS_364 = Str__literal(L"Octal Literal Prefix");
TL_IS_365 = Str__literal(L"Hexadecimal Literal Prefix");
TL_IS_366 = Str__literal(L"Negative Literal Prefix");
TL_IS_367 = Str__literal(L"Shebang");
TL_IS_368 = Str__literal(L"Line Marker");
TL_IS_369 = Str__literal(L"Before Named Paragraph Expansion");
TL_IS_370 = Str__literal(L"After Named Paragraph Expansion");
TL_IS_371 = Str__literal(L"Start Definition");
TL_IS_372 = Str__literal(L"Prolong Definition");
TL_IS_373 = Str__literal(L"End Definition");
TL_IS_374 = Str__literal(L"Start Ifdef");
TL_IS_375 = Str__literal(L"Start Ifndef");
TL_IS_376 = Str__literal(L"End Ifdef");
TL_IS_377 = Str__literal(L"End Ifndef");
TL_IS_378 = Str__literal(L"C-Like");
TL_IS_379 = Str__literal(L"Suppress Disclaimer");
TL_IS_380 = Str__literal(L"Supports Namespaces");
TL_IS_381 = Str__literal(L"Function Declaration Notation");
TL_IS_382 = Str__literal(L"Type Declaration Notation");
TL_IS_383 = Str__literal(L"}");
TL_IS_384 = Str__literal(L"unquoted");
TL_IS_385 = Str__literal(L"{");
TL_IS_386 = Str__literal(L"debug");
TL_IS_387 = Str__literal(L"!string");
TL_IS_388 = Str__literal(L"!function");
TL_IS_389 = Str__literal(L"!definition");
TL_IS_390 = Str__literal(L"!reserved");
TL_IS_391 = Str__literal(L"!element");
TL_IS_392 = Str__literal(L"!identifier");
TL_IS_393 = Str__literal(L"!character");
TL_IS_394 = Str__literal(L"!constant");
TL_IS_395 = Str__literal(L"!plain");
TL_IS_396 = Str__literal(L"!extract");
TL_IS_397 = Str__literal(L"!comment");
TL_IS_398 = Str__literal(L"true");
TL_IS_399 = Str__literal(L"false");
TL_IS_400 = Str__literal(L"both");
TL_IS_401 = Str__literal(L"brackets");
TL_IS_402 = Str__literal(L"characters");
TL_IS_403 = Str__literal(L"coloured");
TL_IS_404 = Str__literal(L"colouring");
TL_IS_405 = Str__literal(L"debug");
TL_IS_406 = Str__literal(L"false");
TL_IS_407 = Str__literal(L"in");
TL_IS_408 = Str__literal(L"instances");
TL_IS_409 = Str__literal(L"keyword");
TL_IS_410 = Str__literal(L"matches");
TL_IS_411 = Str__literal(L"matching");
TL_IS_412 = Str__literal(L"not");
TL_IS_413 = Str__literal(L"of");
TL_IS_414 = Str__literal(L"on");
TL_IS_415 = Str__literal(L"optionally");
TL_IS_416 = Str__literal(L"prefix");
TL_IS_417 = Str__literal(L"runs");
TL_IS_418 = Str__literal(L"spaced");
TL_IS_419 = Str__literal(L"suffix");
TL_IS_420 = Str__literal(L"true");
TL_IS_421 = Str__literal(L"unquoted");
TL_IS_422 = Str__literal(L"Structures");
TL_IS_423 = Str__literal(L"Main::");
TL_IS_424 = Str__literal(L"Tangled output generated by inweb: do not edit");
TL_IS_425 = Str__literal(L"this programming language does not support @d");
TL_IS_426 = Str__literal(L"this programming language does not support multiline @d");
TL_IS_427 = Str__literal(L"Preform");
TL_IS_428 = Str__literal(L"Preform");
TL_IS_429 = Str__literal(L"Namespaces");
TL_IS_430 = Str__literal(L"Being internally called, this function mustn't belong to a :: namespace");
TL_IS_431 = Str__literal(L"Being externally called, this function must belong to a :: namespace");
TL_IS_432 = Str__literal(L"Structures");
TL_IS_433 = Str__literal(L"program ended with conditional compilation open");
TL_IS_434 = Str__literal(L"conditional compilation too deeply nested");
TL_IS_435 = Str__literal(L"found #endif without #ifdef or #ifndef");
TL_IS_436 = Str__literal(L"Preform");
TL_IS_437 = Str__literal(L"'WR[...]' notation unavailable");
TL_IS_438 = Str__literal(L"malformed '{ , }' formula");
TL_IS_439 = Str__literal(L"fail");
TL_IS_440 = Str__literal(L"fail production");
TL_IS_441 = Str__literal(L"fail nonterminal");
TL_IS_442 = Str__literal(L"advance ");
TL_IS_443 = Str__literal(L"pass ");
TL_IS_444 = Str__literal(L"lookahead");
TL_IS_445 = Str__literal(L"-");
TL_IS_446 = Str__literal(L"-");
TL_IS_447 = Str__literal(L"most_recent_result");
TL_IS_448 = Str__literal(L"most_recent_result_p");
TL_IS_449 = Str__literal(L"Syntax.preform");
TL_IS_450 = Str__literal(L"Preform Language");
TL_IS_451 = Str__literal(L"Preform Language");
TL_IS_452 = Str__literal(L"weave tree");
TL_IS_453 = Str__literal(L"document");
TL_IS_454 = Str__literal(L"head");
TL_IS_455 = Str__literal(L"body");
TL_IS_456 = Str__literal(L"tail");
TL_IS_457 = Str__literal(L"chapter footer");
TL_IS_458 = Str__literal(L"chapter header");
TL_IS_459 = Str__literal(L"section footer");
TL_IS_460 = Str__literal(L"section header");
TL_IS_461 = Str__literal(L"section purpose");
TL_IS_462 = Str__literal(L"subheading");
TL_IS_463 = Str__literal(L"bar");
TL_IS_464 = Str__literal(L"pagebreak");
TL_IS_465 = Str__literal(L"linebreak");
TL_IS_466 = Str__literal(L"paragraph");
TL_IS_467 = Str__literal(L"endnote");
TL_IS_468 = Str__literal(L"figure");
TL_IS_469 = Str__literal(L"extract");
TL_IS_470 = Str__literal(L"audio");
TL_IS_471 = Str__literal(L"video");
TL_IS_472 = Str__literal(L"download");
TL_IS_473 = Str__literal(L"material");
TL_IS_474 = Str__literal(L"embed");
TL_IS_475 = Str__literal(L"pmac");
TL_IS_476 = Str__literal(L"vskip");
TL_IS_477 = Str__literal(L"chapter");
TL_IS_478 = Str__literal(L"section");
TL_IS_479 = Str__literal(L"code line");
TL_IS_480 = Str__literal(L"function usage");
TL_IS_481 = Str__literal(L"commentary");
TL_IS_482 = Str__literal(L"carousel slide");
TL_IS_483 = Str__literal(L"toc");
TL_IS_484 = Str__literal(L"toc line");
TL_IS_485 = Str__literal(L"chapter_title_page");
TL_IS_486 = Str__literal(L"defn");
TL_IS_487 = Str__literal(L"source_code");
TL_IS_488 = Str__literal(L"url");
TL_IS_489 = Str__literal(L"footnote_cue");
TL_IS_490 = Str__literal(L"footnote");
TL_IS_491 = Str__literal(L"display line");
TL_IS_492 = Str__literal(L"function defn");
TL_IS_493 = Str__literal(L"item");
TL_IS_494 = Str__literal(L"grammar index");
TL_IS_495 = Str__literal(L"inline");
TL_IS_496 = Str__literal(L"locale");
TL_IS_497 = Str__literal(L"mathematics");
TL_IS_498 = Str__literal(L"verbatim");
TL_IS_499 = Str__literal(L"Weave Content");
TL_IS_500 = Str__literal(L"plain");
TL_IS_501 = Str__literal(L".txt");
TL_IS_502 = Str__literal(L"TeX");
TL_IS_503 = Str__literal(L".tex");
TL_IS_504 = Str__literal(L"S");
TL_IS_505 = Str__literal(L"");
TL_IS_506 = Str__literal(L"Figures");
TL_IS_507 = Str__literal(L"weavesection");
TL_IS_508 = Str__literal(L"weavesections");
TL_IS_509 = Str__literal(L"weavesectionss");
TL_IS_510 = Str__literal(L"weavesectionsss");
TL_IS_511 = Str__literal(L"tweavesection");
TL_IS_512 = Str__literal(L"tweavesections");
TL_IS_513 = Str__literal(L"tweavesectionss");
TL_IS_514 = Str__literal(L"tweavesectionsss");
TL_IS_515 = Str__literal(L"nsweavesection");
TL_IS_516 = Str__literal(L"nsweavesections");
TL_IS_517 = Str__literal(L"HTML");
TL_IS_518 = Str__literal(L".html");
TL_IS_519 = Str__literal(L"ePub");
TL_IS_520 = Str__literal(L".html");
TL_IS_521 = Str__literal(L"");
TL_IS_522 = Str__literal(L"private copy");
TL_IS_523 = Str__literal(L"Base");
TL_IS_524 = Str__literal(L"Colours");
TL_IS_525 = Str__literal(L"");
TL_IS_526 = Str__literal(L"");
TL_IS_527 = Str__literal(L"Breadcrumbs");
TL_IS_528 = Str__literal(L"Title");
TL_IS_529 = Str__literal(L"Short Title");
TL_IS_530 = Str__literal(L"Short Title");
TL_IS_531 = Str__literal(L"index.html");
TL_IS_532 = Str__literal(L"S");
TL_IS_533 = Str__literal(L"Sequential Section Ranges");
TL_IS_534 = Str__literal(L"On");
TL_IS_535 = Str__literal(L"Figures");
TL_IS_536 = Str__literal(L"HTML");
TL_IS_537 = Str__literal(L"Unable to find this HTML extract");
TL_IS_538 = Str__literal(L"Audio");
TL_IS_539 = Str__literal(L"Video");
TL_IS_540 = Str__literal(L"Downloads");
TL_IS_541 = Str__literal(L"Embedding");
TL_IS_542 = Str__literal(L"Download.html");
TL_IS_543 = Str__literal(L"Downloads are not supported");
TL_IS_544 = Str__literal(L"Downloads");
TL_IS_545 = Str__literal(L"Download file missing or empty");
TL_IS_546 = Str__literal(L"File Name");
TL_IS_547 = Str__literal(L"File URL");
TL_IS_548 = Str__literal(L"File Details");
TL_IS_549 = Str__literal(L" byte");
TL_IS_550 = Str__literal(L" bytes");
TL_IS_551 = Str__literal(L"kB");
TL_IS_552 = Str__literal(L"MB");
TL_IS_553 = Str__literal(L"GB");
TL_IS_554 = Str__literal(L"405");
TL_IS_555 = Str__literal(L"720");
TL_IS_556 = Str__literal(L"Embedding");
TL_IS_557 = Str__literal(L"This is not a supported service");
TL_IS_558 = Str__literal(L"Content ID");
TL_IS_559 = Str__literal(L"Content Width");
TL_IS_560 = Str__literal(L"Content Height");
TL_IS_561 = Str__literal(L"named-paragraph-link");
TL_IS_562 = Str__literal(L"function-link");
TL_IS_563 = Str__literal(L"Carousel");
TL_IS_564 = Str__literal(L"carousel-number");
TL_IS_565 = Str__literal(L"carousel-caption");
TL_IS_566 = Str__literal(L"carousel-caption-above");
TL_IS_567 = Str__literal(L"carousel-number-above");
TL_IS_568 = Str__literal(L"carousel-caption-below");
TL_IS_569 = Str__literal(L"carousel-number-below");
TL_IS_570 = Str__literal(L"external");
TL_IS_571 = Str__literal(L"internal");
TL_IS_572 = Str__literal(L"Popups");
TL_IS_573 = Str__literal(L"*");
TL_IS_574 = Str__literal(L"paragraph-anchor");
TL_IS_575 = Str__literal(L"Title");
TL_IS_576 = Str__literal(L"Base");
TL_IS_577 = Str__literal(L"Base.css");
TL_IS_578 = Str__literal(L"TestingInweb");
TL_IS_579 = Str__literal(L".txt");
TL_IS_580 = Str__literal(L".pdf");
TL_IS_581 = Str__literal(L"not");
TL_IS_582 = Str__literal(L"leq");
TL_IS_583 = Str__literal(L"geq");
TL_IS_584 = Str__literal(L"sim");
TL_IS_585 = Str__literal(L"hbox");
TL_IS_586 = Str__literal(L"left");
TL_IS_587 = Str__literal(L"right");
TL_IS_588 = Str__literal(L"Rightarrow");
TL_IS_589 = Str__literal(L"Leftrightarrow");
TL_IS_590 = Str__literal(L"to");
TL_IS_591 = Str__literal(L"rightarrow");
TL_IS_592 = Str__literal(L"longrightarrow");
TL_IS_593 = Str__literal(L"leftarrow");
TL_IS_594 = Str__literal(L"longleftarrow");
TL_IS_595 = Str__literal(L"lbrace");
TL_IS_596 = Str__literal(L"mid");
TL_IS_597 = Str__literal(L"rbrace");
TL_IS_598 = Str__literal(L"cdot");
TL_IS_599 = Str__literal(L"cdots");
TL_IS_600 = Str__literal(L"dots");
TL_IS_601 = Str__literal(L"times");
TL_IS_602 = Str__literal(L"quad");
TL_IS_603 = Str__literal(L"qquad");
TL_IS_604 = Str__literal(L"TeX");
TL_IS_605 = Str__literal(L"neq");
TL_IS_606 = Str__literal(L"noteq");
TL_IS_607 = Str__literal(L"ell");
TL_IS_608 = Str__literal(L"log");
TL_IS_609 = Str__literal(L"exp");
TL_IS_610 = Str__literal(L"sin");
TL_IS_611 = Str__literal(L"cos");
TL_IS_612 = Str__literal(L"tan");
TL_IS_613 = Str__literal(L"top");
TL_IS_614 = Str__literal(L"Alpha");
TL_IS_615 = Str__literal(L"Beta");
TL_IS_616 = Str__literal(L"Gamma");
TL_IS_617 = Str__literal(L"Delta");
TL_IS_618 = Str__literal(L"Epsilon");
TL_IS_619 = Str__literal(L"Zeta");
TL_IS_620 = Str__literal(L"Eta");
TL_IS_621 = Str__literal(L"Theta");
TL_IS_622 = Str__literal(L"Iota");
TL_IS_623 = Str__literal(L"Kappa");
TL_IS_624 = Str__literal(L"Lambda");
TL_IS_625 = Str__literal(L"Mu");
TL_IS_626 = Str__literal(L"Nu");
TL_IS_627 = Str__literal(L"Xi");
TL_IS_628 = Str__literal(L"Omicron");
TL_IS_629 = Str__literal(L"Pi");
TL_IS_630 = Str__literal(L"Rho");
TL_IS_631 = Str__literal(L"Varsigma");
TL_IS_632 = Str__literal(L"Sigma");
TL_IS_633 = Str__literal(L"Tau");
TL_IS_634 = Str__literal(L"Upsilon");
TL_IS_635 = Str__literal(L"Phi");
TL_IS_636 = Str__literal(L"Chi");
TL_IS_637 = Str__literal(L"Psi");
TL_IS_638 = Str__literal(L"Omega");
TL_IS_639 = Str__literal(L"alpha");
TL_IS_640 = Str__literal(L"beta");
TL_IS_641 = Str__literal(L"gamma");
TL_IS_642 = Str__literal(L"delta");
TL_IS_643 = Str__literal(L"epsilon");
TL_IS_644 = Str__literal(L"zeta");
TL_IS_645 = Str__literal(L"eta");
TL_IS_646 = Str__literal(L"theta");
TL_IS_647 = Str__literal(L"iota");
TL_IS_648 = Str__literal(L"kappa");
TL_IS_649 = Str__literal(L"lambda");
TL_IS_650 = Str__literal(L"mu");
TL_IS_651 = Str__literal(L"nu");
TL_IS_652 = Str__literal(L"xi");
TL_IS_653 = Str__literal(L"omicron");
TL_IS_654 = Str__literal(L"pi");
TL_IS_655 = Str__literal(L"rho");
TL_IS_656 = Str__literal(L"varsigma");
TL_IS_657 = Str__literal(L"sigma");
TL_IS_658 = Str__literal(L"tau");
TL_IS_659 = Str__literal(L"upsilon");
TL_IS_660 = Str__literal(L"phi");
TL_IS_661 = Str__literal(L"chi");
TL_IS_662 = Str__literal(L"psi");
TL_IS_663 = Str__literal(L"omega");
TL_IS_664 = Str__literal(L"exists");
TL_IS_665 = Str__literal(L"in");
TL_IS_666 = Str__literal(L"forall");
TL_IS_667 = Str__literal(L"cap");
TL_IS_668 = Str__literal(L"emptyset");
TL_IS_669 = Str__literal(L"subseteq");
TL_IS_670 = Str__literal(L"land");
TL_IS_671 = Str__literal(L"lor");
TL_IS_672 = Str__literal(L"lnot");
TL_IS_673 = Str__literal(L"sum");
TL_IS_674 = Str__literal(L"prod");
TL_IS_675 = Str__literal(L"n");
TL_IS_676 = Str__literal(L"t");
TL_IS_677 = Str__literal(L"exists");
TL_IS_678 = Str__literal(L"forall");
TL_IS_679 = Str__literal(L"platform-settings");
TL_IS_680 = Str__literal(L"identity-settings");
TL_IS_681 = Str__literal(L"modify-filenames");
TL_IS_682 = Str__literal(L"original: ORIGINAL ?suffix: SUFFIX ?prefix: PREFIX");
TL_IS_683 = Str__literal(L"component");
TL_IS_684 = Str__literal(L"symbol: SYMBOL webname: WEBNAME path: PATH set: SET type: TYPE");
TL_IS_685 = Str__literal(L"dependent-files");
TL_IS_686 = Str__literal(L"?tool: TOOL ?module: MODULES ?tool-and-modules: BOTH");
TL_IS_687 = Str__literal(L"components");
TL_IS_688 = Str__literal(L"type: TYPE ?set: SET");
TL_IS_689 = Str__literal(L"intest");
TL_IS_690 = Str__literal(L"platform-settings.mk");
TL_IS_691 = Str__literal(L"Materials");
TL_IS_692 = Str__literal(L"platforms");
TL_IS_693 = Str__literal(L"tool");
TL_IS_694 = Str__literal(L"web");
TL_IS_695 = Str__literal(L"module");
TL_IS_696 = Str__literal(L"SYMBOL");
TL_IS_697 = Str__literal(L"all");
TL_IS_698 = Str__literal(L"tool");
TL_IS_699 = Str__literal(L"web");
TL_IS_700 = Str__literal(L"module");
TL_IS_701 = Str__literal(L"all");
TL_IS_702 = Str__literal(L"basics");
TL_IS_703 = Str__literal(L"default.giscript");
TL_IS_704 = Str__literal(L"tags");
TL_IS_705 = Str__literal(L"bibliographic");
TL_IS_706 = Str__literal(L"datum: DATUM of: ASSET");
TL_IS_707 = Str__literal(L"Build Date");
TL_IS_708 = Str__literal(L"Version Number");
TL_IS_709 = Str__literal(L"Build Date");
TL_IS_710 = Str__literal(L"Version Number");
TL_IS_711 = Str__literal(L"inform6");
TL_IS_712 = Str__literal(L"header.h");
TL_IS_713 = Str__literal(L"(manifest).txt");
TL_IS_714 = Str__literal(L"README.txt");
TL_IS_715 = Str__literal(L"README.md");
TL_IS_716 = Str__literal(L"docs");
TL_IS_717 = Str__literal(L"web");
TL_IS_718 = Str__literal(L"module");
TL_IS_719 = Str__literal(L".inweb");
TL_IS_720 = Str__literal(L".inweb");
TL_IS_721 = Str__literal(L"docs");
TL_IS_722 = Str__literal(L"Multiple cross-references might be meant here");
TL_IS_723 = Str__literal(L"(main)");
}