#ifndef PLATFORM_WINDOWS #define PLATFORM_POSIX #endif /* Tangled output generated by inweb: do not edit */ #include #include #include #include #include #include #include #ifdef PLATFORM_POSIX #include #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #include #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_WINDOWS #include #endif /* PLATFORM_WINDOWS */ #line 42 "inweb/foundation-module/Chapter 1/Foundation Module.w" #include #line 48 "inweb/foundation-module/Chapter 1/Foundation Module.w" #include #ifdef PLATFORM_POSIX #line 25 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #include #line 28 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #include #line 31 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_UNIX #ifdef PLATFORM_POSIX #line 49 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #endif /* PLATFORM_UNIX */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_LINUX #ifdef PLATFORM_POSIX #line 61 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #endif /* PLATFORM_LINUX */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_ANDROID #ifdef PLATFORM_POSIX #line 71 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #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 #endif /* PLATFORM_LINUX */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX #line 422 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_WINDOWS #line 19 "inweb/foundation-module/Chapter 1/Windows Platform.w" #include #line 21 "inweb/foundation-module/Chapter 1/Windows Platform.w" #include #include #define WIN32_LEAN_AND_MEAN #include #include #include #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., || */ 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 #include 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; ahyphenated_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; aon_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; inegated_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; ion_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; ion_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; ithe_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 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 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 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)) 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 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= 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; jchars_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; jchars_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; jchars_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; istream_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, "
"); return; case '&': Streams__literal(stream, "&"); return; case '<': Streams__literal(stream, "<"); return; case '>': Streams__literal(stream, ">"); 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; ichars_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; ihash_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; ihash_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=", 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; ihash_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; ihash_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; iline_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; iswitch_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; filterswitch_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; iswitch_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 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(""); 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; itm_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; istages_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]) && (icapacity = (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 L1) || (N > L2)) return FALSE; for (int i=0; i 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 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; iloop_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; ino_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; ino_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; ino_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; ino_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; iexp[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; iexp_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; iexp[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= 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 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(""); break; default: WRITE("", 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=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= 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= 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) 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=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= 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=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; ivalue; } 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 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= 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= 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("", 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("    "); } } 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("\n"); HTML_OPEN_WITH("html", "xmlns=\"http://www.w3.org/1999/xhtml\""); } else { WRITE("\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"); 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(" 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("    "); 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(" "); 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("    "); 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(" "); 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("    "); 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(" "); 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(" "); 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("\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("&"); break; case '<': WRITE("<"); break; case '>': WRITE(">"); 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("""); break; case '<': WRITE("<"); break; case '>': WRITE(">"); break; case '&': WRITE("&"); 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(" "); 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("\n"); WRITE("\n"); INDENT; WRITE("\n"); INDENT; WRITE("\n"); OUTDENT; WRITE("\n"); OUTDENT; WRITE("\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("\n"); WRITE("\n"); INDENT; { #line 357 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" WRITE("\n"); INDENT; ebook_datum *D = NULL; LOOP_OVER_LINKED_LIST(D, ebook_datum, B->metadata_list) { WRITE("key); if (Str__eq_wide_string(D->key, L"identifier")) WRITE(" id=\"bookid\""); WRITE(">"); WRITE("%S\n", D->value, D->key); } WRITE("\n"); OUTDENT; WRITE("\n"); } #line 345 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; { #line 369 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" WRITE("\n"); INDENT; WRITE("\n"); { #line 377 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" int cssc = 1; if (B->CSS_file_throughout) WRITE("\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("\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("\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("\n", I->image_ID, I->relative_URL, image_type); } } #line 373 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; OUTDENT; WRITE("\n"); } #line 346 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; { #line 409 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" WRITE("\n"); INDENT; ebook_page *P; LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) { WRITE("page_ID); if (Str__len(P->page_type) > 0) WRITE(" linear=\"no\""); WRITE("/>\n"); } OUTDENT; WRITE("\n"); } #line 347 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; { #line 419 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" WRITE("\n"); INDENT; ebook_page *P; LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) { if (Str__len(P->page_type) > 0) { WRITE("\n", Filenames__get_leafname(P->relative_URL), P->page_type, P->page_title); } } OUTDENT; WRITE("\n"); } #line 348 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; OUTDENT; WRITE("\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("\n"); WRITE("\n"); WRITE("\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("\n"); INDENT; WRITE("\n", Epub__get_metadata(B, L"identifier")); WRITE("\n", depth); WRITE("\n"); WRITE("\n"); OUTDENT; WRITE("\n"); WRITE("\n"); INDENT; WRITE("%S\n", Epub__get_metadata(B, L"title")); OUTDENT; WRITE("\n"); } #line 449 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; { #line 467 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" WRITE("\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("\n", navpoint_count, navpoint_count); navpoint_count++; navmap_depth++; INDENT; } #line 493 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; WRITE("%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("\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("\n", navpoint_count, navpoint_count); navpoint_count++; navmap_depth++; INDENT; } #line 474 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; WRITE("%S", V->volume_title); WRITE("\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("\n", navpoint_count, navpoint_count); navpoint_count++; navmap_depth++; INDENT; } #line 504 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; WRITE("%S", C->chapter_title); WRITE("\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("\n", navpoint_count, navpoint_count); navpoint_count++; navmap_depth++; INDENT; } #line 533 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; WRITE("%S", M->mark_text); WRITE("\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("\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("\n", navpoint_count, navpoint_count); navpoint_count++; navmap_depth++; INDENT; } #line 522 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; WRITE("%S", P->page_title); WRITE("\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("\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("\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("\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("\n", navpoint_count, navpoint_count); navpoint_count++; navmap_depth++; INDENT; } #line 493 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; WRITE("%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("\n"); } #line 496 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; } } } #line 481 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; OUTDENT; WRITE("\n"); if (navmap_depth != 1) internal_error("navMap numbering unbalanced"); } #line 450 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" ; WRITE("\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= 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 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 : Title', " "'Appendix : 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; ias_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; iweave_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; ipre); 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; ipost); 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); ianalysed) 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; ianalysis_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: %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; jsp; 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, "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, ""); WRITE_TO(substituted, "

%S

    ", 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, "
      "); cls->inside_navigation_submenu = TRUE; WRITE_TO(substituted, "
    • "); if (Str__eq(url, Filenames__get_leafname(cls->into_file))) { WRITE_TO(substituted, ""); { #line 736 "inweb/Chapter 3/The Collater.w" if (Str__len(icon_text) > 0) { WRITE_TO(substituted, "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, ""); } else if (Str__eq(url, TL_IS_282)) { WRITE_TO(substituted, "", url); WRITE_TO(substituted, ""); { #line 736 "inweb/Chapter 3/The Collater.w" if (Str__len(icon_text) > 0) { WRITE_TO(substituted, "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, ""); WRITE_TO(substituted, ""); } else { WRITE_TO(substituted, "", url); { #line 736 "inweb/Chapter 3/The Collater.w" if (Str__len(icon_text) > 0) { WRITE_TO(substituted, "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, ""); } WRITE_TO(substituted, "
    • "); } #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, ""); 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; iap); 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; iextract_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; ifirst_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; idefining_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; isect_language, temp); for (int i=0; isect_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; ilanguage_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')) 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= 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; istring_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; jwhole_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; imain_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); icharacter_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) && (ibinary_literal_prefix)) { base = 2; for (int j=0; jbinary_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; joctal_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; jhexadecimal_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; jchar_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; imr.exp[i]) Str__clear(block->mr.exp[i]); if (Regexp__match(&(block->mr), matter, block->match_regexp_text)) for (int count=1, i=0; imr.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; ifix_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; iwithin_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; ino_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; itangled != 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"takes_pointer_result = TRUE; if (Regexp__match(&mr, pnt->nt_name, L"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> = *(%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 0) { for (int j=0; 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; jmatter = 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; idepth; 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("❮"); 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("❯"); 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("\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("