#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 47 "inweb/foundation-module/Chapter 1/Foundation.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 130 "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 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" p[0] = '\0'; return; #endif /* PLATFORM_POSIX */ } #line 140 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" ; /* Convert to canonical absolute path */ if (realpath(relative_path, absolute_path) == NULL) { #ifdef PLATFORM_POSIX #line 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" p[0] = '\0'; return; #endif /* PLATFORM_POSIX */ } #line 143 "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 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" p[0] = '\0'; return; #endif /* PLATFORM_POSIX */ } #line 148 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" ; } #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 340 "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_WINDOWS #line 20 "inweb/foundation-module/Chapter 1/Windows Platform.w" #include #include #line 23 "inweb/foundation-module/Chapter 1/Windows Platform.w" #include #include #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 50 "inweb/foundation-module/Chapter 1/Windows Platform.w" unsigned long __stdcall GetCurrentDirectoryA(unsigned long len, char* buffer); unsigned long __stdcall SHGetFolderPathA(unsigned long wnd, int folder, unsigned long token, unsigned long flags, char* path); char *Platform__getenv(const char *name) { static char env[260]; env[0] = 0; if (strcmp(name,"PWD") == 0) { if (GetCurrentDirectoryA(260,env) > 0) return env; } else if (strcmp(name,"HOME") == 0) { if (SHGetFolderPathA(0,5,0,0,env) == 0) return env; } return getenv(name); } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 82 "inweb/foundation-module/Chapter 1/Windows Platform.w" struct Win32_Startup_Info { long v1; char* v2; char* v3; char* v4; long v5; long v6; long v7; long v8; long v9; long v10; long v11; unsigned long flags; unsigned short showWindow; short v12; char* v13; long v14; long v15; long v16; }; struct Win32_Process_Info { unsigned long process; unsigned long thread; long v1; long v2; }; unsigned long __stdcall CloseHandle(unsigned long handle); unsigned long __stdcall WaitForSingleObject(unsigned long handle, unsigned long ms); unsigned long __stdcall CreateProcessA(void* app, char* cmd, void* pa, void* ta, long inherit, unsigned long flags, void* env, void* dir, struct Win32_Startup_Info* start, struct Win32_Process_Info* process); unsigned long __stdcall GetExitCodeProcess(unsigned long proc, unsigned long* code); int Platform__system(const char *cmd) { if (strncmp(cmd,"md5 ", 4) == 0) return 0; char cmdline[4096]; sprintf(cmdline,"cmd /s /c \"%s\"", cmd); struct Win32_Startup_Info start = { sizeof (struct Win32_Startup_Info), 0 }; start.flags = 1; start.showWindow = 0; struct Win32_Process_Info process; if (CreateProcessA(0, cmdline, 0, 0, 0, 0x8000000, 0, 0, &start, &process) == 0) return -1; CloseHandle(process.thread); if (WaitForSingleObject(process.process, -1) != 0) { CloseHandle(process.process); return -1; } unsigned long code = 10; GetExitCodeProcess(process.process, &code); CloseHandle(process.process); return code; } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 165 "inweb/foundation-module/Chapter 1/Windows Platform.w" void __stdcall Sleep(unsigned long ms); void Platform__sleep(int seconds) { Sleep((unsigned long) 1000*seconds); } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 180 "inweb/foundation-module/Chapter 1/Windows Platform.w" unsigned long __stdcall CreateThread(void* attrs, unsigned long stack, void* func, void* param, unsigned long flags, unsigned long* id); struct Win32_Thread_Attrs {}; struct Win32_Thread_Start { void *(*fn)(void *); void* arg; }; typedef unsigned long foundation_thread; typedef struct Win32_Thread_Attrs foundation_thread_attributes; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 250 "inweb/foundation-module/Chapter 1/Windows Platform.w" struct Win32_Critical_Section { void* v1; long v2; long v3; long v4; long v5; void* v6; }; void __stdcall EnterCriticalSection(struct Win32_Critical_Section* cs); void __stdcall LeaveCriticalSection(struct Win32_Critical_Section* cs); #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 #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 HTML_MAP_FONT_SIZE 11 #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #define isdigit(x) Platform__Windows_isdigit(x) #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #define CREATE_MUTEX(name) \ struct Win32_Critical_Section name { (void*)-1, -1, 0, 0, 0, 0 }; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #define LOCK_MUTEX(name) EnterCriticalSection(&name); #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #define UNLOCK_MUTEX(name) LeaveCriticalSection(&name); #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 MEMORY_MANAGEMENT \ 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 filename_MT 0 #define pathname_MT 1 #define string_storage_area_MT 2 #define scan_directory_MT 3 #define ebook_MT 4 #define ebook_datum_MT 5 #define ebook_volume_MT 6 #define ebook_chapter_MT 7 #define ebook_page_MT 8 #define ebook_image_MT 9 #define HTML_file_state_MT 10 #define HTML_tag_array_MT 11 #define text_stream_array_MT 12 #define command_line_switch_MT 13 #define dictionary_MT 14 #define dict_entry_array_MT 15 #define debugging_aspect_MT 16 #define linked_list_MT 17 #define linked_list_item_array_MT 18 #define match_avinue_array_MT 19 #define match_trie_array_MT 20 #define method_MT 21 #define method_set_MT 22 #define ebook_mark_MT 23 #define semantic_version_number_holder_MT 24 #define semver_range_MT 25 #define web_md_MT 26 #define chapter_md_MT 27 #define section_md_MT 28 #define web_bibliographic_datum_MT 29 #define module_MT 30 #define module_search_MT 31 #define SAFETY_MARGIN 128 #define BLANK_END_SIZE 256 #define MAX_BLOCKS_ALLOWED 15000 #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##_MT].first_in_memory) #define LAST_OBJECT(type_name) ((type_name *) alloc_status[type_name##_MT].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##_MT].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##_MT, sizeof(type_name))) #define ALLOCATE_INDIVIDUALLY(type_name) \ MAKE_REFERENCE_ROUTINES(type_name, type_name##_MT)\ type_name *allocate_##type_name(void) {\ CREATE_MUTEX(mutex);\ LOCK_MUTEX(mutex);\ alloc_status[type_name##_MT].name_of_type = #type_name;\ type_name *prev_obj = LAST_OBJECT(type_name);\ type_name *new_obj = NEW_OBJECT(type_name);\ new_obj->allocation_id = alloc_status[type_name##_MT].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[type_name##_MT].objects_count++;\ UNLOCK_MUTEX(mutex);\ return new_obj;\ }\ void deallocate_##type_name(type_name *kill_me) {\ CREATE_MUTEX(mutex);\ LOCK_MUTEX(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[type_name##_MT].first_in_memory = next_obj;\ } else {\ prev_obj->next_structure = next_obj;\ }\ if (next_obj == NULL) {\ alloc_status[type_name##_MT].last_in_memory = prev_obj;\ } else {\ next_obj->prev_structure = prev_obj;\ }\ alloc_status[type_name##_MT].objects_count--;\ UNLOCK_MUTEX(mutex);\ }\ type_name *allocate_##type_name##_before(type_name *existing) {\ CREATE_MUTEX(mutex);\ LOCK_MUTEX(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[type_name##_MT].first_in_memory = (void *) new_obj;\ new_obj->next_structure = existing;\ existing->prev_structure = new_obj;\ alloc_status[type_name##_MT].objects_count++;\ UNLOCK_MUTEX(mutex);\ return new_obj;\ }\ void copy_##type_name(type_name *to, type_name *from) {\ CREATE_MUTEX(mutex);\ LOCK_MUTEX(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(mutex);\ } #define ALLOCATE_IN_ARRAYS(type_name, NO_TO_ALLOCATE_TOGETHER)\ MAKE_REFERENCE_ROUTINES(type_name, type_name##_array_MT)\ typedef struct type_name##_array {\ int used;\ struct type_name array[NO_TO_ALLOCATE_TOGETHER];\ MEMORY_MANAGEMENT\ } type_name##_array;\ ALLOCATE_INDIVIDUALLY(type_name##_array)\ type_name##_array *next_##type_name##_array = NULL;\ struct type_name *allocate_##type_name(void) {\ CREATE_MUTEX(mutex);\ LOCK_MUTEX(mutex);\ if ((next_##type_name##_array == NULL) ||\ (next_##type_name##_array->used >= NO_TO_ALLOCATE_TOGETHER)) {\ alloc_status[type_name##_array_MT].no_allocated_together = NO_TO_ALLOCATE_TOGETHER;\ next_##type_name##_array = allocate_##type_name##_array();\ next_##type_name##_array->used = 0;\ }\ UNLOCK_MUTEX(mutex);\ return &(next_##type_name##_array->array[\ next_##type_name##_array->used++]);\ } #define STREAM_MREASON 0 #define FILENAME_STORAGE_MREASON 1 #define STRING_STORAGE_MREASON 2 #define DICTIONARY_MREASON 3 #define CLS_SORTING_MREASON 4 #define SSA_CAPACITY 64*1024 #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 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 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 METHOD_CALLS \ struct method_set *methods; #define ENABLE_METHOD_CALLS(obj) \ obj->methods = Methods__new_set(); #define UNUSED_METHOD_ID_MTID 1 #define IMETHOD_TYPE(id, args...)\ typedef int (*id##_type)(args); #define VMETHOD_TYPE(id, args...)\ typedef void (*id##_type)(args); #define METHOD_ADD(upon, id, func)\ Methods__add(upon->methods, id, (void *) &func); #define IMETHOD_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 IMETHOD_CALLV(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 VMETHOD_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 VMETHOD_CALLV(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 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_CLASS 1 #define DIGIT_CLASS 2 #define WHITESPACE_CLASS 3 #define NONWHITESPACE_CLASS 4 #define IDENTIFIER_CLASS 5 #define PREFORM_CLASS 6 #define PREFORMC_CLASS 7 #define LITERAL_CLASS 8 #define TAB_CLASS 9 #define QUOTE_CLASS 10 #define REP_REPEATING 1 #define REP_ATSTART 2 #define tag_error(x) { LOG("Tag error: %s\n", x); } #define HTML_TAG(tag) HTML__tag(OUT, tag, NULL); #define HTML_OPEN(tag) HTML__open(OUT, tag, NULL); #define HTML_CLOSE(tag) HTML__close(OUT, tag); #define CORNER_SIZE 8 /* measured in pixels */ #define ROUND_BOX_TOP 1 #define ROUND_BOX_BOTTOM 2 #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 INTOOL_NAME "inweb" #define INWEB_BUILD "7" #define breadcrumb_request_MT 32 #define c_structure_MT 33 #define chapter_MT 34 #define colouring_rule_MT 35 #define enumeration_set_MT 36 #define function_MT 37 #define hash_table_entry_MT 38 #define hash_table_entry_usage_MT 39 #define colouring_language_block_MT 40 #define macro_MT 41 #define macro_tokens_MT 42 #define macro_usage_MT 43 #define nonterminal_variable_MT 44 #define para_macro_MT 45 #define paragraph_MT 46 #define paragraph_tagging_MT 47 #define preform_nonterminal_MT 48 #define programming_language_MT 49 #define reserved_word_MT 50 #define section_MT 51 #define source_line_array_MT 52 #define structure_element_MT 53 #define tangle_target_MT 54 #define tex_results_MT 55 #define text_literal_MT 56 #define theme_tag_MT 57 #define weave_format_MT 58 #define weave_pattern_MT 59 #define weave_target_MT 60 #define web_MT 61 #define writeme_asset_MT 62 #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 6 #define IMPORT_FROM_CLSW 7 #define LANGUAGES_CLSG 2 #define LANGUAGE_CLSW 8 #define LANGUAGES_CLSW 9 #define SHOW_LANGUAGES_CLSW 10 #define ANALYSIS_CLSG 3 #define CATALOGUE_CLSW 11 #define FUNCTIONS_CLSW 12 #define STRUCTURES_CLSW 13 #define ADVANCE_CLSW 14 #define GITIGNORE_CLSW 15 #define MAKEFILE_CLSW 16 #define WRITEME_CLSW 17 #define ADVANCE_FILE_CLSW 18 #define PROTOTYPE_CLSW 19 #define SCAN_CLSW 20 #define WEAVING_CLSG 4 #define WEAVE_CLSW 21 #define WEAVE_INTO_CLSW 22 #define WEAVE_TO_CLSW 23 #define SEQUENTIAL_CLSW 24 #define OPEN_CLSW 25 #define WEAVE_AS_CLSW 26 #define WEAVE_TAG_CLSW 27 #define WEAVE_DOCS_CLSW 28 #define BREADCRUMB_CLSW 29 #define NAVIGATION_CLSW 30 #define TANGLING_CLSG 5 #define TANGLE_CLSW 31 #define TANGLE_TO_CLSW 32 #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 HEADING_START_LCAT 11 #define INTERFACE_BODY_LCAT 12 #define INTERFACE_LCAT 13 #define MACRO_DEFINITION_LCAT 14 #define PARAGRAPH_START_LCAT 15 #define PREFORM_GRAMMAR_LCAT 16 #define PREFORM_LCAT 17 #define PURPOSE_BODY_LCAT 18 #define PURPOSE_LCAT 19 #define SECTION_HEADING_LCAT 20 #define SOURCE_DISPLAY_LCAT 21 #define TEXT_EXTRACT_LCAT 22 #define TYPEDEF_LCAT 23 #define NO_CMD 0 #define PAGEBREAK_CMD 1 #define GRAMMAR_INDEX_CMD 2 #define FIGURE_CMD 3 #define TAG_CMD 4 #define ORDINARY_WEIGHT 0 /* an ordinary paragraph has this "weight" */ #define SUBHEADING_WEIGHT 1 /* a heading paragraph */ #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 WEAVE_FIRST_HALF 1 #define WEAVE_SECOND_HALF 2 #define IN_SECOND_HALF 4 #define MAX_TEMPLATE_LINES 256 /* maximum number of lines in template */ #define CI_STACK_CAPACITY 8 /* maximum recursion of chapter/section iteration */ #define TRACE_CI_EXECUTION FALSE /* set true for debugging */ #define CHAPTER_LEVEL 1 #define SECTION_LEVEL 2 #define REGULAR_MATERIAL 1 #define MACRO_MATERIAL 2 #define DEFINITION_MATERIAL 3 #define CODE_MATERIAL 4 #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 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 INSTANCES_CRULE_RUN -3 /* This block applies to each instance in turn */ #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 DEFINITION_COLOUR 'd' #define FUNCTION_COLOUR 'f' #define RESERVED_COLOUR 'r' #define ELEMENT_COLOUR 'e' #define IDENTIFIER_COLOUR 'i' #define CHAR_LITERAL_COLOUR 'c' #define CONSTANT_COLOUR 'n' #define STRING_COLOUR 's' #define PLAIN_COLOUR 'p' #define EXTRACT_COLOUR 'x' #define COMMENT_COLOUR '!' #define NOT_A_COLOUR ' ' #define UNQUOTED_COLOUR '_' #define FURTHER_PARSING_PAR_MTID 2 #define SUBCATEGORISE_LINE_PAR_MTID 3 #define PARSE_COMMENT_TAN_MTID 4 #define SHEBANG_TAN_MTID 5 #define SUPPRESS_DISCLAIMER_TAN_MTID 6 #define ADDITIONAL_EARLY_MATTER_TAN_MTID 7 #define START_DEFN_TAN_MTID 8 #define PROLONG_DEFN_TAN_MTID 9 #define END_DEFN_TAN_MTID 10 #define ADDITIONAL_PREDECLARATIONS_TAN_MTID 11 #define SUPPRESS_EXPANSION_TAN_MTID 12 #define TANGLE_COMMAND_TAN_MTID 13 #define WILL_TANGLE_EXTRA_LINE_TAN_MTID 14 #define TANGLE_EXTRA_LINE_TAN_MTID 15 #define INSERT_LINE_MARKER_TAN_MTID 16 #define BEFORE_MACRO_EXPANSION_TAN_MTID 17 #define AFTER_MACRO_EXPANSION_TAN_MTID 18 #define OPEN_IFDEF_TAN_MTID 19 #define CLOSE_IFDEF_TAN_MTID 20 #define COMMENT_TAN_MTID 21 #define TANGLE_CODE_UNUSUALLY_TAN_MTID 22 #define GNABEHS_TAN_MTID 23 #define ADDITIONAL_TANGLING_TAN_MTID 24 #define BEGIN_WEAVE_WEA_MTID 25 #define SKIP_IN_WEAVING_WEA_MTID 26 #define RESET_SYNTAX_COLOURING_WEA_MTID 27 #define SYNTAX_COLOUR_WEA_MTID 28 #define WEAVE_CODE_LINE_WEA_MTID 29 #define NOTIFY_NEW_TAG_WEA_MTID 30 #define CATALOGUE_ANA_MTID 31 #define EARLY_PREWEAVE_ANALYSIS_ANA_MTID 32 #define LATE_PREWEAVE_ANALYSIS_ANA_MTID 33 #define SHARE_ELEMENT_ANA_MTID 34 #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 BEGIN_WEAVING_FOR_MTID 35 #define END_WEAVING_FOR_MTID 36 #define TOP_FOR_MTID 37 #define TOC_FOR_MTID 38 #define CHAPTER_TP_FOR_MTID 39 #define SUBHEADING_FOR_MTID 40 #define PARAGRAPH_HEADING_FOR_MTID 41 #define SOURCE_CODE_FOR_MTID 42 #define INLINE_CODE_FOR_MTID 43 #define DISPLAY_LINE_FOR_MTID 44 #define ITEM_FOR_MTID 45 #define BAR_FOR_MTID 46 #define FIGURE_FOR_MTID 47 #define PARA_MACRO_FOR_MTID 48 #define PAGEBREAK_FOR_MTID 49 #define BLANK_LINE_FOR_MTID 50 #define AFTER_DEFINITIONS_FOR_MTID 51 #define CHANGE_MATERIAL_FOR_MTID 52 #define CHANGE_COLOUR_FOR_MTID 53 #define COMMENTARY_TEXT_FOR_MTID 54 #define PRESERVE_MATH_MODE_FOR_MTID 55 #define PREFORM_DOCUMENT_FOR_MTID 56 #define ENDNOTE_FOR_MTID 57 #define LOCALE_FOR_MTID 58 #define TAIL_FOR_MTID 59 #define POST_PROCESS_POS_MTID 60 #define POST_PROCESS_REPORT_POS_MTID 61 #define INDEX_PDFS_POS_MTID 62 #define POST_PROCESS_SUBSTITUTE_POS_MTID 63 #define HTML_OUT 0 /* write position in HTML file is currently outside of p, pre, li */ #define HTML_IN_P 1 /* write position in HTML file is currently outside p */ #define HTML_IN_PRE 2 /* write position in HTML file is currently outside pre */ #define HTML_IN_LI 3 /* write position in HTML file is currently outside li */ #define NO_DEFINED_CLSW_VALUES 33 #define NO_DEFINED_DA_VALUES 4 #define NO_DEFINED_MT_VALUES 63 #define NO_DEFINED_MREASON_VALUES 5 #define NO_DEFINED_MTID_VALUES 63 #define NO_DEFINED_CLSF_VALUES 5 #define NO_DEFINED_CLSG_VALUES 6 #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_LCAT_VALUES 24 #define NO_DEFINED_CMD_VALUES 5 #define NO_DEFINED_SECTIONCAT_VALUES 3 #define NO_DEFINED_MATERIAL_VALUES 4 #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 */ MEMORY_MANAGEMENT } debugging_aspect; #line 87 "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., |"lexicon_entry_MT"| */ 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 169 "inweb/foundation-module/Chapter 2/Memory.w" typedef struct memblock_header { int block_number; struct memblock_header *next; char *the_memory; } memblock_header; #line 251 "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 700 "inweb/foundation-module/Chapter 2/Memory.w" typedef struct string_storage_area { char *storage_at; int first_free_byte; MEMORY_MANAGEMENT } string_storage_area; #line 879 "inweb/foundation-module/Chapter 2/Memory.w" typedef struct general_pointer { void *pointer_to_data; int run_time_type_code; } general_pointer; #line 233 "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 36 "inweb/foundation-module/Chapter 2/Methods.w" typedef struct method_set { struct method *first_method; MEMORY_MANAGEMENT } method_set; #line 78 "inweb/foundation-module/Chapter 2/Methods.w" typedef struct method { int method_id; void *method_function; struct method *next_method; MEMORY_MANAGEMENT } method; #line 23 "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; struct linked_list_item early_items[NO_LL_EARLY_ITEMS]; MEMORY_MANAGEMENT } 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 */ MEMORY_MANAGEMENT } 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 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 */ MEMORY_MANAGEMENT } 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 */ MEMORY_MANAGEMENT } pathname; #line 14 "inweb/foundation-module/Chapter 3/Filenames.w" typedef struct filename { struct pathname *pathname_of_location; struct text_stream *leafname; MEMORY_MANAGEMENT } 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]; MEMORY_MANAGEMENT } scan_directory; #line 159 "inweb/foundation-module/Chapter 4/String Manipulation.w" typedef struct string_position { struct text_stream *S; int index; } string_position; #line 208 "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 26 "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 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]; } match_results; #line 20 "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; MEMORY_MANAGEMENT } HTML_file_state; #line 43 "inweb/foundation-module/Chapter 5/HTML.w" typedef struct HTML_tag { char *tag_name; int tag_xref; MEMORY_MANAGEMENT } HTML_tag; #line 583 "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| */ MEMORY_MANAGEMENT } ebook; #line 48 "inweb/foundation-module/Chapter 5/Epub Ebooks.w" typedef struct ebook_datum { struct text_stream *key; struct text_stream *value; MEMORY_MANAGEMENT } 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 */ MEMORY_MANAGEMENT } 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; MEMORY_MANAGEMENT } 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 */ MEMORY_MANAGEMENT } 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; MEMORY_MANAGEMENT } 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 */ MEMORY_MANAGEMENT } ebook_image; #line 61 "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 67 "inweb/foundation-module/Chapter 7/Version Numbers.w" typedef struct semantic_version_number_holder { struct semantic_version_number version; MEMORY_MANAGEMENT } 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; MEMORY_MANAGEMENT } 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| */ MEMORY_MANAGEMENT } 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 *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| */ MEMORY_MANAGEMENT } chapter_md; #line 66 "inweb/foundation-module/Chapter 8/Web Structure.w" typedef struct section_md { struct text_stream *sect_title; /* e.g., "Program Control" */ 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; MEMORY_MANAGEMENT } section_md; #line 151 "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_folder_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; MEMORY_MANAGEMENT } 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 *sections_md; /* of |section_md|: just the ones in this module */ MEMORY_MANAGEMENT } module; #line 71 "inweb/foundation-module/Chapter 8/Web Modules.w" typedef struct module_search { struct pathname *path_to_search; MEMORY_MANAGEMENT } 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 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_format; /* |-weave-as X|: for example, |-weave-as TeX| */ struct text_stream *weave_pattern; /* |-weave-to X|: for example, |-weave-to HTML| */ int weave_docs; /* |-docs|: for GitHub Pages */ 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 open_pdf_switch; /* |-open-pdf|: open any woven PDF in the OS once it is made */ int scan_switch; /* |-scan|: simply show the syntactic scan of the source */ 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 *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 linked_list *breadcrumb_setting; /* of |breadcrumb_request| */ int verbose_switch; /* |-verbose|: print names of files read to stdout */ int targets; /* used only for parsing */ struct pathname *import_setting; /* |-import X|: where to find imported webs */ } inweb_instructions; #line 48 "inweb/Chapter 1/Configuration.w" typedef struct breadcrumb_request { struct text_stream *breadcrumb_text; struct text_stream *breadcrumb_link; MEMORY_MANAGEMENT } breadcrumb_request; #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 *payloads; /* of |text_stream|: leafnames of associated files */ struct linked_list *up_payloads; /* of |text_stream|: leafnames of associated files */ struct text_stream *tex_command; /* shell command to use for |tex| */ struct text_stream *pdftex_command; /* shell command to use for |pdftex| */ struct text_stream *open_command; /* shell command to use for |open| */ int embed_CSS; /* embed CSS directly into any HTML files made? */ int hierarchical; /* weave as one part of a collection of woven webs */ 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 */ MEMORY_MANAGEMENT } weave_pattern; #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 no_lines; /* 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 *c_structures; /* of |c_structure|: used only for C-like languages */ struct ebook *as_ebook; /* when being woven to an ebook */ struct pathname *redirect_weaves_to; /* ditto */ MEMORY_MANAGEMENT } 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_target *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 */ MEMORY_MANAGEMENT } 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" */ struct text_stream *sect_range; /* e.g., "9/tfto" */ 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_target *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 */ MEMORY_MANAGEMENT } section; #line 250 "inweb/Chapter 3/The Analyser.w" typedef struct hash_table { struct linked_list *analysis_hash[HASH_TAB_SIZE]; /* of |hash_table_entry| */ int analysis_hash_initialised; /* when we start up, array's contents are undefined */ } 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 */ MEMORY_MANAGEMENT } 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 */ struct programming_language *colour_as; /* used only for |TEXT_EXTRACT_LCAT| lines */ int is_commentary; /* flag */ struct 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 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 610 "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 */ 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 |c_structure|: similarly */ struct linked_list *taggings; /* of |paragraph_tagging| */ struct source_line *first_line_in_paragraph; struct section *under_section; MEMORY_MANAGEMENT } paragraph; #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 */ MEMORY_MANAGEMENT } 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; MEMORY_MANAGEMENT } theme_tag; #line 50 "inweb/Chapter 2/Tags.w" typedef struct paragraph_tagging { struct theme_tag *the_tag; struct text_stream *caption; MEMORY_MANAGEMENT } 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; MEMORY_MANAGEMENT } 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 */ MEMORY_MANAGEMENT } macro_usage; #line 258 "inweb/Chapter 3/The Analyser.w" typedef struct hash_table_entry { text_stream *hash_key; int reserved_word; /* in the language currently being woven, that is */ struct linked_list *usages; /* of |hash_table_entry_usage| */ MEMORY_MANAGEMENT } hash_table_entry; #line 331 "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 */ MEMORY_MANAGEMENT } hash_table_entry_usage; #line 70 "inweb/Chapter 3/The Swarm.w" typedef struct weave_target { 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 */ struct text_stream *cover_sheet_to_use; /* leafname of the copy, or |NULL| for no cover */ void *post_processing_results; /* optional typesetting diagnostics after running through */ int self_contained; /* make a self-contained file if possible */ int docs_mode; /* make as part of a |-weave-docs| run */ struct linked_list *breadcrumbs; /* non-standard breadcrumb trail, if any */ struct filename *navigation; /* navigation links, or |NULL| if not supplied */ MEMORY_MANAGEMENT } weave_target; #line 33 "inweb/Chapter 3/The Indexer.w" typedef struct cover_sheet_state { struct text_stream *WEAVE_COVER_TO; int halves; /* a bitmap of the above values */ struct weave_target *target; } cover_sheet_state; #line 164 "inweb/Chapter 3/The Indexer.w" typedef struct contents_processor { text_stream *tlines[MAX_TEMPLATE_LINES]; int no_tlines; int repeat_stack_level[CI_STACK_CAPACITY]; linked_list_item *repeat_stack_variable[CI_STACK_CAPACITY]; linked_list_item *repeat_stack_threshold[CI_STACK_CAPACITY]; int repeat_stack_startpos[CI_STACK_CAPACITY]; int stack_pointer; /* And this is our stack pointer for tracking of loops */ text_stream *restrict_to_range; web *nav_web; weave_pattern *nav_pattern; pathname *nav_path; filename *nav_file; linked_list *crumbs; int docs_mode; } contents_processor; #line 84 "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 show_section_toc_soon; /* is a table of contents for the section imminent? */ int horizontal_rule_just_drawn; int in_run_of_definitions; struct section *last_extract_from; struct paragraph *last_endnoted_para; int substantive_comment; struct text_stream *chaptermark; struct text_stream *sectionmark; } weaver_state; #line 75 "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; 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 */ METHOD_CALLS MEMORY_MANAGEMENT } programming_language; #line 122 "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 335 "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| */ MEMORY_MANAGEMENT } colouring_language_block; #line 369 "inweb/Chapter 4/Programming Languages.w" typedef struct colouring_rule { /* the premiss: */ int match_colour; /* for |colour C|, or else |NOT_A_COLOUR| */ int 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 */ /* the conclusion: */ struct colouring_language_block *execute_block; /* or |NULL|, in which case... */ int set_to_colour; /* ...paint the snippet in this colour */ int 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 */ MEMORY_MANAGEMENT } colouring_rule; #line 469 "inweb/Chapter 4/Programming Languages.w" typedef struct reserved_word { struct text_stream *word; int colour; MEMORY_MANAGEMENT } reserved_word; #line 122 "inweb/Chapter 4/C-Like Languages.w" typedef struct c_structure { struct text_stream *structure_name; int tangled; /* whether the structure definition has been tangled out */ struct source_line *typedef_begins; /* opening line of |typedef| */ struct source_line *typedef_ends; /* closing line, where |}| appears */ struct linked_list *incorporates; /* of |c_structure| */ struct linked_list *elements; /* of |structure_element| */ struct c_structure *next_cst_alphabetically; MEMORY_MANAGEMENT } c_structure; #line 251 "inweb/Chapter 4/C-Like Languages.w" typedef struct structure_element { struct text_stream *element_name; struct source_line *element_created_at; int allow_sharing; MEMORY_MANAGEMENT } structure_element; #line 396 "inweb/Chapter 4/C-Like Languages.w" typedef struct 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 no_conditionals; struct source_line *within_conditionals[MAX_CONDITIONAL_COMPILATION_STACK]; MEMORY_MANAGEMENT } function; #line 104 "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 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; MEMORY_MANAGEMENT } preform_nonterminal; #line 279 "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 */ MEMORY_MANAGEMENT } nonterminal_variable; #line 331 "inweb/Chapter 4/InC Support.w" typedef struct text_literal { struct text_stream *tl_identifier; struct text_stream *tl_content; MEMORY_MANAGEMENT } text_literal; #line 11 "inweb/Chapter 5/Weave Formats.w" typedef struct weave_format { struct text_stream *format_name; struct text_stream *woven_extension; METHOD_CALLS MEMORY_MANAGEMENT } weave_format; #line 377 "inweb/Chapter 5/HTML Formats.w" typedef struct HTML_figure_state { struct text_stream *OUT; struct programming_language *colour_as; struct weave_target *wv; struct hash_table *keywords; } HTML_figure_state; #line 42 "inweb/Chapter 5/Running Through TeX.w" typedef struct tex_results { int overfull_hbox_count; int tex_error_count; int page_count; int pdf_size; struct filename *PDF_filename; MEMORY_MANAGEMENT } tex_results; #line 9 "inweb/Chapter 6/Makefiles.w" typedef struct makefile_state { struct web *for_web; struct text_stream to_makefile; struct text_stream *repeat_block; /* a "repeatblock" body being scanned */ int inside_block; /* scanning a "repeatblock" into that text? */ int last_line_was_blank; /* used to suppress runs of multiple blank lines */ int allow_commands; /* permit the prototype to use special commands */ int repeat_scope; /* during a repeat, either |MAKEFILE_TOOL_MOM| or |MAKEFILE_MODULE_MOM| */ struct text_stream *repeat_tag; struct dictionary *tools_dictionary; struct dictionary *webs_dictionary; struct dictionary *modules_dictionary; struct module_search *search_path; } makefile_state; #line 9 "inweb/Chapter 6/Git Support.w" typedef struct gitignore_state { struct web *for_web; struct text_stream to_gitignore; int last_line_was_blank; /* used to suppress runs of multiple blank lines */ } gitignore_state; #line 12 "inweb/Chapter 6/Readme Writeme.w" typedef struct write_state { struct text_stream *OUT; struct linked_list *known_macros; /* of |macro| */ struct macro *current_definition; struct macro_tokens *stack_frame; } write_state; #line 91 "inweb/Chapter 6/Readme Writeme.w" typedef struct macro_tokens { struct macro *bound_to; struct text_stream *pars[8]; int no_pars; struct macro_tokens *down; MEMORY_MANAGEMENT } macro_tokens; #line 76 "inweb/Chapter 6/Readme Writeme.w" typedef struct macro { struct text_stream *name; struct text_stream *content; struct macro_tokens tokens; MEMORY_MANAGEMENT } macro; #line 254 "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; MEMORY_MANAGEMENT } writeme_asset; 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 88 "inweb/foundation-module/Chapter 1/Foundation.w" void Foundation__start(void) ; #line 167 "inweb/foundation-module/Chapter 1/Foundation.w" void Foundation__end(void) ; #ifdef PLATFORM_POSIX #line 90 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" char * Platform__getenv(const char *name) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_LINUX #ifdef PLATFORM_POSIX #line 103 "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 154 "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 161 "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 174 "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 204 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__system(const char *cmd) ; #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 221 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__mkdir(char *transcoded_pathname) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 229 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void * Platform__opendir(char *path_to_folder) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 234 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__readdir(void *folder, char *path_to_folder, char *leafname) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 249 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__closedir(void *folder) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 262 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" time_t Platform__never_time(void) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 266 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" time_t Platform__timestamp(char *transcoded_filename) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 280 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__rsync(char *transcoded_source, char *transcoded_dest) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 289 "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 305 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__sleep(int seconds) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX #line 321 "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 334 "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 346 "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 351 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__join_thread(pthread_t pt, void** rv) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 355 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__init_thread(pthread_attr_t* pa, size_t size) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 360 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" size_t Platform__get_thread_stack_size(pthread_attr_t* pa) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_WINDOWS #line 43 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__Windows_isdigit(int c) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 74 "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 126 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__mkdir(char *transcoded_pathname) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 134 "inweb/foundation-module/Chapter 1/Windows Platform.w" void * Platform__opendir(char *path_to_folder) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 139 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__readdir(void *folder, char *path_to_folder, char *leafname) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 156 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__closedir(void *folder) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 173 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__notification(text_stream *text, int happy) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 191 "inweb/foundation-module/Chapter 1/Windows Platform.w" unsigned long __stdcall Platform__Win32_Thread_Func(unsigned long param) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 198 "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 213 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__join_thread(pthread_t pt, void** rv) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 217 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__init_thread(pthread_attr_t* pa, size_t size) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 220 "inweb/foundation-module/Chapter 1/Windows Platform.w" size_t Platform__get_thread_stack_size(pthread_attr_t* pa) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 232 "inweb/foundation-module/Chapter 1/Windows Platform.w" time_t Platform__never_time(void) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 236 "inweb/foundation-module/Chapter 1/Windows Platform.w" time_t Platform__timestamp(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 107 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__start(void) ; #line 185 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__allocate_another_block(void) ; #line 230 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__free(void) ; #line 275 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__check_memory_integrity(void) ; #line 286 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__debug_memory_frames(int from, int to) ; #line 303 "inweb/foundation-module/Chapter 2/Memory.w" void * Memory__allocate(int mem_type, int extent) ; #line 576 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__name_fundamental_reasons(void) ; #line 589 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__reason_name(int r, char *reason) ; #line 594 "inweb/foundation-module/Chapter 2/Memory.w" char * Memory__description_of_reason(int r) ; #line 619 "inweb/foundation-module/Chapter 2/Memory.w" void * Memory__I7_calloc(int how_many, int size_in_bytes, int reason) ; #line 622 "inweb/foundation-module/Chapter 2/Memory.w" void * Memory__I7_malloc(int size_in_bytes, int reason) ; #line 629 "inweb/foundation-module/Chapter 2/Memory.w" void * Memory__I7_alloc(int N, int S, int R) ; #line 680 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__I7_free(void *pointer, int R, int bytes_freed) ; #line 690 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__I7_array_free(void *pointer, int R, int num_cells, size_t cell_size) ; #line 713 "inweb/foundation-module/Chapter 2/Memory.w" char * Memory__new_string(char *from) ; #line 733 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__free_ssas(void) ; #line 743 "inweb/foundation-module/Chapter 2/Memory.w" int Memory__log_usage(int total) ; #line 762 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__log_statistics(void) ; #line 832 "inweb/foundation-module/Chapter 2/Memory.w" int Memory__compare_usage(const void *ent1, const void *ent2) ; #line 842 "inweb/foundation-module/Chapter 2/Memory.w" int Memory__proportion(int bytes, int total) ; #line 849 "inweb/foundation-module/Chapter 2/Memory.w" void * Memory__paranoid_calloc(size_t N, size_t S) ; #line 884 "inweb/foundation-module/Chapter 2/Memory.w" general_pointer Memory__store_gp_null(void) ; #line 890 "inweb/foundation-module/Chapter 2/Memory.w" int Memory__test_gp_null(general_pointer gp) ; #line 272 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__initialise(text_stream *stream, int from) ; #line 290 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__enable_XML_escapes(text_stream *stream) ; #line 294 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__disable_XML_escapes(text_stream *stream) ; #line 300 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__enable_I6_escapes(text_stream *stream) ; #line 305 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__disable_I6_escapes(text_stream *stream) ; #line 311 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__I6_escapes_enabled(text_stream *stream) ; #line 315 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__enable_debugging(text_stream *stream) ; #line 319 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__disable_debugging(text_stream *stream) ; #line 324 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__mark_as_read_only(text_stream *stream) ; #line 328 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__declare_as_HTML(text_stream *stream, HTML_file_state *hs) ; #line 332 "inweb/foundation-module/Chapter 2/Streams.w" HTML_file_state * Streams__get_HTML_file_state(text_stream *stream) ; #line 339 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__log(OUTPUT_STREAM, void *vS) ; #line 362 "inweb/foundation-module/Chapter 2/Streams.w" text_stream * Streams__get_stdout(void) ; #line 380 "inweb/foundation-module/Chapter 2/Streams.w" text_stream * Streams__get_stderr(void) ; #line 399 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_to_file(text_stream *stream, filename *name, int encoding) ; #line 418 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_to_file_append(text_stream *stream, filename *name, int encoding) ; #line 439 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_to_memory(text_stream *stream, int capacity) ; #line 458 "inweb/foundation-module/Chapter 2/Streams.w" text_stream Streams__new_buffer(int capacity, wchar_t *at) ; #line 476 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_wide_string(text_stream *stream, wchar_t *c_string) ; #line 484 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_wide_string(text_stream *stream, wchar_t *c_string) ; #line 492 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_ISO_string(text_stream *stream, char *c_string) ; #line 500 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_ISO_string(text_stream *stream, char *c_string) ; #line 507 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_UTF8_string(text_stream *stream, char *c_string) ; #line 515 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_UTF8_string(text_stream *stream, char *c_string) ; #line 534 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_as_wide_string(wchar_t *C_string, text_stream *stream, int buffer_size) ; #line 553 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_as_ISO_string(char *C_string, text_stream *stream, int buffer_size) ; #line 570 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_as_UTF8_string(char *C_string, text_stream *stream, int buffer_size) ; #line 601 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_locale_string(text_stream *stream, char *C_string) ; #line 610 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_as_locale_string(char *C_string, text_stream *stream, int buffer_size) ; #line 619 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__write_locale_string(text_stream *stream, char *C_string) ; #line 633 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__flush(text_stream *stream) ; #line 641 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__close(text_stream *stream) ; #line 692 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__putc(int c_int, text_stream *stream) ; #line 788 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__literal(text_stream *stream, char *p) ; #line 802 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__indent(text_stream *stream) ; #line 807 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__outdent(text_stream *stream) ; #line 816 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__set_indentation(text_stream *stream, int N) ; #line 830 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__get_position(text_stream *stream) ; #line 844 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__latest(text_stream *stream) ; #line 860 "inweb/foundation-module/Chapter 2/Streams.w" wchar_t Streams__get_char_at_index(text_stream *stream, int position) ; #line 872 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__put_char_at_index(text_stream *stream, int position, wchar_t C) ; #line 898 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__set_position(text_stream *stream, int position) ; #line 922 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__copy(text_stream *to, text_stream *from) ; #line 938 "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 129 "inweb/foundation-module/Chapter 2/Writers and Loggers.w" void Writers__printf(text_stream *stream, char *fmt, ...) ; #line 41 "inweb/foundation-module/Chapter 2/Methods.w" method_set * Methods__new_set(void) ; #line 85 "inweb/foundation-module/Chapter 2/Methods.w" void Methods__add(method_set *S, int ID, void *function) ; #line 99 "inweb/foundation-module/Chapter 2/Methods.w" int Methods__provided(method_set *S, int ID) ; #line 29 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" linked_list * LinkedLists__new(void) ; #line 41 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" void LinkedLists__add(linked_list *L, void *P, int to_end) ; #line 70 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" void * LinkedLists__remove_from_front(linked_list *L) ; #line 83 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" void * LinkedLists__delete(int N, linked_list *L) ; #line 106 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" int LinkedLists__len(linked_list *L) ; #line 109 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" linked_list_item * LinkedLists__first(linked_list *L) ; #line 112 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" void * LinkedLists__entry(int N, linked_list *L) ; #line 119 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" linked_list_item * LinkedLists__last(linked_list *L) ; #line 122 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" linked_list_item * LinkedLists__next(linked_list_item *I) ; #line 125 "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__read_value(dictionary *D, text_stream *key) ; #line 210 "inweb/foundation-module/Chapter 2/Dictionaries.w" void * Dictionaries__read_value_literal(dictionary *D, wchar_t *key) ; #line 219 "inweb/foundation-module/Chapter 2/Dictionaries.w" void Dictionaries__write_value(dictionary *D, text_stream *key, void *val) ; #line 227 "inweb/foundation-module/Chapter 2/Dictionaries.w" void Dictionaries__write_value_literal(dictionary *D, wchar_t *key, void *val) ; #line 240 "inweb/foundation-module/Chapter 2/Dictionaries.w" text_stream * Dictionaries__create_text(dictionary *D, text_stream *key) ; #line 246 "inweb/foundation-module/Chapter 2/Dictionaries.w" text_stream * Dictionaries__create_text_literal(dictionary *D, wchar_t *lit) ; #line 257 "inweb/foundation-module/Chapter 2/Dictionaries.w" text_stream * Dictionaries__get_text(dictionary *D, text_stream *key) ; #line 265 "inweb/foundation-module/Chapter 2/Dictionaries.w" text_stream * Dictionaries__get_text_literal(dictionary *D, wchar_t *lit) ; #line 278 "inweb/foundation-module/Chapter 2/Dictionaries.w" void Dictionaries__dispose_of(dictionary *D) ; #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 41 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__fatal(char *message) ; #line 48 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__fatal_with_C_string(char *message, char *parameter) ; #line 57 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__fatal_with_text(char *message, text_stream *parameter) ; #line 66 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__fatal_with_file(char *message, filename *F) ; #line 73 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__fatal_with_path(char *message, pathname *P) ; #line 85 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__internal_error_handler(void *p, char *message, char *f, int lc) ; #line 99 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__enter_debugger_mode(void) ; #line 104 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__die(void) ; #line 120 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__nowhere(char *message) ; #line 124 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__in_text_file(char *message, text_file_position *here) ; #line 131 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__in_text_file_S(text_stream *message, text_file_position *here) ; #line 141 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__at_position(char *message, filename *file, int line) ; #line 150 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__at_position_S(text_stream *message, filename *file, int line) ; #line 162 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__with_file(char *message, filename *F) ; #line 169 "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__read_array(clf_reader_state *crs, int argc, char **argv) ; #line 216 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__also_read_file(filename *F) ; #line 227 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__record_log(text_stream *line) ; #line 233 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__play_back_log(void) ; #line 250 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__read_file(clf_reader_state *crs) ; #line 262 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__read_file_helper(text_stream *text, text_file_position *tfp, void *state) ; #line 291 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__read_one(clf_reader_state *crs, text_stream *opt) ; #line 299 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" int CommandLine__read_pair(clf_reader_state *crs, text_stream *opt, text_stream *arg) ; #line 323 "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 414 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__declare_heading(wchar_t *heading_text_literal) ; #line 418 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" void CommandLine__write_help(OUTPUT_STREAM) ; #line 476 "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__subfolder(pathname *P, text_stream *folder_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 175 "inweb/foundation-module/Chapter 3/Pathnames.w" void Pathnames__to_text_relative(OUTPUT_STREAM, pathname *P, pathname *R) ; #line 189 "inweb/foundation-module/Chapter 3/Pathnames.w" pathname * Pathnames__up(pathname *P) ; #line 194 "inweb/foundation-module/Chapter 3/Pathnames.w" text_stream * Pathnames__directory_name(pathname *P) ; #line 204 "inweb/foundation-module/Chapter 3/Pathnames.w" int Pathnames__create_in_file_system(pathname *P) ; #line 222 "inweb/foundation-module/Chapter 3/Pathnames.w" void Pathnames__rsync(pathname *source, pathname *dest) ; #line 24 "inweb/foundation-module/Chapter 3/Filenames.w" filename * Filenames__in_folder(pathname *P, text_stream *file_name) ; #line 28 "inweb/foundation-module/Chapter 3/Filenames.w" filename * Filenames__primitive(text_stream *S, int from, int to, pathname *P) ; #line 44 "inweb/foundation-module/Chapter 3/Filenames.w" filename * Filenames__from_text(text_stream *path) ; #line 60 "inweb/foundation-module/Chapter 3/Filenames.w" filename * Filenames__from_text_relative(pathname *from, text_stream *path) ; #line 77 "inweb/foundation-module/Chapter 3/Filenames.w" void Filenames__writer(OUTPUT_STREAM, char *format_string, void *vF) ; #line 93 "inweb/foundation-module/Chapter 3/Filenames.w" void Filenames__to_text_relative(OUTPUT_STREAM, filename *F, pathname *P) ; #line 110 "inweb/foundation-module/Chapter 3/Filenames.w" pathname * Filenames__get_path_to(filename *F) ; #line 118 "inweb/foundation-module/Chapter 3/Filenames.w" filename * Filenames__without_path(filename *F) ; #line 122 "inweb/foundation-module/Chapter 3/Filenames.w" text_stream * Filenames__get_leafname(filename *F) ; #line 127 "inweb/foundation-module/Chapter 3/Filenames.w" void Filenames__write_unextended_leafname(OUTPUT_STREAM, filename *F) ; #line 143 "inweb/foundation-module/Chapter 3/Filenames.w" void Filenames__write_extension(OUTPUT_STREAM, filename *F) ; #line 152 "inweb/foundation-module/Chapter 3/Filenames.w" filename * Filenames__set_extension(filename *F, char *extension) ; #line 185 "inweb/foundation-module/Chapter 3/Filenames.w" int Filenames__guess_format(filename *F) ; #line 229 "inweb/foundation-module/Chapter 3/Filenames.w" FILE * Filenames__fopen(filename *F, char *usage) ; #line 238 "inweb/foundation-module/Chapter 3/Filenames.w" FILE * Filenames__fopen_caseless(filename *F, char *usage) ; #line 253 "inweb/foundation-module/Chapter 3/Filenames.w" int Filenames__eq(filename *F1, filename *F2) ; #line 268 "inweb/foundation-module/Chapter 3/Filenames.w" time_t Filenames__timestamp(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 212 "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 232 "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(pathname *P) ; #line 30 "inweb/foundation-module/Chapter 3/Directories.w" int Directories__next(scan_directory *D, text_stream *leafname) ; #line 42 "inweb/foundation-module/Chapter 3/Directories.w" void Directories__close(scan_directory *D) ; #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 84 "inweb/foundation-module/Chapter 3/Time.w" int Time__feast(void) ; #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__vowel(wchar_t c) ; #line 37 "inweb/foundation-module/Chapter 4/Characters.w" int Characters__is_space_or_tab(int c) ; #line 41 "inweb/foundation-module/Chapter 4/Characters.w" int Characters__is_whitespace(int c) ; #line 51 "inweb/foundation-module/Chapter 4/Characters.w" int Characters__is_babel_whitespace(int c) ; #line 62 "inweb/foundation-module/Chapter 4/Characters.w" int Characters__combine_accent(int accent, int letter) ; #line 116 "inweb/foundation-module/Chapter 4/Characters.w" int Characters__make_filename_safe(int charcode) ; #line 125 "inweb/foundation-module/Chapter 4/Characters.w" int Characters__remove_accent(int charcode) ; #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__ne(char *A, char *B) ; #line 72 "inweb/foundation-module/Chapter 4/C Strings.w" int CStrings__cmp(char *A, char *B) ; #line 85 "inweb/foundation-module/Chapter 4/C Strings.w" void CStrings__transcode_ISO_string_to_UTF8(char *p, char *dest) ; #line 106 "inweb/foundation-module/Chapter 4/C Strings.w" void CStrings__truncated_strcpy(char *to, char *from, int max) ; #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(wchar_t *C_string) ; #line 79 "inweb/foundation-module/Chapter 4/String Manipulation.w" text_stream * Str__new_from_ISO_string(char *C_string) ; #line 85 "inweb/foundation-module/Chapter 4/String Manipulation.w" text_stream * Str__new_from_UTF8_string(char *C_string) ; #line 91 "inweb/foundation-module/Chapter 4/String Manipulation.w" text_stream * Str__new_from_locale_string(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" void Str__concatenate(text_stream *S1, text_stream *S2) ; #line 278 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__copy(text_stream *S1, text_stream *S2) ; #line 284 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__copy_tail(text_stream *S1, text_stream *S2, int from) ; #line 295 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__copy_ISO_string(text_stream *S, char *C_string) ; #line 300 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__copy_UTF8_string(text_stream *S, char *C_string) ; #line 305 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__copy_wide_string(text_stream *S, wchar_t *C_string) ; #line 314 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__eq(text_stream *S1, text_stream *S2) ; #line 319 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__eq_insensitive(text_stream *S1, text_stream *S2) ; #line 324 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__ne(text_stream *S1, text_stream *S2) ; #line 329 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__ne_insensitive(text_stream *S1, text_stream *S2) ; #line 338 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__cmp(text_stream *S1, text_stream *S2) ; #line 348 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__cmp_insensitive(text_stream *S1, text_stream *S2) ; #line 369 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__prefix_eq(text_stream *S1, text_stream *S2, int N) ; #line 378 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__suffix_eq(text_stream *S1, text_stream *S2, int N) ; #line 387 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__begins_with_wide_string(text_stream *S, wchar_t *prefix) ; #line 396 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__ends_with_wide_string(text_stream *S, wchar_t *suffix) ; #line 406 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__eq_wide_string(text_stream *S1, wchar_t *S2) ; #line 416 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__eq_narrow_string(text_stream *S1, char *S2) ; #line 426 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__ne_wide_string(text_stream *S1, wchar_t *S2) ; #line 433 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__is_whitespace(text_stream *S) ; #line 443 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__trim_white_space(text_stream *S) ; #line 472 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__trim_white_space_at_end(text_stream *S) ; #line 483 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__trim_all_white_space_at_end(text_stream *S) ; #line 497 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__delete_first_character(text_stream *S) ; #line 501 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__delete_last_character(text_stream *S) ; #line 506 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__delete_nth_character(text_stream *S, int n) ; #line 511 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__delete_n_characters(text_stream *S, int n) ; #line 524 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__substr(OUTPUT_STREAM, string_position from, string_position to) ; #line 530 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__includes_character(text_stream *S, wchar_t c) ; #line 538 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__includes_wide_string_at(text_stream *S, wchar_t *prefix, int j) ; #line 547 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__includes_wide_string_at_insensitive(text_stream *S, wchar_t *prefix, int j) ; #line 556 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__includes(text_stream *S, text_stream *T) ; #line 584 "inweb/foundation-module/Chapter 4/String Manipulation.w" text_stream * Str__literal(wchar_t *wide_C_string) ; #line 15 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__exists(filename *F) ; #line 39 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__get_line_count(text_file_position *tfp) ; #line 47 "inweb/foundation-module/Chapter 4/Text Files.w" text_file_position TextFiles__nowhere(void) ; #line 64 "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 156 "inweb/foundation-module/Chapter 4/Text Files.w" void TextFiles__read_line(OUTPUT_STREAM, int escape_oddities, text_file_position *tfp) ; #line 180 "inweb/foundation-module/Chapter 4/Text Files.w" void TextFiles__lose_interest(text_file_position *tfp) ; #line 213 "inweb/foundation-module/Chapter 4/Text Files.w" unicode_file_buffer TextFiles__create_ufb(void) ; #line 219 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__utf8_fgetc(FILE *from, char **or_from, int escape_oddities, unicode_file_buffer *ufb) ; #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 143 "inweb/foundation-module/Chapter 4/Pattern Matching.w" match_results Regexp__create_mr(void) ; #line 151 "inweb/foundation-module/Chapter 4/Pattern Matching.w" void Regexp__dispose_of(match_results *mr) ; #line 165 "inweb/foundation-module/Chapter 4/Pattern Matching.w" int Regexp__match(match_results *mr, text_stream *text, wchar_t *pattern) ; #line 172 "inweb/foundation-module/Chapter 4/Pattern Matching.w" void Regexp__prepare(match_results *mr) ; #line 187 "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 315 "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 344 "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 388 "inweb/foundation-module/Chapter 4/Pattern Matching.w" int Regexp__replace(text_stream *text, wchar_t *pattern, wchar_t *replacement, int options) ; #line 28 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__declare_as_HTML(OUTPUT_STREAM, int XHTML) ; #line 49 "inweb/foundation-module/Chapter 5/HTML.w" int HTML__push_tag(OUTPUT_STREAM, char *tag) ; #line 62 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__pop_tag(OUTPUT_STREAM, char *tag) ; #line 83 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__completed(OUTPUT_STREAM) ; #line 123 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__tag(OUTPUT_STREAM, char *tag, text_stream *details) ; #line 132 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__tag_sc(OUTPUT_STREAM, char *tag, text_stream *details) ; #line 139 "inweb/foundation-module/Chapter 5/HTML.w" int HTML__tag_formatting(char *tag) ; #line 148 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__open(OUTPUT_STREAM, char *tag, text_stream *details) ; #line 157 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__close(OUTPUT_STREAM, char *tag) ; #line 166 "inweb/foundation-module/Chapter 5/HTML.w" int HTML__pair_formatting(char *tag) ; #line 188 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_head(OUTPUT_STREAM, filename *CSS_file) ; #line 206 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__end_head(OUTPUT_STREAM) ; #line 211 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__title(OUTPUT_STREAM, text_stream *title) ; #line 220 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__open_javascript(OUTPUT_STREAM, int define_project) ; #line 234 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__close_javascript(OUTPUT_STREAM) ; #line 238 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__incorporate_javascript(OUTPUT_STREAM, int define_project, filename *M) ; #line 249 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__open_CSS(OUTPUT_STREAM) ; #line 254 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__close_CSS(OUTPUT_STREAM) ; #line 259 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__incorporate_CSS(OUTPUT_STREAM, filename *M) ; #line 268 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__incorporate_HTML(OUTPUT_STREAM, filename *M) ; #line 276 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__incorporate_helper(text_stream *line_of_template, text_file_position *tfp, void *OUT) ; #line 284 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_body(OUTPUT_STREAM, text_stream *class) ; #line 289 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__end_body(OUTPUT_STREAM) ; #line 297 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_div_with_id(OUTPUT_STREAM, char *id) ; #line 301 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_div_with_class(OUTPUT_STREAM, char *cl) ; #line 305 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_div_with_class_and_id(OUTPUT_STREAM, char *cl, char *id, int hide) ; #line 310 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_div_with_id_S(OUTPUT_STREAM, text_stream *id) ; #line 317 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_div_with_class_S(OUTPUT_STREAM, text_stream *cl) ; #line 324 "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) ; #line 332 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__end_div(OUTPUT_STREAM) ; #line 339 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__image(OUTPUT_STREAM, filename *F) ; #line 346 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__anchor(OUTPUT_STREAM, text_stream *id) ; #line 350 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_link(OUTPUT_STREAM, text_stream *to) ; #line 354 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_link_with_class(OUTPUT_STREAM, text_stream *cl, text_stream *to) ; #line 358 "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 362 "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 366 "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 374 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__end_link(OUTPUT_STREAM) ; #line 382 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_plain_html_table(OUTPUT_STREAM) ; #line 386 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_wide_html_table(OUTPUT_STREAM) ; #line 393 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_html_table(OUTPUT_STREAM, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width) ; #line 410 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_html_table_bg(OUTPUT_STREAM, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width, char *bg) ; #line 423 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__first_html_column(OUTPUT_STREAM, int width) ; #line 428 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__first_html_column_nowrap(OUTPUT_STREAM, int width, char *colour) ; #line 436 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__first_html_column_spaced(OUTPUT_STREAM, int width) ; #line 444 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__first_html_column_coloured(OUTPUT_STREAM, int width, char *colour, int cs) ; #line 453 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column(OUTPUT_STREAM, int width) ; #line 459 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column_centred(OUTPUT_STREAM, int width) ; #line 465 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) ; #line 471 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) ; #line 477 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) ; #line 483 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column_nw(OUTPUT_STREAM, int width) ; #line 489 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column_w(OUTPUT_STREAM, int width) ; #line 495 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) ; #line 500 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__end_html_row(OUTPUT_STREAM) ; #line 504 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__end_html_table(OUTPUT_STREAM) ; #line 515 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__open_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ; #line 535 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__close_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ; #line 553 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__box_corner(OUTPUT_STREAM, char *html_colour, char *corner) ; #line 563 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__comment(OUTPUT_STREAM, text_stream *text) ; #line 567 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__heading(OUTPUT_STREAM, char *tag, text_stream *text) ; #line 574 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__hr(OUTPUT_STREAM, char *class) ; #line 739 "inweb/foundation-module/Chapter 5/HTML.w" wchar_t * HTML__translate_colour_name(wchar_t *original) ; #line 747 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_colour(OUTPUT_STREAM, text_stream *col) ; #line 750 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__end_colour(OUTPUT_STREAM) ; #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 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 78 "inweb/foundation-module/Chapter 7/Version Numbers.w" semantic_version_number VersionNumbers__null(void) ; #line 89 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__is_null(semantic_version_number V) ; #line 103 "inweb/foundation-module/Chapter 7/Version Numbers.w" void VersionNumbers__to_text(OUTPUT_STREAM, semantic_version_number V) ; #line 126 "inweb/foundation-module/Chapter 7/Version Numbers.w" void VersionNumbers__writer(OUTPUT_STREAM, char *format_string, void *vE) ; #line 144 "inweb/foundation-module/Chapter 7/Version Numbers.w" semantic_version_number VersionNumbers__from_text(text_stream *T) ; #line 215 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__le(semantic_version_number V1, semantic_version_number V2) ; #line 251 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__floor(int N) ; #line 261 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__strict_atoi(text_stream *T) ; #line 277 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__eq(semantic_version_number V1, semantic_version_number V2) ; #line 283 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__ne(semantic_version_number V1, semantic_version_number V2) ; #line 287 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__gt(semantic_version_number V1, semantic_version_number V2) ; #line 291 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__ge(semantic_version_number V1, semantic_version_number V2) ; #line 295 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__lt(semantic_version_number V1, semantic_version_number V2) ; #line 302 "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 87 "inweb/foundation-module/Chapter 8/Web Structure.w" web_md * WebMetadata__get_without_modules(pathname *P, filename *alt_F) ; #line 91 "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 172 "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 227 "inweb/foundation-module/Chapter 8/Web Structure.w" void WebMetadata__read_contents_line(text_stream *line, text_file_position *tfp, void *X) ; #line 553 "inweb/foundation-module/Chapter 8/Web Structure.w" int WebMetadata__directory_looks_like_a_web(pathname *P) ; #line 557 "inweb/foundation-module/Chapter 8/Web Structure.w" filename * WebMetadata__contents_filename(pathname *P) ; #line 564 "inweb/foundation-module/Chapter 8/Web Structure.w" int WebMetadata__chapter_count(web_md *Wm) ; #line 570 "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 77 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w" void Bibliographic__check_required_data(web_md *Wm) ; #line 90 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w" text_stream * Bibliographic__get_datum(web_md *Wm, text_stream *key) ; #line 96 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w" int Bibliographic__data_exists(web_md *Wm, text_stream *key) ; #line 102 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w" web_bibliographic_datum * Bibliographic__look_up_datum(web_md *Wm, text_stream *key) ; #line 117 "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 30 "inweb/foundation-module/Chapter 8/Web Modules.w" module * WebModules__new(text_stream *name, pathname *at, int m) ; #line 50 "inweb/foundation-module/Chapter 8/Web Modules.w" module * WebModules__create_main_module(web_md *WS) ; #line 61 "inweb/foundation-module/Chapter 8/Web Modules.w" void WebModules__dependency(module *A, module *B) ; #line 77 "inweb/foundation-module/Chapter 8/Web Modules.w" module_search * WebModules__make_search_path(pathname *ext_path) ; #line 87 "inweb/foundation-module/Chapter 8/Web Modules.w" module * WebModules__find(web_md *WS, module_search *ms, text_stream *name, pathname *X) ; #line 116 "inweb/foundation-module/Chapter 8/Web Modules.w" int WebModules__exists(pathname *P) ; #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 63 "inweb/Chapter 1/Program Control.w" int main(int argc, char **argv) ; #line 90 "inweb/Chapter 1/Program Control.w" void Main__follow_instructions(inweb_instructions *ins) ; #line 281 "inweb/Chapter 1/Program Control.w" void Main__error_in_web(text_stream *message, source_line *sl) ; #line 60 "inweb/Chapter 1/Configuration.w" inweb_instructions Configuration__read(int argc, char **argv) ; #line 244 "inweb/Chapter 1/Configuration.w" void Configuration__switch(int id, int val, text_stream *arg, void *state) ; #line 338 "inweb/Chapter 1/Configuration.w" breadcrumb_request * Configuration__breadcrumb(text_stream *arg) ; #line 358 "inweb/Chapter 1/Configuration.w" void Configuration__bareword(int id, text_stream *opt, void *state) ; #line 373 "inweb/Chapter 1/Configuration.w" void Configuration__set_range(inweb_instructions *args, text_stream *opt) ; #line 405 "inweb/Chapter 1/Configuration.w" void Configuration__set_fundamental_mode(inweb_instructions *args, int new_material) ; #line 37 "inweb/Chapter 1/Patterns.w" weave_pattern * Patterns__find(web *W, text_stream *name) ; #line 87 "inweb/Chapter 1/Patterns.w" void Patterns__scan_pattern_line(text_stream *line, text_file_position *tfp, void *X) ; #line 158 "inweb/Chapter 1/Patterns.w" int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) ; #line 176 "inweb/Chapter 1/Patterns.w" filename * Patterns__obtain_filename(weave_pattern *pattern, text_stream *leafname) ; #line 192 "inweb/Chapter 1/Patterns.w" void Patterns__copy_payloads_into_weave(web *W, weave_pattern *pattern) ; #line 213 "inweb/Chapter 1/Patterns.w" void Patterns__copy_file_into_weave(web *W, filename *F) ; #line 218 "inweb/Chapter 1/Patterns.w" void Patterns__copy_up_file_into_weave(web *W, filename *F) ; #line 98 "inweb/Chapter 2/The Reader.w" web_md * Reader__load_web_md(pathname *P, filename *alt_F, module_search *I, int verbosely, int including_modules) ; #line 104 "inweb/Chapter 2/The Reader.w" web * Reader__load_web(pathname *P, filename *alt_F, module_search *I, int verbosely, int including_modules) ; #line 207 "inweb/Chapter 2/The Reader.w" void Reader__read_web(web *W, int verbosely) ; #line 221 "inweb/Chapter 2/The Reader.w" void Reader__read_file(web *W, chapter *C, filename *F, text_stream *titling_line, section *S, int verbosely, int disregard_top) ; #line 264 "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 43 "inweb/Chapter 2/Line Categories.w" source_line * Lines__new_source_line(text_stream *line, text_file_position *tfp) ; #line 104 "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, int sequential) ; #line 697 "inweb/Chapter 2/The Parser.w" text_stream * Parser__extract_purpose(text_stream *prologue, source_line *XL, section *S, source_line **adjust) ; #line 718 "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(OUTPUT_STREAM, weave_target *wv, 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 146 "inweb/Chapter 2/Paragraph Numbering.w" void Numbering__settle_paragraph_number(paragraph *P) ; #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 107 "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 227 "inweb/Chapter 3/The Analyser.w" int Analyser__hash_code_from_word(text_stream *text) ; #line 271 "inweb/Chapter 3/The Analyser.w" hash_table_entry * Analyser__find_hash_entry(hash_table *HT, text_stream *text, int create) ; #line 296 "inweb/Chapter 3/The Analyser.w" hash_table_entry * Analyser__find_hash_entry_for_section(section *S, text_stream *text, int create) ; #line 304 "inweb/Chapter 3/The Analyser.w" void Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) ; #line 309 "inweb/Chapter 3/The Analyser.w" void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) ; #line 313 "inweb/Chapter 3/The Analyser.w" int Analyser__is_reserved_word(hash_table *HT, text_stream *p, int e) ; #line 319 "inweb/Chapter 3/The Analyser.w" int Analyser__is_reserved_word_for_section(section *S, text_stream *p, int e) ; #line 340 "inweb/Chapter 3/The Analyser.w" void Analyser__analyse_find(web *W, source_line *L, text_stream *identifier, int u) ; #line 362 "inweb/Chapter 3/The Analyser.w" void Analyser__write_makefile(web *W, filename *F, module_search *I) ; #line 369 "inweb/Chapter 3/The Analyser.w" void Analyser__write_gitignore(web *W, filename *F) ; #line 20 "inweb/Chapter 3/The Swarm.w" void Swarm__weave(web *W, text_stream *range, int swarm_mode, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, int docs_mode, linked_list *breadcrumbs, filename *navigation) ; #line 52 "inweb/Chapter 3/The Swarm.w" weave_target * Swarm__weave_subset(web *W, text_stream *range, int open_afterwards, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, int docs_mode, linked_list *breadcrumbs, filename *navigation) ; #line 172 "inweb/Chapter 3/The Swarm.w" void Swarm__weave_index_templates(web *W, text_stream *range, weave_pattern *pattern, int self_contained, pathname *into, filename *F, linked_list *crumbs, int docs) ; #line 11 "inweb/Chapter 3/The Indexer.w" void Indexer__cover_sheet_maker(OUTPUT_STREAM, web *W, text_stream *unextended_leafname, weave_target *wt, int halves) ; #line 49 "inweb/Chapter 3/The Indexer.w" void Indexer__scan_cover_line(text_stream *line, text_file_position *tfp, void *v_state) ; #line 131 "inweb/Chapter 3/The Indexer.w" void Indexer__nav_column(OUTPUT_STREAM, pathname *P, web *W, text_stream *range, weave_pattern *pattern, filename *nav) ; #line 181 "inweb/Chapter 3/The Indexer.w" contents_processor Indexer__new_processor(text_stream *range) ; #line 194 "inweb/Chapter 3/The Indexer.w" void Indexer__run(web *W, text_stream *range, filename *template_filename, text_stream *contents_page_leafname, text_stream *write_to, weave_pattern *pattern, pathname *P, filename *nav_file, linked_list *crumbs, int docs) ; #line 257 "inweb/Chapter 3/The Indexer.w" void Indexer__save_template_line(text_stream *line, text_file_position *tfp, void *void_cp) ; #line 409 "inweb/Chapter 3/The Indexer.w" linked_list_item * Indexer__heading_topmost_on_stack(contents_processor *cp, int level) ; #line 420 "inweb/Chapter 3/The Indexer.w" void Indexer__start_CI_loop(contents_processor *cp, int level, linked_list_item *from, linked_list_item *to, int pos) ; #line 430 "inweb/Chapter 3/The Indexer.w" void Indexer__end_CI_loop(contents_processor *cp) ; #line 566 "inweb/Chapter 3/The Indexer.w" void Indexer__list_module(OUTPUT_STREAM, module *M, int list_this) ; #line 583 "inweb/Chapter 3/The Indexer.w" void Indexer__transcribe_CSS(OUTPUT_STREAM, filename *CSS_file) ; #line 590 "inweb/Chapter 3/The Indexer.w" void Indexer__copy_CSS(text_stream *line, text_file_position *tfp, void *X) ; #line 16 "inweb/Chapter 3/The Weaver.w" int Weaver__weave_source(web *W, weave_target *wv) ; #line 659 "inweb/Chapter 3/The Weaver.w" void Weaver__show_endnotes_on_previous_paragraph(OUTPUT_STREAM, weave_target *wv, paragraph *P) ; #line 796 "inweb/Chapter 3/The Weaver.w" int Weaver__weave_table_of_contents(OUTPUT_STREAM, weave_target *wv, section *S) ; #line 14 "inweb/Chapter 3/The Tangler.w" void Tangler__go(web *W, tangle_target *target, filename *dest_file) ; #line 109 "inweb/Chapter 3/The Tangler.w" void Tangler__tangle_paragraph(OUTPUT_STREAM, paragraph *P) ; #line 144 "inweb/Chapter 3/The Tangler.w" void Tangler__tangle_code(OUTPUT_STREAM, text_stream *original, section *S, source_line *L) ; #line 241 "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) ; #line 39 "inweb/Chapter 4/Programming Languages.w" programming_language * Languages__default(void) ; #line 43 "inweb/Chapter 4/Programming Languages.w" void Languages__show(OUTPUT_STREAM) ; #line 53 "inweb/Chapter 4/Programming Languages.w" void Languages__read_definitions(pathname *P) ; #line 67 "inweb/Chapter 4/Programming Languages.w" pathname * Languages__default_directory(void) ; #line 127 "inweb/Chapter 4/Programming Languages.w" programming_language * Languages__read_definition(filename *F) ; #line 190 "inweb/Chapter 4/Programming Languages.w" void Languages__read_definition_line(text_stream *line, text_file_position *tfp, void *v_state) ; #line 344 "inweb/Chapter 4/Programming Languages.w" colouring_language_block * Languages__new_block(colouring_language_block *within, int r) ; #line 388 "inweb/Chapter 4/Programming Languages.w" colouring_rule * Languages__new_rule(colouring_language_block *within) ; #line 405 "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 475 "inweb/Chapter 4/Programming Languages.w" reserved_word * Languages__reserved(programming_language *pl, text_stream *W, int C, text_file_position *tfp) ; #line 511 "inweb/Chapter 4/Programming Languages.w" int Languages__colour(text_stream *T, text_file_position *tfp) ; #line 536 "inweb/Chapter 4/Programming Languages.w" int Languages__boolean(text_stream *T, text_file_position *tfp) ; #line 550 "inweb/Chapter 4/Programming Languages.w" text_stream * Languages__text(text_stream *T, text_file_position *tfp) ; #line 39 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__further_parsing(web *W, programming_language *pl) ; #line 52 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__subcategorise_line(programming_language *pl, source_line *L) ; #line 66 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__parse_comment(programming_language *pl, text_stream *line, text_stream *before, text_stream *within) ; #line 85 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__shebang(OUTPUT_STREAM, programming_language *pl, web *W, tangle_target *target) ; #line 96 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__disclaimer(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ; #line 110 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__additional_early_matter(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ; #line 129 "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 137 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__prolong_definition(OUTPUT_STREAM, programming_language *pl, text_stream *more, section *S, source_line *L) ; #line 145 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__end_definition(OUTPUT_STREAM, programming_language *pl, section *S, source_line *L) ; #line 158 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__additional_predeclarations(OUTPUT_STREAM, programming_language *pl, web *W) ; #line 171 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__allow_expansion(programming_language *pl, text_stream *material) ; #line 186 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__special_tangle_command(OUTPUT_STREAM, programming_language *pl, text_stream *data) ; #line 203 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__will_insert_in_tangle(programming_language *pl, source_line *L) ; #line 208 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__insert_in_tangle(OUTPUT_STREAM, programming_language *pl, source_line *L) ; #line 221 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__insert_line_marker(OUTPUT_STREAM, programming_language *pl, source_line *L) ; #line 235 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__before_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ; #line 238 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__after_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ; #line 252 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__open_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ; #line 255 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__close_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ; #line 265 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__comment(OUTPUT_STREAM, programming_language *pl, text_stream *comm) ; #line 277 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__tangle_code(OUTPUT_STREAM, programming_language *pl, text_stream *original) ; #line 289 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__gnabehs(OUTPUT_STREAM, programming_language *pl, web *W) ; #line 301 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__additional_tangling(programming_language *pl, web *W, tangle_target *target) ; #line 313 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__begin_weave(section *S, weave_target *wv) ; #line 323 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__skip_in_weaving(programming_language *pl, weave_target *wv, source_line *L) ; #line 338 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__reset_syntax_colouring(programming_language *pl) ; #line 351 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__syntax_colour(OUTPUT_STREAM, programming_language *pl, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) ; #line 372 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__weave_code_line(OUTPUT_STREAM, programming_language *pl, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ; #line 385 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__new_tag_declared(theme_tag *tag) ; #line 403 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__catalogue(programming_language *pl, section *S, int functions_too) ; #line 419 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__early_preweave_analysis(programming_language *pl, web *W) ; #line 422 "inweb/Chapter 4/Language Methods.w" void LanguageMethods__late_preweave_analysis(programming_language *pl, web *W) ; #line 433 "inweb/Chapter 4/Language Methods.w" int LanguageMethods__share_element(programming_language *pl, text_stream *element_name) ; #line 442 "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 54 "inweb/Chapter 4/ACME Support.w" void ACMESupport__expand(OUTPUT_STREAM, text_stream *prototype, text_stream *S, int N, filename *F) ; #line 78 "inweb/Chapter 4/ACME Support.w" void ACMESupport__shebang(programming_language *pl, text_stream *OUT, web *W, tangle_target *target) ; #line 83 "inweb/Chapter 4/ACME Support.w" void ACMESupport__before_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ; #line 88 "inweb/Chapter 4/ACME Support.w" void ACMESupport__after_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ; #line 93 "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 102 "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 111 "inweb/Chapter 4/ACME Support.w" int ACMESupport__end_definition(programming_language *pl, text_stream *OUT, section *S, source_line *L) ; #line 119 "inweb/Chapter 4/ACME Support.w" void ACMESupport__I6_open_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ; #line 125 "inweb/Chapter 4/ACME Support.w" void ACMESupport__I6_close_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ; #line 131 "inweb/Chapter 4/ACME Support.w" void ACMESupport__insert_line_marker(programming_language *pl, text_stream *OUT, source_line *L) ; #line 137 "inweb/Chapter 4/ACME Support.w" void ACMESupport__comment(programming_language *pl, text_stream *OUT, text_stream *comm) ; #line 153 "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 208 "inweb/Chapter 4/ACME Support.w" int ACMESupport__text_at(text_stream *line, int i, text_stream *pattern) ; #line 222 "inweb/Chapter 4/ACME Support.w" int ACMESupport__suppress_disclaimer(programming_language *pl) ; #line 229 "inweb/Chapter 4/ACME Support.w" void ACMESupport__begin_weave(programming_language *pl, section *S, weave_target *wv) ; #line 238 "inweb/Chapter 4/ACME Support.w" void ACMESupport__reset_syntax_colouring(programming_language *pl) ; #line 242 "inweb/Chapter 4/ACME Support.w" int ACMESupport__syntax_colour(programming_language *pl, text_stream *OUT, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) ; #line 16 "inweb/Chapter 4/The Painter.w" void Painter__reset_syntax_colouring(programming_language *pl) ; #line 36 "inweb/Chapter 4/The Painter.w" int Painter__syntax_colour(programming_language *pl, text_stream *OUT, hash_table *HT, text_stream *matter, text_stream *colouring, int with_comments) ; #line 56 "inweb/Chapter 4/The Painter.w" void Painter__syntax_colour_inner(programming_language *pl, text_stream *OUT, hash_table *HT, text_stream *matter, text_stream *colouring, int from, int to) ; #line 166 "inweb/Chapter 4/The Painter.w" int Painter__identifier_at(programming_language *pl, text_stream *matter, text_stream *colouring, int i) ; #line 199 "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) ; #line 250 "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) ; #line 267 "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) ; #line 315 "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 9 "inweb/Chapter 4/C-Like Languages.w" void CLike__make_c_like(programming_language *pl) ; #line 41 "inweb/Chapter 4/C-Like Languages.w" void CLike__further_parsing(programming_language *self, web *W) ; #line 459 "inweb/Chapter 4/C-Like Languages.w" c_structure * CLike__find_structure(web *W, text_stream *name) ; #line 473 "inweb/Chapter 4/C-Like Languages.w" void CLike__subcategorise_code(programming_language *self, source_line *L) ; #line 502 "inweb/Chapter 4/C-Like Languages.w" void CLike__additional_early_matter(programming_language *self, text_stream *OUT, web *W, tangle_target *target) ; #line 521 "inweb/Chapter 4/C-Like Languages.w" void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) ; #line 559 "inweb/Chapter 4/C-Like Languages.w" void CLike__tangle_structure(OUTPUT_STREAM, programming_language *self, c_structure *str) ; #line 626 "inweb/Chapter 4/C-Like Languages.w" void CLike__catalogue(programming_language *self, section *S, int functions_too) ; #line 643 "inweb/Chapter 4/C-Like Languages.w" void CLike__analyse_code(programming_language *self, web *W) ; #line 665 "inweb/Chapter 4/C-Like Languages.w" void CLike__post_analysis(programming_language *self, web *W) ; #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 367 "inweb/Chapter 4/InC Support.w" int InCSupport__suppress_expansion(programming_language *self, text_stream *material) ; #line 391 "inweb/Chapter 4/InC Support.w" int InCSupport__special_tangle_command(programming_language *me, OUTPUT_STREAM, text_stream *data) ; #line 415 "inweb/Chapter 4/InC Support.w" void InCSupport__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) ; #line 444 "inweb/Chapter 4/InC Support.w" void InCSupport__gnabehs(programming_language *self, text_stream *OUT, web *W) ; #line 478 "inweb/Chapter 4/InC Support.w" int InCSupport__will_insert_in_tangle(programming_language *self, source_line *L) ; #line 499 "inweb/Chapter 4/InC Support.w" void InCSupport__insert_in_tangle(programming_language *self, text_stream *OUT, source_line *L) ; #line 636 "inweb/Chapter 4/InC Support.w" void InCSupport__tangle_code(programming_language *self, text_stream *OUT, text_stream *original) ; #line 756 "inweb/Chapter 4/InC Support.w" preform_nonterminal * InCSupport__nonterminal_by_name(text_stream *name) ; #line 770 "inweb/Chapter 4/InC Support.w" text_stream * InCSupport__nonterminal_variable_identifier(text_stream *name) ; #line 791 "inweb/Chapter 4/InC Support.w" void InCSupport__additional_tangling(programming_language *self, web *W, tangle_target *target) ; #line 853 "inweb/Chapter 4/InC Support.w" void InCSupport__weave_grammar_index(OUTPUT_STREAM) ; #line 931 "inweb/Chapter 4/InC Support.w" int InCSupport__skip_in_weaving(programming_language *self, weave_target *wv, source_line *L) ; #line 946 "inweb/Chapter 4/InC Support.w" int InCSupport__weave_code_line(programming_language *self, text_stream *OUT, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ; #line 960 "inweb/Chapter 4/InC Support.w" void InCSupport__new_tag_declared(programming_language *self, theme_tag *tag) ; #line 967 "inweb/Chapter 4/InC Support.w" void InCSupport__analyse_code(programming_language *self, web *W) ; #line 974 "inweb/Chapter 4/InC Support.w" int InCSupport__share_element(programming_language *self, text_stream *elname) ; #line 18 "inweb/Chapter 5/Weave Formats.w" weave_format * Formats__create_weave_format(text_stream *name, text_stream *ext) ; #line 26 "inweb/Chapter 5/Weave Formats.w" weave_format * Formats__find_by_name(text_stream *name) ; #line 40 "inweb/Chapter 5/Weave Formats.w" text_stream * Formats__file_extension(weave_format *wf) ; #line 48 "inweb/Chapter 5/Weave Formats.w" void Formats__create_weave_formats(void) ; #line 71 "inweb/Chapter 5/Weave Formats.w" int Formats__begin_weaving(web *W, weave_pattern *pattern) ; #line 77 "inweb/Chapter 5/Weave Formats.w" void Formats__end_weaving(web *W, weave_pattern *pattern) ; #line 92 "inweb/Chapter 5/Weave Formats.w" void Formats__top(OUTPUT_STREAM, weave_target *wv, text_stream *comment) ; #line 110 "inweb/Chapter 5/Weave Formats.w" void Formats__toc(OUTPUT_STREAM, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ; #line 124 "inweb/Chapter 5/Weave Formats.w" void Formats__chapter_title_page(OUTPUT_STREAM, weave_target *wv, chapter *C) ; #line 145 "inweb/Chapter 5/Weave Formats.w" void Formats__subheading(OUTPUT_STREAM, weave_target *wv, int level, text_stream *heading, text_stream *addendum) ; #line 170 "inweb/Chapter 5/Weave Formats.w" void Formats__paragraph_heading(OUTPUT_STREAM, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ; #line 190 "inweb/Chapter 5/Weave Formats.w" void Formats__source_code(OUTPUT_STREAM, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ; #line 206 "inweb/Chapter 5/Weave Formats.w" void Formats__source_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) ; #line 223 "inweb/Chapter 5/Weave Formats.w" void Formats__display_line(OUTPUT_STREAM, weave_target *wv, text_stream *from) ; #line 245 "inweb/Chapter 5/Weave Formats.w" void Formats__item(OUTPUT_STREAM, weave_target *wv, int depth, text_stream *label) ; #line 257 "inweb/Chapter 5/Weave Formats.w" void Formats__bar(OUTPUT_STREAM, weave_target *wv) ; #line 271 "inweb/Chapter 5/Weave Formats.w" void Formats__figure(OUTPUT_STREAM, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) ; #line 286 "inweb/Chapter 5/Weave Formats.w" void Formats__para_macro(OUTPUT_STREAM, weave_target *wv, para_macro *pmac, int defn) ; #line 299 "inweb/Chapter 5/Weave Formats.w" void Formats__pagebreak(OUTPUT_STREAM, weave_target *wv) ; #line 314 "inweb/Chapter 5/Weave Formats.w" void Formats__blank_line(OUTPUT_STREAM, weave_target *wv, int in_comment) ; #line 328 "inweb/Chapter 5/Weave Formats.w" void Formats__after_definitions(OUTPUT_STREAM, weave_target *wv) ; #line 344 "inweb/Chapter 5/Weave Formats.w" void Formats__change_material(OUTPUT_STREAM, weave_target *wv, int old_material, int new_material, int content) ; #line 360 "inweb/Chapter 5/Weave Formats.w" void Formats__change_colour(OUTPUT_STREAM, weave_target *wv, int col, int in_code) ; #line 371 "inweb/Chapter 5/Weave Formats.w" void Formats__text(OUTPUT_STREAM, weave_target *wv, text_stream *id) ; #line 375 "inweb/Chapter 5/Weave Formats.w" void Formats__text_r(OUTPUT_STREAM, weave_target *wv, text_stream *id, int within) ; #line 412 "inweb/Chapter 5/Weave Formats.w" void Formats__text_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) ; #line 433 "inweb/Chapter 5/Weave Formats.w" int Formats__preform_document(OUTPUT_STREAM, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ; #line 451 "inweb/Chapter 5/Weave Formats.w" void Formats__endnote(OUTPUT_STREAM, weave_target *wv, int end) ; #line 466 "inweb/Chapter 5/Weave Formats.w" void Formats__locale(OUTPUT_STREAM, weave_target *wv, paragraph *par1, paragraph *par2) ; #line 479 "inweb/Chapter 5/Weave Formats.w" void Formats__tail(OUTPUT_STREAM, weave_target *wv, text_stream *comment, section *S) ; #line 495 "inweb/Chapter 5/Weave Formats.w" void Formats__post_process_weave(weave_target *wv, int open_afterwards) ; #line 506 "inweb/Chapter 5/Weave Formats.w" void Formats__report_on_post_processing(weave_target *wv) ; #line 518 "inweb/Chapter 5/Weave Formats.w" int Formats__index_pdfs(text_stream *format) ; #line 534 "inweb/Chapter 5/Weave Formats.w" int Formats__substitute_post_processing_data(OUTPUT_STREAM, weave_target *wv, text_stream *detail, weave_pattern *pattern) ; #line 9 "inweb/Chapter 5/Plain Text Format.w" void PlainText__create(void) ; #line 32 "inweb/Chapter 5/Plain Text Format.w" void PlainText__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ; #line 38 "inweb/Chapter 5/Plain Text Format.w" void PlainText__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) ; #line 45 "inweb/Chapter 5/Plain Text Format.w" void PlainText__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ; #line 56 "inweb/Chapter 5/Plain Text Format.w" void PlainText__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv, chapter *C) ; #line 66 "inweb/Chapter 5/Plain Text Format.w" void PlainText__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ; #line 79 "inweb/Chapter 5/Plain Text Format.w" void PlainText__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ; #line 96 "inweb/Chapter 5/Plain Text Format.w" void PlainText__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *from) ; #line 102 "inweb/Chapter 5/Plain Text Format.w" void PlainText__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ; #line 109 "inweb/Chapter 5/Plain Text Format.w" void PlainText__bar(weave_format *self, text_stream *OUT, weave_target *wv) ; #line 114 "inweb/Chapter 5/Plain Text Format.w" void PlainText__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ; #line 122 "inweb/Chapter 5/Plain Text Format.w" void PlainText__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ; #line 128 "inweb/Chapter 5/Plain Text Format.w" void PlainText__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ; #line 134 "inweb/Chapter 5/Plain Text Format.w" void PlainText__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ; #line 140 "inweb/Chapter 5/Plain Text Format.w" void PlainText__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ; #line 147 "inweb/Chapter 5/Plain Text Format.w" void PlainText__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) ; #line 9 "inweb/Chapter 5/TeX Format.w" void TeX__create(void) ; #line 67 "inweb/Chapter 5/TeX Format.w" int TeX__yes(weave_format *self) ; #line 72 "inweb/Chapter 5/TeX Format.w" void TeX__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ; #line 96 "inweb/Chapter 5/TeX Format.w" void TeX__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) ; #line 112 "inweb/Chapter 5/TeX Format.w" void TeX__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ; #line 134 "inweb/Chapter 5/TeX Format.w" void TeX__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv, chapter *C) ; #line 148 "inweb/Chapter 5/TeX Format.w" void TeX__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ; #line 180 "inweb/Chapter 5/TeX Format.w" void TeX__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ; #line 222 "inweb/Chapter 5/TeX Format.w" void TeX__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) ; #line 228 "inweb/Chapter 5/TeX Format.w" void TeX__change_colour_PDF(weave_format *self, text_stream *OUT, weave_target *wv, int col, int in_code) ; #line 245 "inweb/Chapter 5/TeX Format.w" void TeX__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *text) ; #line 251 "inweb/Chapter 5/TeX Format.w" void TeX__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ; #line 263 "inweb/Chapter 5/TeX Format.w" void TeX__bar(weave_format *self, text_stream *OUT, weave_target *wv) ; #line 275 "inweb/Chapter 5/TeX Format.w" void TeX__figure_PDF(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) ; #line 297 "inweb/Chapter 5/TeX Format.w" void TeX__para_macro_PDF_1(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ; #line 306 "inweb/Chapter 5/TeX Format.w" void TeX__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ; #line 315 "inweb/Chapter 5/TeX Format.w" void TeX__para_macro_PDF_2(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ; #line 324 "inweb/Chapter 5/TeX Format.w" void TeX__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) ; #line 329 "inweb/Chapter 5/TeX Format.w" void TeX__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ; #line 336 "inweb/Chapter 5/TeX Format.w" void TeX__after_definitions(weave_format *self, text_stream *OUT, weave_target *wv) ; #line 341 "inweb/Chapter 5/TeX Format.w" void TeX__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ; #line 351 "inweb/Chapter 5/TeX Format.w" void TeX__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ; #line 374 "inweb/Chapter 5/TeX Format.w" void TeX__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ; #line 381 "inweb/Chapter 5/TeX Format.w" void TeX__change_material(weave_format *self, text_stream *OUT, weave_target *wv, int old_material, int new_material, int content) ; #line 407 "inweb/Chapter 5/TeX Format.w" void TeX__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) ; #line 417 "inweb/Chapter 5/TeX Format.w" int TeX__preform_document(weave_format *self, text_stream *OUT, web *W, weave_target *wv, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ; #line 496 "inweb/Chapter 5/TeX Format.w" void TeX__post_process_PDF(weave_format *self, weave_target *wv, int open) ; #line 499 "inweb/Chapter 5/TeX Format.w" void TeX__post_process_DVI(weave_format *self, weave_target *wv, int open) ; #line 504 "inweb/Chapter 5/TeX Format.w" void TeX__post_process_report(weave_format *self, weave_target *wv) ; #line 509 "inweb/Chapter 5/TeX Format.w" int TeX__post_process_substitute(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *detail, weave_pattern *pattern) ; #line 522 "inweb/Chapter 5/TeX Format.w" void TeX__remove_math_mode(OUTPUT_STREAM, text_stream *text) ; #line 529 "inweb/Chapter 5/TeX Format.w" void TeX__remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) ; #line 6 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__create(void) ; #line 58 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__p(OUTPUT_STREAM, char *class) ; #line 64 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__cp(OUTPUT_STREAM) ; #line 69 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__pre(OUTPUT_STREAM, char *class) ; #line 76 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__cpre(OUTPUT_STREAM) ; #line 85 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__go_to_depth(OUTPUT_STREAM, int depth) ; #line 110 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__exit_current_paragraph(OUTPUT_STREAM) ; #line 122 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__breadcrumb(OUTPUT_STREAM, text_stream *text, text_stream *link) ; #line 142 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ; #line 156 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__top_EPUB(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ; #line 165 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) ; #line 182 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ; #line 217 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ; #line 271 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__drop_initial_breadcrumbs(OUTPUT_STREAM, linked_list *crumbs, int docs_mode) ; #line 282 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ; #line 340 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) ; #line 351 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *from) ; #line 362 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ; #line 371 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__bar(weave_format *self, text_stream *OUT, weave_target *wv) ; #line 384 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__figure(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) ; #line 416 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__text_file_helper(text_stream *text, text_file_position *tfp, void *state) ; #line 430 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ; #line 445 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) ; #line 450 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ; #line 463 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__change_material(weave_format *self, text_stream *OUT, weave_target *wv, int old_material, int new_material, int content) ; #line 531 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__change_colour(weave_format *self, text_stream *OUT, weave_target *wv, int col, int in_code) ; #line 552 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ; #line 562 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ; #line 583 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ; #line 597 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__xref(OUTPUT_STREAM, weave_target *wv, paragraph *P, section *from, int a_link) ; #line 618 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *this_S) ; #line 665 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__sref(OUTPUT_STREAM, weave_target *wv, section *S) ; #line 678 "inweb/Chapter 5/HTML Formats.w" int HTMLFormat__begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ; #line 693 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__end_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ; #line 22 "inweb/Chapter 5/Running Through TeX.w" void RunningTeX__post_process_weave(weave_target *wv, int open_afterwards, int to_DVI) ; #line 109 "inweb/Chapter 5/Running Through TeX.w" void RunningTeX__scan_console_line(text_stream *line, text_file_position *tfp, void *res_V) ; #line 129 "inweb/Chapter 5/Running Through TeX.w" void RunningTeX__report_on_post_processing(weave_target *wv) ; #line 143 "inweb/Chapter 5/Running Through TeX.w" int RunningTeX__substitute_post_processing_data(text_stream *to, weave_target *wv, text_stream *detail) ; #line 24 "inweb/Chapter 6/Makefiles.w" void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I) ; #line 49 "inweb/Chapter 6/Makefiles.w" void Makefiles__scan_makefile_line(text_stream *line, text_file_position *tfp, void *X) ; #line 260 "inweb/Chapter 6/Makefiles.w" void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) ; #line 271 "inweb/Chapter 6/Makefiles.w" void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) ; #line 310 "inweb/Chapter 6/Makefiles.w" void Makefiles__repeat(OUTPUT_STREAM, text_stream *prefix, int every_time, text_stream *matter, int as_lines, text_stream *suffix, text_file_position *tfp, makefile_state *MS, int over, text_stream *tag) ; #line 15 "inweb/Chapter 6/Git Support.w" void Git__write_gitignore(web *W, filename *prototype, filename *F) ; #line 31 "inweb/Chapter 6/Git Support.w" void Git__copy_gitignore_line(text_stream *line, text_file_position *tfp, void *X) ; #line 19 "inweb/Chapter 6/Readme Writeme.w" void Readme__write(filename *from, filename *to) ; #line 44 "inweb/Chapter 6/Readme Writeme.w" void Readme__write_helper(text_stream *text, text_file_position *tfp, void *state) ; #line 83 "inweb/Chapter 6/Readme Writeme.w" macro * Readme__new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) ; #line 100 "inweb/Chapter 6/Readme Writeme.w" macro_tokens Readme__parse_token_list(text_stream *chunk, text_file_position *tfp) ; #line 149 "inweb/Chapter 6/Readme Writeme.w" void Readme__expand_material(write_state *ws, text_stream *OUT, text_stream *text, text_file_position *tfp) ; #line 172 "inweb/Chapter 6/Readme Writeme.w" void Readme__expand_at(write_state *ws, text_stream *OUT, text_stream *macro_name, text_file_position *tfp) ; #line 204 "inweb/Chapter 6/Readme Writeme.w" void Readme__expand_macro(write_state *ws, text_stream *OUT, macro *M, text_file_position *tfp) ; #line 263 "inweb/Chapter 6/Readme Writeme.w" void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) ; #line 273 "inweb/Chapter 6/Readme Writeme.w" writeme_asset * Readme__find_asset(text_stream *program) ; #line 324 "inweb/Chapter 6/Readme Writeme.w" void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) ; #line 336 "inweb/Chapter 6/Readme Writeme.w" void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) ; #line 350 "inweb/Chapter 6/Readme Writeme.w" void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) ; #line 366 "inweb/Chapter 6/Readme Writeme.w" void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) ; 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; 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 50 "inweb/foundation-module/Chapter 1/Foundation.w" text_stream *DL = NULL; /* Current destination of debugging text: kept |NULL| until opened */ #line 79 "inweb/foundation-module/Chapter 1/Foundation.w" #line 88 "inweb/foundation-module/Chapter 1/Foundation.w" void Foundation__start(void) { Memory__start(); { #line 105 "inweb/foundation-module/Chapter 1/Foundation.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 90 "inweb/foundation-module/Chapter 1/Foundation.w" ; register_tangled_text_literals(); ; Time__begin(); Pathnames__start(); { #line 116 "inweb/foundation-module/Chapter 1/Foundation.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 94 "inweb/foundation-module/Chapter 1/Foundation.w" ; { #line 127 "inweb/foundation-module/Chapter 1/Foundation.w" Writers__register_logger('a', &Tries__log_avinue); Writers__register_logger('S', &Streams__log); } #line 95 "inweb/foundation-module/Chapter 1/Foundation.w" ; { #line 146 "inweb/foundation-module/Chapter 1/Foundation.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__end_group(); } #line 96 "inweb/foundation-module/Chapter 1/Foundation.w" ; } #line 144 "inweb/foundation-module/Chapter 1/Foundation.w" #line 167 "inweb/foundation-module/Chapter 1/Foundation.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" #ifndef LOCALE_IS_ISO #ifndef LOCALE_IS_UTF8 #define LOCALE_IS_UTF8 1 #endif #endif #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 90 "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 103 "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 115 "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 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" p[0] = '\0'; return; #endif /* PLATFORM_POSIX */ } #line 116 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" ; // unable to find buffer[link_len] = '\0'; #endif /* PLATFORM_POSIX */ } #line 105 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" ; { #ifdef PLATFORM_POSIX #line 124 "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 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" p[0] = '\0'; return; #endif /* PLATFORM_POSIX */ } #line 125 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" ; // wouldn't fit #endif /* PLATFORM_POSIX */ } #line 106 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" ; } #endif /* PLATFORM_LINUX */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_UNIX #ifdef PLATFORM_POSIX #line 154 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__where_am_i(wchar_t *p, size_t length) { { #ifdef PLATFORM_POSIX #line 168 "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" ; } #endif /* PLATFORM_UNIX */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_ANDROID #ifdef PLATFORM_POSIX #line 161 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__where_am_i(wchar_t *p, size_t length) { { #ifdef PLATFORM_POSIX #line 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" p[0] = '\0'; return; #endif /* PLATFORM_POSIX */ } #line 162 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" ; } #endif /* PLATFORM_ANDROID */ #endif /* PLATFORM_POSIX */ #ifndef PLATFORM_MACOS #ifdef PLATFORM_POSIX #line 174 "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 199 "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 221 "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 *path_to_folder) { DIR *dirp = opendir(path_to_folder); return (void *) dirp; } int Platform__readdir(void *folder, char *path_to_folder, char *leafname) { char path_to[2*MAX_FILENAME_LENGTH+2]; struct stat file_status; int rv; DIR *dirp = (DIR *) folder; struct dirent *dp; if ((dp = readdir(dirp)) == NULL) return FALSE; sprintf(path_to, "%s%c%s", path_to_folder, 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 *folder) { DIR *dirp = (DIR *) folder; closedir(dirp); } #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 262 "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(); } #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #line 280 "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 305 "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 321 "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 334 "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 346 "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(pthread_t pt, void** rv) { return pthread_join(pt, rv); } void Platform__init_thread(pthread_attr_t* 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(pthread_attr_t* pa) { size_t mystacksize; pthread_attr_getstacksize(pa, &mystacksize); return mystacksize; } #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_WINDOWS #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 43 "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 74 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__where_am_i(wchar_t *p, size_t length) { DWORD result = GetModuleFileNameW(NULL, p, length); if ((result == 0) || (result == length)) p[0] = 0; } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 126 "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 *path_to_folder) { DIR *dirp = opendir(path_to_folder); return (void *) dirp; } int Platform__readdir(void *folder, char *path_to_folder, char *leafname) { char path_to[2*MAX_FILENAME_LENGTH+2]; struct _stat file_status; int rv; DIR *dirp = (DIR *) folder; struct dirent *dp; if ((dp = readdir(dirp)) == NULL) return FALSE; sprintf(path_to, "%s%c%s", path_to_folder, 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 *folder) { DIR *dirp = (DIR *) folder; closedir(dirp); } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 173 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__notification(text_stream *text, int happy) { } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 191 "inweb/foundation-module/Chapter 1/Windows Platform.w" unsigned long __stdcall Platform__Win32_Thread_Func(unsigned long 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; unsigned long 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(pthread_t pt, void** rv) { return (WaitForSingleObject(pt,-1) == 0) ? 0 : 1; } void Platform__init_thread(pthread_attr_t* pa, size_t size) { } size_t Platform__get_thread_stack_size(pthread_attr_t* pa) { return 0; } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS #line 232 "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_pathname, &filestat) != -1) return filestat.st_mtime; return Platform__never_time(); } #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", INTOOL_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", INTOOL_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 99 "inweb/foundation-module/Chapter 2/Memory.w" #line 105 "inweb/foundation-module/Chapter 2/Memory.w" allocation_status_structure alloc_status[NO_DEFINED_MT_VALUES]; void Memory__start(void) { for (int i=0; i= MAX_BLOCKS_ALLOWED) Errors__fatal( "the memory manager has halted inweb, which seems to be generating " "endless structures. Presumably it is trapped in a loop"); Memory__check_memory_integrity(); cp = (unsigned char *) (Memory__paranoid_calloc(MEMORY_GRANULARITY, 1)); if (cp == NULL) Errors__fatal("Run out of memory: malloc failed"); for (i=0; ithe_memory = (void *) (cp + used_in_current_memblock); { #line 216 "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 195 "inweb/foundation-module/Chapter 2/Memory.w" ; } #line 230 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__free(void) { Memory__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 257 "inweb/foundation-module/Chapter 2/Memory.w" #line 263 "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 274 "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 303 "inweb/foundation-module/Chapter 2/Memory.w" void *Memory__allocate(int mem_type, int extent) { CREATE_MUTEX(mutex); LOCK_MUTEX(mutex); 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 340 "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 314 "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 351 "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 326 "inweb/foundation-module/Chapter 2/Memory.w" ; { #line 359 "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 327 "inweb/foundation-module/Chapter 2/Memory.w" ; total_objects_allocated++; UNLOCK_MUTEX(mutex); return (void *) cp; } #line 531 "inweb/foundation-module/Chapter 2/Memory.w" ALLOCATE_INDIVIDUALLY(filename) ALLOCATE_INDIVIDUALLY(pathname) ALLOCATE_INDIVIDUALLY(string_storage_area) ALLOCATE_INDIVIDUALLY(scan_directory) ALLOCATE_INDIVIDUALLY(ebook) ALLOCATE_INDIVIDUALLY(ebook_datum) ALLOCATE_INDIVIDUALLY(ebook_volume) ALLOCATE_INDIVIDUALLY(ebook_chapter) ALLOCATE_INDIVIDUALLY(ebook_page) ALLOCATE_INDIVIDUALLY(ebook_image) ALLOCATE_INDIVIDUALLY(HTML_file_state) ALLOCATE_INDIVIDUALLY(command_line_switch) ALLOCATE_INDIVIDUALLY(dictionary) ALLOCATE_INDIVIDUALLY(debugging_aspect) ALLOCATE_INDIVIDUALLY(linked_list) ALLOCATE_INDIVIDUALLY(method) ALLOCATE_INDIVIDUALLY(method_set) ALLOCATE_INDIVIDUALLY(ebook_mark) ALLOCATE_INDIVIDUALLY(semantic_version_number_holder) ALLOCATE_INDIVIDUALLY(semver_range) ALLOCATE_INDIVIDUALLY(web_bibliographic_datum) ALLOCATE_INDIVIDUALLY(web_md) ALLOCATE_INDIVIDUALLY(chapter_md) ALLOCATE_INDIVIDUALLY(section_md) ALLOCATE_INDIVIDUALLY(module) ALLOCATE_INDIVIDUALLY(module_search) ALLOCATE_IN_ARRAYS(dict_entry, 100) ALLOCATE_IN_ARRAYS(HTML_tag, 1000) ALLOCATE_IN_ARRAYS(linked_list_item, 1000) ALLOCATE_IN_ARRAYS(match_avinue, 1000) ALLOCATE_IN_ARRAYS(match_trie, 1000) ALLOCATE_IN_ARRAYS(text_stream, 100) #line 574 "inweb/foundation-module/Chapter 2/Memory.w" #line 576 "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(CLS_SORTING_MREASON, "sorting"); } #line 587 "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 607 "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 619 "inweb/foundation-module/Chapter 2/Memory.w" void *Memory__I7_calloc(int how_many, int size_in_bytes, int reason) { return Memory__I7_alloc(how_many, size_in_bytes, reason); } void *Memory__I7_malloc(int size_in_bytes, int reason) { return Memory__I7_alloc(-1, size_in_bytes, reason); } #line 629 "inweb/foundation-module/Chapter 2/Memory.w" void *Memory__I7_alloc(int N, int S, int R) { CREATE_MUTEX(mutex); LOCK_MUTEX(mutex); 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 663 "inweb/foundation-module/Chapter 2/Memory.w" int i; for (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 636 "inweb/foundation-module/Chapter 2/Memory.w" ; { #line 671 "inweb/foundation-module/Chapter 2/Memory.w" 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]; } #line 637 "inweb/foundation-module/Chapter 2/Memory.w" ; UNLOCK_MUTEX(mutex); return pointer; } #line 680 "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"); CREATE_MUTEX(mutex); LOCK_MUTEX(mutex); memory_claimed_for_each_need[R] -= bytes_freed; free(pointer); UNLOCK_MUTEX(mutex); } 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 705 "inweb/foundation-module/Chapter 2/Memory.w" string_storage_area *current_ssa = NULL; #line 713 "inweb/foundation-module/Chapter 2/Memory.w" char *Memory__new_string(char *from) { CREATE_MUTEX(mutex); LOCK_MUTEX(mutex); int length_needed = (int) strlen(from) + 1; if (!((current_ssa) && (current_ssa->first_free_byte + length_needed < SSA_CAPACITY))) { current_ssa = CREATE(string_storage_area); current_ssa->storage_at = Memory__I7_malloc(SSA_CAPACITY, STRING_STORAGE_MREASON); current_ssa->first_free_byte = 0; } char *rp = current_ssa->storage_at + current_ssa->first_free_byte; current_ssa->first_free_byte += length_needed; strcpy(rp, from); UNLOCK_MUTEX(mutex); return rp; } #line 733 "inweb/foundation-module/Chapter 2/Memory.w" void Memory__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 743 "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) LOG("0.%03d: %s - %d bytes in %d claim(s)\n", Memory__proportion(max_memory_at_once_for_each_need[i], total), Memory__description_of_reason(i), max_memory_at_once_for_each_need[i], number_of_claims_for_each_need[i]); } return t; } #line 762 "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_MT_VALUES]; /* memory type numbers, in usage order */ int total = (total_for_objects + total_for_SMAs)/1024; /* total memory usage in KB */ { #line 795 "inweb/foundation-module/Chapter 2/Memory.w" int i; for (i=0; istream_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 290 "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 339 "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 361 "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 LOCALE_IS_ISO STDOUT_struct.stream_flags |= FILE_ENCODING_ISO_STRF; #endif #ifdef LOCALE_IS_UTF8 STDOUT_struct.stream_flags |= FILE_ENCODING_UTF8_STRF; #endif } return &STDOUT_struct; } #line 379 "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; #ifdef LOCALE_IS_ISO STDERR_struct.stream_flags |= FILE_ENCODING_ISO_STRF; #endif #ifdef LOCALE_IS_UTF8 STDERR_struct.stream_flags |= FILE_ENCODING_UTF8_STRF; #endif } return &STDERR_struct; } #line 399 "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 418 "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 439 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_to_memory(text_stream *stream, int capacity) { CREATE_MUTEX(mutex); LOCK_MUTEX(mutex); 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__I7_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; UNLOCK_MUTEX(mutex); return TRUE; } #line 458 "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 476 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_wide_string(text_stream *stream, wchar_t *c_string) { if (stream == NULL) internal_error("tried to open NULL stream"); int capacity = (c_string)?((int) wcslen(c_string)):0; { #line 525 "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 479 "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, wchar_t *c_string) { for (int i=0; c_string[i]; i++) Streams__putc(c_string[i], stream); } #line 492 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_ISO_string(text_stream *stream, char *c_string) { if (stream == NULL) internal_error("tried to open NULL stream"); int capacity = (c_string)?((int) strlen(c_string)):0; { #line 525 "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 495 "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, char *c_string) { for (int i=0; c_string[i]; i++) Streams__putc(c_string[i], stream); } #line 507 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_UTF8_string(text_stream *stream, char *c_string) { if (stream == NULL) internal_error("tried to open NULL stream"); int capacity = (c_string)?((int) strlen(c_string)):0; { #line 525 "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 510 "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, 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 534 "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 553 "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 570 "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 601 "inweb/foundation-module/Chapter 2/Streams.w" int Streams__open_from_locale_string(text_stream *stream, char *C_string) { #ifdef LOCALE_IS_UTF8 return Streams__open_from_UTF8_string(stream, C_string); #endif #ifdef LOCALE_IS_ISO return Streams__open_from_ISO_string(stream, C_string); #endif } void Streams__write_as_locale_string(char *C_string, text_stream *stream, int buffer_size) { #ifdef LOCALE_IS_UTF8 Streams__write_as_UTF8_string(C_string, stream, buffer_size); #endif #ifdef LOCALE_IS_ISO Streams__write_as_ISO_string(C_string, stream, buffer_size); #endif } void Streams__write_locale_string(text_stream *stream, char *C_string) { #ifdef LOCALE_IS_UTF8 Streams__write_UTF8_string(stream, C_string); #endif #ifdef LOCALE_IS_ISO Streams__write_ISO_string(stream, C_string); #endif } #line 633 "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 641 "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 662 "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 651 "inweb/foundation-module/Chapter 2/Streams.w" ; if (stream->write_to_memory) { #line 681 "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 652 "inweb/foundation-module/Chapter 2/Streams.w" ; } #line 692 "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 741 "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 768 "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__I7_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 708 "inweb/foundation-module/Chapter 2/Streams.w" ; if (stream->write_to_file) { if (stream->stream_flags & FILE_ENCODING_UTF8_STRF) { #line 731 "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 711 "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"); } 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 788 "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 802 "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 830 "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 844 "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 860 "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 898 "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 922 "inweb/foundation-module/Chapter 2/Streams.w" void Streams__copy(text_stream *to, text_stream *from) { if ((from == NULL) || (to == NULL)) return; 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 938 "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 107 "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(esc) == FALSE) && (Characters__isdigit(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 129 "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 162 "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 236 "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 214 "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 137 "inweb/foundation-module/Chapter 2/Writers and Loggers.w" ; break; } case '$': { int set = 1; if ((stream->stream_flags) & USES_LOG_ESCAPES_STRF) { #line 162 "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 236 "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 214 "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 143 "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 40 "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 53 "inweb/foundation-module/Chapter 2/Methods.w" #line 67 "inweb/foundation-module/Chapter 2/Methods.w" IMETHOD_TYPE(UNUSED_METHOD_ID_MTID, text_stream *example, int wont_be_used) #line 84 "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 22 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" #line 27 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" #line 29 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w" linked_list *LinkedLists__new(void) { linked_list *ll = CREATE(linked_list); ll->linked_list_length = 0; ll->first_list_item = NULL; ll->last_list_item = NULL; return ll; } #line 41 "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->linked_list_length < NO_LL_EARLY_ITEMS) item = &(L->early_items[L->linked_list_length]); else item = CREATE(linked_list_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 70 "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"); if (L->first_list_item == NULL) internal_error("empty list can't be popped"); linked_list_item *top = L->first_list_item; L->first_list_item = top->next_list_item; if (L->first_list_item == NULL) L->last_list_item = NULL; L->linked_list_length--; return top->item_contents; } #line 83 "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 106 "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; } 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__I7_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", (unsigned int) D); 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=%08x", E->key, (unsigned int) E->value); 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__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 240 "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 257 "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 278 "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 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) { int rv = TRUE; if (errors_handler) rv = (*errors_handler)(message, fatality); if (rv) WRITE_TO(STDERR, "%S", message); if (fatality) Errors__die(); else problem_count++; } #line 41 "inweb/foundation-module/Chapter 3/Error Messages.w" void Errors__fatal(char *message) { TEMPORARY_TEXT(ERM) WRITE_TO(ERM, "%s: fatal error: %s\n", INTOOL_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: ", INTOOL_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: ", INTOOL_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", INTOOL_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", INTOOL_NAME, message, P); Errors__issue(ERM, TRUE); DISCARD_TEXT(ERM) } #line 85 "inweb/foundation-module/Chapter 3/Error Messages.w" 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); } #line 98 "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 120 "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 141 "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: ", INTOOL_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: ", INTOOL_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 162 "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", INTOOL_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: ", INTOOL_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__read_array(clf_reader_state *crs, 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 299 "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 323 "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 353 "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 392 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" if (Log__get_debug_log_filename() == NULL) { TEMPORARY_TEXT(itn); WRITE_TO(itn, "%s", INTOOL_NAME); filename *F = Filenames__in_folder(Pathnames__from_text(itn), TL_IS_2); DISCARD_TEXT(itn); Log__set_debug_log_filename(F); } Log__open(); Log__set_aspect_from_command_line(arg, TRUE); } #line 359 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" ; innocuous = TRUE; break; case VERSION_CLSW: { PRINT("inweb"); char *svn = "7"; if (svn[0]) PRINT(" version %s", svn); char *vname = "Escape to Danger"; if (vname[0]) PRINT(" '%s'", vname); char *d = "5 April 2020"; 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; 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 344 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" ; if ((innocuous == FALSE) && (substantive)) *substantive = TRUE; return cls->valency; } #line 412 "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__I7_calloc(N, (int) sizeof(command_line_switch *), CLS_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 444 "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 433 "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 436 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" ; filter = FOUNDATION_CLSG; { #line 444 "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 438 "inweb/foundation-module/Chapter 3/Command Line Arguments.w" ; Memory__I7_free(sorted_table, CLS_SORTING_MREASON, N*((int) sizeof(command_line_switch *))); } #line 476 "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__get_path_to(F); if ((P) && (Str__eq(P->intermediate, TL_IS_3))) 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__subfolder(pathname *P, text_stream *folder_name) { return Pathnames__primitive(folder_name, 0, Str__len(folder_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 (Str__get(Str__at(path, i)) == FOLDER_SEPARATOR) { 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 175 "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)) && (Str__get_at(rt, n)==FOLDER_SEPARATOR)) { Str__delete_n_characters(rt, n+1); WRITE("%S", rt); } else 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 204 "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 222 "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 19 "inweb/foundation-module/Chapter 3/Filenames.w" #line 24 "inweb/foundation-module/Chapter 3/Filenames.w" filename *Filenames__in_folder(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 44 "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 (Str__get(at) == FOLDER_SEPARATOR) 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 77 "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 93 "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)) && (Str__get_at(ft, n)==FOLDER_SEPARATOR)) { Str__delete_n_characters(ft, n+1); WRITE("%S", ft); } else internal_error("filename not relative to pathname"); DISCARD_TEXT(ft); DISCARD_TEXT(pt); } #line 110 "inweb/foundation-module/Chapter 3/Filenames.w" pathname *Filenames__get_path_to(filename *F) { if (F == NULL) return NULL; return F->pathname_of_location; } #line 118 "inweb/foundation-module/Chapter 3/Filenames.w" filename *Filenames__without_path(filename *F) { return Filenames__in_folder(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 143 "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, char *extension) { TEMPORARY_TEXT(NEWLEAF); LOOP_THROUGH_TEXT(pos, F->leafname) { wchar_t c = Str__get(pos); if (c == '.') break; PUT_TO(NEWLEAF, c); } if (extension) { if (extension[0] == '.') extension++; if (extension[0]) WRITE_TO(NEWLEAF, ".%s", extension); } filename *N = Filenames__in_folder(F->pathname_of_location, NEWLEAF); DISCARD_TEXT(NEWLEAF); return N; } #line 185 "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 229 "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 253 "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 268 "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; } #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 176 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w" char *p; size_t extdirindex = 0, extindex = 0, namelen = 0, dirlen = 0; p = strrchr(path, FOLDER_SEPARATOR); if (p) { extindex = (size_t) (p - path); namelen = length - extindex - 1; strncpy(ciextname, path + extindex + 1, namelen); } ciextname[namelen] = 0; strncpy(workstring, path, extindex); workstring[extindex] = 0; p = strrchr(workstring, FOLDER_SEPARATOR); 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 212 "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 232 "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); 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(pathname *P) { scan_directory *D = CREATE(scan_directory); TEMPORARY_TEXT(pn); WRITE_TO(pn, "%p", P); Str__copy_to_locale_string(D->directory_name_written_out, pn, 4*MAX_FILENAME_LENGTH); DISCARD_TEXT(pn); D->directory_handle = Platform__opendir(D->directory_name_written_out); if (D->directory_handle == NULL) return NULL; 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 9 "inweb/foundation-module/Chapter 3/Time.w" time_t right_now; struct tm *the_present = NULL; int fix_time_mode = FALSE; void Time__begin(void) { time_t right_now = time(NULL); the_present = localtime(&right_now); fix_time_mode = FALSE; } #line 26 "inweb/foundation-module/Chapter 3/Time.w" void Time__fix(void) { struct tm start; start.tm_sec = 0; start.tm_min = 0; start.tm_hour = 11; start.tm_mday = 28; start.tm_mon = 3; start.tm_year = 116; start.tm_isdst = -1; time_t pretend_time = mktime(&start); the_present = localtime(&pretend_time); fix_time_mode = TRUE; } int Time__fixed(void) { return fix_time_mode; } #line 84 "inweb/foundation-module/Chapter 3/Time.w" int Time__feast(void) { int this_month = the_present->tm_mon + 1; int this_day = the_present->tm_mday; int this_year = the_present->tm_year + 1900; int c, y, k, i, n, j, l, m, d; y = this_year; c = y/100; n = y-19*(y/19); k = (c-17)/25; i = c-c/4-(c-k)/3+19*n+15; i = i-30*(i/30); i = i-(i/28)*(1-(i/28)*(29/(i+1))*((21-n)/11)); j = y+y/4+i+2-c+c/4; j = j-7*(j/7); l = i-j; m = 3+(l+40)/44; d = l+28-31*(m/4); 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 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__vowel(wchar_t c) { if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) return TRUE; return FALSE; } #line 37 "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 51 "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 62 "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 116 "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; } #line 125 "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; } #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__ne(char *A, char *B) { return (CStrings__cmp(A, B) == 0)?FALSE:TRUE; } #line 72 "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 85 "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 106 "inweb/foundation-module/Chapter 4/C Strings.w" void CStrings__truncated_strcpy(char *to, char *from, int max) { int i; for (i=0; ((from[i]) && (i 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" void Str__concatenate(text_stream *S1, text_stream *S2) { Streams__copy(S1, S2); } void Str__copy(text_stream *S1, text_stream *S2) { if (S1 == S2) return; Str__clear(S1); Streams__copy(S1, S2); } void Str__copy_tail(text_stream *S1, text_stream *S2, int from) { Str__clear(S1); int L = Str__len(S2); if (from < L) for (string_position P = Str__at(S2, from); P.index < L; P = Str__forward(P)) PUT_TO(S1, Str__get(P)); } #line 295 "inweb/foundation-module/Chapter 4/String Manipulation.w" void Str__copy_ISO_string(text_stream *S, char *C_string) { Str__clear(S); Streams__write_ISO_string(S, C_string); } void Str__copy_UTF8_string(text_stream *S, char *C_string) { Str__clear(S); Streams__write_UTF8_string(S, C_string); } void Str__copy_wide_string(text_stream *S, wchar_t *C_string) { Str__clear(S); Streams__write_wide_string(S, C_string); } #line 314 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__eq(text_stream *S1, text_stream *S2) { if ((Str__len(S1) == Str__len(S2)) && (Str__cmp(S1, S2) == 0)) return TRUE; return FALSE; } int Str__eq_insensitive(text_stream *S1, text_stream *S2) { if ((Str__len(S1) == Str__len(S2)) && (Str__cmp_insensitive(S1, S2) == 0)) return TRUE; return FALSE; } int Str__ne(text_stream *S1, text_stream *S2) { if ((Str__len(S1) != Str__len(S2)) || (Str__cmp(S1, S2) != 0)) return TRUE; return FALSE; } int Str__ne_insensitive(text_stream *S1, text_stream *S2) { if ((Str__len(S1) != Str__len(S2)) || (Str__cmp_insensitive(S1, S2) != 0)) return TRUE; return FALSE; } #line 338 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__cmp(text_stream *S1, text_stream *S2) { for (string_position P = Str__start(S1), Q = Str__start(S2); (P.index < Str__len(S1)) && (Q.index < Str__len(S2)); P = Str__forward(P), Q = Str__forward(Q)) { int d = (int) Str__get(P) - (int) Str__get(Q); if (d != 0) return d; } return Str__len(S1) - Str__len(S2); } int Str__cmp_insensitive(text_stream *S1, text_stream *S2) { for (string_position P = Str__start(S1), Q = Str__start(S2); (P.index < Str__len(S1)) && (Q.index < Str__len(S2)); P = Str__forward(P), Q = Str__forward(Q)) { int d = tolower((int) Str__get(P)) - tolower((int) Str__get(Q)); if (d != 0) return d; } return Str__len(S1) - Str__len(S2); } #line 369 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__prefix_eq(text_stream *S1, text_stream *S2, int N) { int L1 = Str__len(S1), L2 = Str__len(S2); if ((N > L1) || (N > L2)) return FALSE; for (int i=0; i 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 406 "inweb/foundation-module/Chapter 4/String Manipulation.w" int Str__eq_wide_string(text_stream *S1, wchar_t *S2) { 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 (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 433 "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 443 "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 497 "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; iline_count; } #line 47 "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; } #line 64 "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 77 "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 69 "inweb/foundation-module/Chapter 4/Text Files.w" ; { #line 90 "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 70 "inweb/foundation-module/Chapter 4/Text Files.w" ; { #line 109 "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 133 "inweb/foundation-module/Chapter 4/Text Files.w" iterator(line, &tfp, state); tfp.line_count++; } #line 116 "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 147 "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 120 "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 133 "inweb/foundation-module/Chapter 4/Text Files.w" iterator(line, &tfp, state); tfp.line_count++; } #line 127 "inweb/foundation-module/Chapter 4/Text Files.w" ; DISCARD_TEXT(line); } #line 71 "inweb/foundation-module/Chapter 4/Text Files.w" ; fclose(tfp.handle_when_open); return tfp.line_count; } #line 156 "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 180 "inweb/foundation-module/Chapter 4/Text Files.w" void TextFiles__lose_interest(text_file_position *tfp) { tfp->actively_scanning = FALSE; } #line 212 "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, 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 252 "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 230 "inweb/foundation-module/Chapter 4/Text Files.w" ; { #line 281 "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 231 "inweb/foundation-module/Chapter 4/Text Files.w" ; if (escape_oddities) { #line 296 "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 232 "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 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 */ int 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) { int pairc = 0; if (c == '<') pairc = '>'; if (c == '>') pairc = '<'; if (pairc) { int j; for (j = i+delta; j != endpoint; j += delta) { int 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 135 "inweb/foundation-module/Chapter 4/Pattern Matching.w" #line 143 "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 165 "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; } void Regexp__prepare(match_results *mr) { if (mr) { mr->no_matched_texts = 0; for (int i=0; iexp[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 187 "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 222 "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 195 "inweb/foundation-module/Chapter 4/Pattern Matching.w" ; int chcl, /* what class of characters to match: a |*_CLASS| value */ range_from, range_to, /* for |LITERAL_CLASS| only */ reverse = FALSE; /* require a non-match rather than a match */ { #line 240 "inweb/foundation-module/Chapter 4/Pattern Matching.w" int len; chcl = Regexp__get_cclass(pattern, at.ppos, &len, &range_from, &range_to, &reverse); at.ppos += len; } #line 200 "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 248 "inweb/foundation-module/Chapter 4/Pattern Matching.w" if (chcl == WHITESPACE_CLASS) { 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 204 "inweb/foundation-module/Chapter 4/Pattern Matching.w" ; int reps = 0; { #line 259 "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 207 "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 265 "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 212 "inweb/foundation-module/Chapter 4/Pattern Matching.w" ; /* no match length worked, so no match */ return -1; } { #line 274 "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->no_matched_texts = at.bc; } } #line 217 "inweb/foundation-module/Chapter 4/Pattern Matching.w" ; return at.tpos; } #line 315 "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_CLASS; case 'c': return ANY_CLASS; case 'C': return NONWHITESPACE_CLASS; case 'i': return IDENTIFIER_CLASS; case 'p': return PREFORM_CLASS; case 'P': return PREFORMC_CLASS; case 'q': return QUOTE_CLASS; case 't': return TAB_CLASS; } *from = ppos; *to = ppos; return LITERAL_CLASS; case '[': *from = ppos+2; while ((pattern[ppos]) && (pattern[ppos] != ']')) ppos++; *to = ppos - 1; *len = ppos - *from + 1; return LITERAL_CLASS; case ' ': *len = 1; return WHITESPACE_CLASS; } *len = 1; *from = ppos; *to = ppos; return LITERAL_CLASS; } #line 344 "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_CLASS: if (c) match = TRUE; break; case DIGIT_CLASS: if (isdigit(c)) match = TRUE; break; case WHITESPACE_CLASS: if (Characters__is_space_or_tab(c)) match = TRUE; break; case TAB_CLASS: if (c == '\t') match = TRUE; break; case NONWHITESPACE_CLASS: if (!(Characters__is_space_or_tab(c))) match = TRUE; break; case QUOTE_CLASS: if (c != '\"') match = TRUE; break; case IDENTIFIER_CLASS: if (Regexp__identifier_char(c)) match = TRUE; break; case PREFORM_CLASS: if ((c == '-') || (c == '_') || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'))) match = TRUE; break; case PREFORMC_CLASS: if ((c == '-') || (c == '_') || (c == ':') || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'))) match = TRUE; break; case LITERAL_CLASS: 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 388 "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 427 "inweb/foundation-module/Chapter 4/Pattern Matching.w" for (i++; i 0) Str__copy(text, altered); DISCARD_TEXT(altered); return changes; } #line 27 "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 42 "inweb/foundation-module/Chapter 5/HTML.w" int unique_xref = 0; #line 48 "inweb/foundation-module/Chapter 5/HTML.w" int HTML__push_tag(OUTPUT_STREAM, char *tag) { 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; PUSH_TO_LIFO_STACK(ht, HTML_tag, hs->tag_stack); } return u; } #line 62 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__pop_tag(OUTPUT_STREAM, char *tag) { HTML_file_state *hs = Streams__get_HTML_file_state(OUT); if (hs) { if (LIFO_STACK_EMPTY(HTML_tag, hs->tag_stack)) { LOG("{tag: %s}\n", tag); tag_error("closed HTML tag which wasn't open"); } else { HTML_tag *ht = TOP_OF_LIFO_STACK(HTML_tag, hs->tag_stack); if (strcmp(tag, ht->tag_name) != 0) { LOG("{expected to close tag %s (%d), but actually closed %s}\n", ht->tag_name, ht->tag_xref, tag); tag_error("closed HTML tag which wasn't open"); } POP_LIFO_STACK(HTML_tag, hs->tag_stack); } } } #line 83 "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)) { HTML_tag *ht; int i = 0; LOG("HTML tag stack: "); LOOP_DOWN_LIFO_STACK(ht, HTML_tag, hs->tag_stack) { if (i++ > 0) LOG(" in "); LOG("%s (%d)", ht->tag_name, ht->tag_xref); } LOG("\n"); tag_error("HTML tags still open"); } } #line 106 "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); \ DISCARD_TEXT(details); \ } #line 123 "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) { int f = HTML__pair_formatting(tag); HTML__push_tag(OUT, tag); 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) { int f = HTML__pair_formatting(tag); if (f >= 3) WRITE("\n"); if (f >= 2) OUTDENT; WRITE("", tag); HTML__pop_tag(OUT, tag); if (f >= 1) WRITE("\n"); } 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 188 "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 211 "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 220 "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; #ifdef WINDOWS_JAVASCRIPT WRITE("return external.Project;\n"); #endif #ifndef WINDOWS_JAVASCRIPT WRITE("return window.Project;\n"); #endif OUTDENT; WRITE("}\n"); } } void HTML__close_javascript(OUTPUT_STREAM) { HTML_CLOSE("script"); } void HTML__incorporate_javascript(OUTPUT_STREAM, int define_project, filename *M) { HTML__open_javascript(OUT, define_project); 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"); } HTML__close_javascript(OUT); HTML_file_state *hs = Streams__get_HTML_file_state(OUT); if (hs) hs->JS_included++; } 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) { 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); HTML_file_state *hs = Streams__get_HTML_file_state(OUT); if (hs) hs->CSS_included++; } void HTML__incorporate_HTML(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 276 "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 284 "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 297 "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) { TEMPORARY_TEXT(details); WRITE_TO(details, "id=\"%S\"", id); HTML__open(OUT, "div", details); DISCARD_TEXT(details); } void HTML__begin_div_with_class_S(OUTPUT_STREAM, text_stream *cl) { TEMPORARY_TEXT(details); WRITE_TO(details, "class=\"%S\"", cl); HTML__open(OUT, "div", details); DISCARD_TEXT(details); } void HTML__begin_div_with_class_and_id_S(OUTPUT_STREAM, text_stream *cl, text_stream *id, int hide) { 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); DISCARD_TEXT(details); } void HTML__end_div(OUTPUT_STREAM) { HTML_CLOSE("div"); } #line 339 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__image(OUTPUT_STREAM, filename *F) { HTML_TAG_WITH("img", "src=\"%/f\"", F); } #line 346 "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__begin_link(OUTPUT_STREAM, text_stream *to) { HTML_OPEN_WITH("a", "href=\"%S\"", 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 382 "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 393 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__begin_html_table(OUTPUT_STREAM, char *colour, 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 (colour) { if (*colour == '*') WRITE_TO(tab, " style=\"background-image:url('inform:/%s');\"", colour+1); else WRITE_TO(tab, " bgcolor=\"%s\"", colour); } 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, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width, char *bg) { TEMPORARY_TEXT(tab); WRITE_TO(tab, "border=\"%d\" cellspacing=\"%d\" cellpadding=\"%d\"", border, cellspacing, cellpadding); if (bg) WRITE_TO(tab, " background=\"inform:/map_icons/%s\"", bg); if (colour) WRITE_TO(tab, " bgcolor=\"%s\"", colour); 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, char *colour) { if (colour) HTML_OPEN_WITH("tr", "bgcolor=\"%s\"", colour) 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, char *colour, int cs) { if (colour) HTML_OPEN_WITH("tr", "bgcolor=\"%s\"", colour) 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 515 "inweb/foundation-module/Chapter 5/HTML.w" void HTML__open_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) { HTML_OPEN_WITH("table", "width=\"100%%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" " "style=\"background-color: #%s\"", html_colour); HTML_OPEN("tr"); HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE); if (rounding & ROUND_BOX_TOP) HTML__box_corner(OUT, html_colour, "tl"); HTML_CLOSE("td"); HTML_OPEN("td"); HTML_CLOSE("td"); HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE); if (rounding & ROUND_BOX_TOP) HTML__box_corner(OUT, html_colour, "tr"); HTML_CLOSE("td"); HTML_CLOSE("tr"); HTML_OPEN("tr"); HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE); HTML_CLOSE("td"); HTML_OPEN("td"); } void HTML__close_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) { HTML_CLOSE("td"); HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE); HTML_CLOSE("td"); HTML_CLOSE("tr"); HTML_OPEN("tr"); HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE); if (rounding & ROUND_BOX_BOTTOM) HTML__box_corner(OUT, html_colour, "bl"); HTML_CLOSE("td"); HTML_OPEN("td"); HTML_CLOSE("td"); HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE); if (rounding & ROUND_BOX_BOTTOM) HTML__box_corner(OUT, html_colour, "br"); HTML_CLOSE("td"); HTML_CLOSE("tr"); HTML__end_html_table(OUT); } void HTML__box_corner(OUTPUT_STREAM, char *html_colour, char *corner) { HTML_TAG_WITH("img", "src=\"inform:/bg_images/%s_corner_%s.gif\" " "width=\"%d\" height=\"%d\" border=\"0\" alt=\"...\"", corner, html_colour, CORNER_SIZE, CORNER_SIZE); } #line 563 "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 587 "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 739 "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 747 "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 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_folder(P, TEMP); DISCARD_TEXT(TEMP) pathname *Holder = Pathnames__subfolder(P, TL_IS_7); 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_folder(Holder, TL_IS_9); 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__subfolder(Holder, TL_IS_10); if (Pathnames__create_in_file_system(META_INF) == FALSE) return NULL; filename *container = Filenames__in_folder(META_INF, TL_IS_11); 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__subfolder(Holder, TL_IS_8); 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_folder(OEBPS, TL_IS_12); 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_13, TL_IS_14); 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_folder(B->OEBPS_path, TL_IS_15); 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_folder(B->OEBPS_path, TL_IS_16); 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_17); filename *ePub_relative = Filenames__in_folder(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 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 66 "inweb/foundation-module/Chapter 7/Version Numbers.w" #line 71 "inweb/foundation-module/Chapter 7/Version Numbers.w" #line 78 "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 126 "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 142 "inweb/foundation-module/Chapter 7/Version Numbers.w" #line 144 "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 201 "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 172 "inweb/foundation-module/Chapter 7/Version Numbers.w" ; } else if (c == '+') { { #line 201 "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 174 "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 201 "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 185 "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(); } 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 215 "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; while ((I1) && (I2)) { 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); } if ((I1 == NULL) && (I2)) return TRUE; if ((I1) && (I2 == NULL)) return FALSE; return TRUE; } #line 251 "inweb/foundation-module/Chapter 7/Version Numbers.w" int VersionNumbers__floor(int N) { if (N < 0) return 0; return N; } #line 261 "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 277 "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 302 "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_18, 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 62 "inweb/foundation-module/Chapter 8/Web Structure.w" #line 79 "inweb/foundation-module/Chapter 8/Web Structure.w" #line 87 "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 104 "inweb/foundation-module/Chapter 8/Web Structure.w" Wm->bibliographic_data = NEW_LINKED_LIST(web_bibliographic_datum); Bibliographic__initialise_data(Wm); } #line 95 "inweb/foundation-module/Chapter 8/Web Structure.w" ; { #line 108 "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__get_path_to(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 96 "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 128 "inweb/foundation-module/Chapter 8/Web Structure.w" Bibliographic__check_required_data(Wm); BuildFiles__deduce_semver(Wm); BuildFiles__set_bibliographic_data_for(Wm); } #line 99 "inweb/foundation-module/Chapter 8/Web Structure.w" ; return Wm; } #line 171 "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 191 "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_folder_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 176 "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 227 "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 251 "inweb/foundation-module/Chapter 8/Web Structure.w" if (Str__eq(line, TL_IS_19)) RS->Wm->default_syntax = V1_SYNTAX; else if (Str__eq(line, TL_IS_20)) RS->Wm->default_syntax = V2_SYNTAX; } #line 236 "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 262 "inweb/foundation-module/Chapter 8/Web Structure.w" RS->halted = TRUE; text_stream *new_chapter_range = TL_IS_21; text_stream *language_name = NULL; line = TL_IS_22; { #line 463 "inweb/foundation-module/Chapter 8/Web Structure.w" chapter_md *Cm = CREATE(chapter_md); Cm->ch_range = Str__duplicate(new_chapter_range); Cm->ch_title = Str__duplicate(line); 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); RS->chapter_being_scanned = Cm; } #line 266 "inweb/foundation-module/Chapter 8/Web Structure.w" ; line = TL_IS_23; filename_of_single_file_web = tfp->text_file_filename; { #line 480 "inweb/foundation-module/Chapter 8/Web Structure.w" section_md *Sm = CREATE(section_md); Sm = CREATE(section_md); { #line 490 "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); 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); } #line 482 "inweb/foundation-module/Chapter 8/Web Structure.w" ; { #line 507 "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 483 "inweb/foundation-module/Chapter 8/Web Structure.w" ; { #line 515 "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 526 "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_26); Sm->sect_independent_language = Str__duplicate(p); } #line 520 "inweb/foundation-module/Chapter 8/Web Structure.w" ; Str__copy(Sm->sect_title, title_alone); } Regexp__dispose_of(&mr); } #line 484 "inweb/foundation-module/Chapter 8/Web Structure.w" ; if (Sm->source_file_for_section == NULL) { #line 536 "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_folder_name) > 0) P = Pathnames__subfolder(P, RS->chapter_folder_name); Sm->source_file_for_section = Filenames__in_folder(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_folder(P, leafname_to_use); } DISCARD_TEXT(leafname_to_use); } #line 487 "inweb/foundation-module/Chapter 8/Web Structure.w" ; } #line 269 "inweb/foundation-module/Chapter 8/Web Structure.w" ; return; } #line 241 "inweb/foundation-module/Chapter 8/Web Structure.w" ; { #line 278 "inweb/foundation-module/Chapter 8/Web Structure.w" if (Str__len(line) == 0) { #line 286 "inweb/foundation-module/Chapter 8/Web Structure.w" RS->in_biblio = FALSE; } #line 278 "inweb/foundation-module/Chapter 8/Web Structure.w" else if (RS->in_biblio) { #line 292 "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 312 "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 299 "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 279 "inweb/foundation-module/Chapter 8/Web Structure.w" else { #line 335 "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 348 "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 339 "inweb/foundation-module/Chapter 8/Web Structure.w" else { #line 360 "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 455 "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_25); else if (Regexp__match(&mr, language_name, L" *(%c*?) *")) language_name = mr.exp[0]; Regexp__dispose_of(&mr); } #line 368 "inweb/foundation-module/Chapter 8/Web Structure.w" ; Str__copy(line, title_alone); } int this_is_a_chapter = TRUE; Str__clear(RS->chapter_folder_name); if (Str__eq_wide_string(line, L"Sections")) { WRITE_TO(new_chapter_range, "S"); WRITE_TO(RS->chapter_folder_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_folder_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_folder_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__subfolder(P, TL_IS_24); filename *HF = Filenames__in_folder(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->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_folder_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_folder_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 463 "inweb/foundation-module/Chapter 8/Web Structure.w" chapter_md *Cm = CREATE(chapter_md); Cm->ch_range = Str__duplicate(new_chapter_range); Cm->ch_title = Str__duplicate(line); 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); RS->chapter_being_scanned = Cm; } #line 446 "inweb/foundation-module/Chapter 8/Web Structure.w" ; DISCARD_TEXT(new_chapter_range); DISCARD_TEXT(pdf_leafname); Regexp__dispose_of(&mr); } #line 340 "inweb/foundation-module/Chapter 8/Web Structure.w" ; } else { #line 480 "inweb/foundation-module/Chapter 8/Web Structure.w" section_md *Sm = CREATE(section_md); Sm = CREATE(section_md); { #line 490 "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); 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); } #line 482 "inweb/foundation-module/Chapter 8/Web Structure.w" ; { #line 507 "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 483 "inweb/foundation-module/Chapter 8/Web Structure.w" ; { #line 515 "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 526 "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_26); Sm->sect_independent_language = Str__duplicate(p); } #line 520 "inweb/foundation-module/Chapter 8/Web Structure.w" ; Str__copy(Sm->sect_title, title_alone); } Regexp__dispose_of(&mr); } #line 484 "inweb/foundation-module/Chapter 8/Web Structure.w" ; if (Sm->source_file_for_section == NULL) { #line 536 "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_folder_name) > 0) P = Pathnames__subfolder(P, RS->chapter_folder_name); Sm->source_file_for_section = Filenames__in_folder(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_folder(P, leafname_to_use); } DISCARD_TEXT(leafname_to_use); } #line 487 "inweb/foundation-module/Chapter 8/Web Structure.w" ; } #line 341 "inweb/foundation-module/Chapter 8/Web Structure.w" ; } #line 280 "inweb/foundation-module/Chapter 8/Web Structure.w" ; } #line 243 "inweb/foundation-module/Chapter 8/Web Structure.w" ; } #line 553 "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_folder(P, TL_IS_27); } #line 564 "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_28, NULL); bd->declaration_mandatory = TRUE; bd = Bibliographic__set_datum(Wm, TL_IS_29, NULL); bd->declaration_mandatory = TRUE; bd = Bibliographic__set_datum(Wm, TL_IS_30, NULL); bd->declaration_mandatory = TRUE; bd = Bibliographic__set_datum(Wm, TL_IS_31, NULL); bd->declaration_mandatory = TRUE; bd = Bibliographic__set_datum(Wm, TL_IS_32, NULL); bd->alias = Bibliographic__set_datum(Wm, TL_IS_33, NULL); /* alias US to UK spelling */ Bibliographic__set_datum(Wm, TL_IS_34, NULL); Bibliographic__set_datum(Wm, TL_IS_35, NULL); Bibliographic__set_datum(Wm, TL_IS_36, NULL); Bibliographic__set_datum(Wm, TL_IS_37, NULL); Bibliographic__set_datum(Wm, TL_IS_38, NULL); Bibliographic__set_datum(Wm, TL_IS_39, NULL); Bibliographic__set_datum(Wm, TL_IS_40, TL_IS_41); Bibliographic__set_datum(Wm, TL_IS_42, NULL); Bibliographic__set_datum(Wm, TL_IS_43, NULL); Bibliographic__set_datum(Wm, TL_IS_44, NULL); bd = Bibliographic__set_datum(Wm, TL_IS_45, TL_IS_46); bd->on_or_off = TRUE; bd = Bibliographic__set_datum(Wm, TL_IS_47, TL_IS_48); bd->on_or_off = TRUE; bd = Bibliographic__set_datum(Wm, TL_IS_49, TL_IS_50); bd->on_or_off = TRUE; bd = Bibliographic__set_datum(Wm, TL_IS_51, NULL); } #line 77 "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 90 "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 117 "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 126 "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 119 "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 141 "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, toupper(Str__get(P))); Bibliographic__set_datum(Wm, TL_IS_52, recapped); DISCARD_TEXT(recapped); } #line 121 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w" ; return bd; } #line 28 "inweb/foundation-module/Chapter 8/Web Modules.w" #line 30 "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_53; M->sections_md = NEW_LINKED_LIST(section_md); return M; } #line 50 "inweb/foundation-module/Chapter 8/Web Modules.w" module *WebModules__create_main_module(web_md *WS) { return WebModules__new(TL_IS_54, WS->path_to_web, READING_WEB_MOM); } #line 61 "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 75 "inweb/foundation-module/Chapter 8/Web Modules.w" #line 77 "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 87 "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 98 "inweb/foundation-module/Chapter 8/Web Modules.w" ; } DISCARD_TEXT(T); return NULL; } #line 116 "inweb/foundation-module/Chapter 8/Web Modules.w" int WebModules__exists(pathname *P) { return WebMetadata__directory_looks_like_a_web(P); } #line 10 "inweb/foundation-module/Chapter 8/Build Files.w" filename *BuildFiles__build_file_for_web(web_md *WS) { filename *F = Filenames__in_folder(WS->path_to_web, TL_IS_55); if (TextFiles__exists(F)) return F; F = Filenames__in_folder(NULL, TL_IS_56); 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_57, bfd.prerelease_text); if (Str__len(bfd.build_code) > 0) Bibliographic__set_datum(WS, TL_IS_58, bfd.build_code); if (Str__len(bfd.build_date) > 0) Bibliographic__set_datum(WS, TL_IS_59, 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_60); if (Str__len(s) > 0) WRITE_TO(combined, "%S", s); else { text_stream *v = Bibliographic__get_datum(WS, TL_IS_61); if (Str__len(v) > 0) WRITE_TO(combined, "%S", v); text_stream *p = Bibliographic__get_datum(WS, TL_IS_62); if (Str__len(p) > 0) WRITE_TO(combined, "-%S", p); text_stream *b = Bibliographic__get_datum(WS, TL_IS_63); 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_64, 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 55 "inweb/Chapter 1/Basics.w" ALLOCATE_IN_ARRAYS(source_line, 1000) ALLOCATE_INDIVIDUALLY(breadcrumb_request) ALLOCATE_INDIVIDUALLY(c_structure) ALLOCATE_INDIVIDUALLY(chapter) ALLOCATE_INDIVIDUALLY(colouring_rule) ALLOCATE_INDIVIDUALLY(enumeration_set) ALLOCATE_INDIVIDUALLY(function) ALLOCATE_INDIVIDUALLY(hash_table_entry_usage) ALLOCATE_INDIVIDUALLY(hash_table_entry) ALLOCATE_INDIVIDUALLY(colouring_language_block) ALLOCATE_INDIVIDUALLY(macro_tokens) ALLOCATE_INDIVIDUALLY(macro_usage) ALLOCATE_INDIVIDUALLY(macro) ALLOCATE_INDIVIDUALLY(nonterminal_variable) ALLOCATE_INDIVIDUALLY(para_macro) ALLOCATE_INDIVIDUALLY(paragraph_tagging) ALLOCATE_INDIVIDUALLY(paragraph) ALLOCATE_INDIVIDUALLY(preform_nonterminal) ALLOCATE_INDIVIDUALLY(programming_language) ALLOCATE_INDIVIDUALLY(reserved_word) ALLOCATE_INDIVIDUALLY(section) ALLOCATE_INDIVIDUALLY(structure_element) ALLOCATE_INDIVIDUALLY(tangle_target) ALLOCATE_INDIVIDUALLY(tex_results) ALLOCATE_INDIVIDUALLY(text_literal) ALLOCATE_INDIVIDUALLY(theme_tag) ALLOCATE_INDIVIDUALLY(weave_format) ALLOCATE_INDIVIDUALLY(weave_pattern) ALLOCATE_INDIVIDUALLY(weave_target) ALLOCATE_INDIVIDUALLY(web) ALLOCATE_INDIVIDUALLY(writeme_asset) #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; #line 63 "inweb/Chapter 1/Program Control.w" int main(int argc, char **argv) { { #line 78 "inweb/Chapter 1/Program Control.w" Foundation__start(); Formats__create_weave_formats(); } #line 64 "inweb/Chapter 1/Program Control.w" ; inweb_instructions args = Configuration__read(argc, argv); fundamental_mode = args.inweb_mode; path_to_inweb = Pathnames__installation_path("INWEB_PATH", TL_IS_66); if (args.verbose_switch) PRINT("Installation path is %p\n", path_to_inweb); path_to_inweb_patterns = Pathnames__subfolder(path_to_inweb, TL_IS_67); path_to_inweb_materials = Pathnames__subfolder(path_to_inweb, TL_IS_68); Main__follow_instructions(&args); { #line 82 "inweb/Chapter 1/Program Control.w" Foundation__end(); return (no_inweb_errors == 0)?0:1; } #line 74 "inweb/Chapter 1/Program Control.w" ; } #line 90 "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), ins->verbose_switch, TRUE); W->redirect_weaves_to = ins->weave_into_setting; Reader__read_web(W, ins->verbose_switch); Parser__parse_web(W, ins->inweb_mode, ins->sequential); } if (no_inweb_errors == 0) { if (ins->inweb_mode == TRANSLATE_MODE) { #line 110 "inweb/Chapter 1/Program Control.w" if ((ins->makefile_setting) && (ins->prototype_setting == NULL)) ins->prototype_setting = Filenames__from_text(TL_IS_69); if ((ins->gitignore_setting) && (ins->prototype_setting == NULL)) ins->prototype_setting = Filenames__from_text(TL_IS_70); if ((ins->writeme_setting) && (ins->prototype_setting == NULL)) ins->prototype_setting = Filenames__from_text(TL_IS_71); if (ins->makefile_setting) Makefiles__write(W, ins->prototype_setting, ins->makefile_setting, WebModules__make_search_path(ins->import_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 101 "inweb/Chapter 1/Program Control.w" else if (ins->show_languages_switch) { #line 129 "inweb/Chapter 1/Program Control.w" Languages__read_definitions(NULL); Languages__show(STDOUT); } #line 102 "inweb/Chapter 1/Program Control.w" else if (ins->inweb_mode != NO_MODE) { #line 135 "inweb/Chapter 1/Program Control.w" Reader__print_web_statistics(W); if (ins->inweb_mode == ANALYSE_MODE) { #line 143 "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)); 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 136 "inweb/Chapter 1/Program Control.w" ; if (ins->inweb_mode == TANGLE_MODE) { #line 176 "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 199 "inweb/Chapter 1/Program Control.w" tn = NULL; if (Bibliographic__data_exists(W->md, TL_IS_72)) Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_73)); else Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_74)); Str__concatenate(tangle_leaf, W->main_language->file_extension); } #line 179 "inweb/Chapter 1/Program Control.w" ; } else if (Reader__get_section_for_range(W, ins->chosen_range)) { { #line 209 "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 181 "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__get_path_to(W->md->single_file); tangle_to = Filenames__in_folder(P, tangle_leaf); } if (tn == NULL) tn = Tangler__primary_target(W); Tangler__go(W, tn, tangle_to); DISCARD_TEXT(tangle_leaf); } #line 137 "inweb/Chapter 1/Program Control.w" ; if (ins->inweb_mode == WEAVE_MODE) { #line 217 "inweb/Chapter 1/Program Control.w" Numbering__number_web(W); if (ins->weave_docs) { #line 251 "inweb/Chapter 1/Program Control.w" if (ins->weave_into_setting == NULL) { pathname *docs = Pathnames__subfolder(W->md->path_to_web, TL_IS_75); Pathnames__create_in_file_system(docs); text_stream *leaf = Str__new(); if (Bibliographic__data_exists(W->md, TL_IS_76)) Str__copy(leaf, Bibliographic__get_datum(W->md, TL_IS_77)); else Str__copy(leaf, Bibliographic__get_datum(W->md, TL_IS_78)); if (Str__len(leaf) > 0) { ins->weave_into_setting = Pathnames__subfolder(docs, leaf); Pathnames__create_in_file_system(ins->weave_into_setting); } else ins->weave_into_setting = docs; } else { Pathnames__create_in_file_system(ins->weave_into_setting); } W->redirect_weaves_to = ins->weave_into_setting; ins->weave_pattern = TL_IS_79; } #line 218 "inweb/Chapter 1/Program Control.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 270 "inweb/Chapter 1/Program Control.w" section *S; int k = 1; LOOP_OVER(S, section) if (Reader__range_within(S->sect_range, ins->chosen_range)) S->printed_number = k++; } #line 230 "inweb/Chapter 1/Program Control.w" ; if (ins->swarm_mode == SWARM_OFF_SWM) { int shall_we_open = ins->open_pdf_switch; if (shall_we_open == NOT_APPLICABLE) { /* i.e., if it wasn't set at the command line */ if (Str__len(pattern->open_command) > 0) shall_we_open = TRUE; else shall_we_open = FALSE; } Swarm__weave_subset(W, ins->chosen_range, shall_we_open, tag, pattern, ins->weave_to_setting, ins->weave_into_setting, ins->weave_docs, 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->weave_docs, ins->breadcrumb_setting, ins->navigation_setting); } Formats__end_weaving(W, pattern); } #line 138 "inweb/Chapter 1/Program Control.w" ; } #line 103 "inweb/Chapter 1/Program Control.w" ; } } #line 281 "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 47 "inweb/Chapter 1/Configuration.w" #line 53 "inweb/Chapter 1/Configuration.w" #line 60 "inweb/Chapter 1/Configuration.w" inweb_instructions Configuration__read(int argc, char **argv) { inweb_instructions args; { #line 78 "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.open_pdf_switch = NOT_APPLICABLE; args.scan_switch = FALSE; args.verbose_switch = FALSE; args.chosen_web = NULL; args.chosen_file = NULL; args.chosen_range = Str__new(); args.chosen_range_actually_chosen = FALSE; args.tangle_setting = NULL; args.weave_to_setting = NULL; args.weave_into_setting = NULL; args.sequential = FALSE; 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.breadcrumb_setting = NEW_LINKED_LIST(breadcrumb_request); args.tag_setting = Str__new(); args.weave_pattern = Str__new_from_wide_string(L"HTML"); args.weave_docs = FALSE; args.import_setting = NULL; args.targets = 0; } #line 62 "inweb/Chapter 1/Configuration.w" ; { #line 154 "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_81); 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__end_group(); CommandLine__begin_group(ANALYSIS_CLSG, TL_IS_82); 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(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_83); CommandLine__declare_switch(WEAVE_DOCS_CLSW, L"weave-docs", 1, L"weave the web for use at GitHub Pages"); 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_boolean_switch(SEQUENTIAL_CLSW, L"sequential", 1, L"name woven leaves with sequential numbering", FALSE); 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_84); 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__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 63 "inweb/Chapter 1/Configuration.w" ; CommandLine__read(argc, argv, &args, &Configuration__switch, &Configuration__bareword); 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_80); } return args; } #line 115 "inweb/Chapter 1/Configuration.w" #line 117 "inweb/Chapter 1/Configuration.w" #line 121 "inweb/Chapter 1/Configuration.w" #line 123 "inweb/Chapter 1/Configuration.w" #line 134 "inweb/Chapter 1/Configuration.w" #line 136 "inweb/Chapter 1/Configuration.w" #line 147 "inweb/Chapter 1/Configuration.w" #line 149 "inweb/Chapter 1/Configuration.w" #line 152 "inweb/Chapter 1/Configuration.w" #line 244 "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 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 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_DOCS_CLSW: args->weave_docs = TRUE; 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 SEQUENTIAL_CLSW: args->sequential = val; break; case OPEN_CLSW: args->open_pdf_switch = TRUE; 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(Configuration__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; /* 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; default: internal_error("unimplemented switch"); } } breadcrumb_request *Configuration__breadcrumb(text_stream *arg) { breadcrumb_request *BR = CREATE(breadcrumb_request); match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, arg, L"(%c*?): *(%c*)")) { BR->breadcrumb_text = Str__duplicate(mr.exp[0]); BR->breadcrumb_link = Str__duplicate(mr.exp[1]); } else { BR->breadcrumb_text = Str__duplicate(arg); BR->breadcrumb_link = Str__duplicate(arg); WRITE_TO(BR->breadcrumb_link, ".html"); } Regexp__dispose_of(&mr); return BR; } #line 358 "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_85, 6)) args->chosen_file = Filenames__from_text(opt); else args->chosen_web = Pathnames__from_text(opt); } else Configuration__set_range(args, opt); } #line 373 "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_86); } 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, 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 405 "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 33 "inweb/Chapter 1/Patterns.w" #line 37 "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 47 "inweb/Chapter 1/Patterns.w" wp->pattern_name = Str__duplicate(name); wp->pattern_location = NULL; wp->payloads = NEW_LINKED_LIST(text_stream); wp->up_payloads = NEW_LINKED_LIST(text_stream); wp->based_on = NULL; wp->embed_CSS = FALSE; wp->hierarchical = FALSE; wp->patterned_for = W; wp->show_abbrevs = TRUE; wp->number_sections = FALSE; wp->default_range = Str__duplicate(TL_IS_87); wp->tex_command = Str__duplicate(TL_IS_88); wp->pdftex_command = Str__duplicate(TL_IS_89); wp->open_command = Str__duplicate(TL_IS_90); } #line 40 "inweb/Chapter 1/Patterns.w" ; { #line 63 "inweb/Chapter 1/Patterns.w" wp->pattern_location = Pathnames__subfolder( Pathnames__subfolder(W->md->path_to_web, TL_IS_91), name); pattern_file = Filenames__in_folder(wp->pattern_location, TL_IS_92); if (TextFiles__exists(pattern_file) == FALSE) { wp->pattern_location = Pathnames__subfolder(path_to_inweb_patterns, name); pattern_file = Filenames__in_folder(wp->pattern_location, TL_IS_93); if (TextFiles__exists(pattern_file) == FALSE) Errors__fatal_with_text("no such weave pattern as '%S'", name); } } #line 41 "inweb/Chapter 1/Patterns.w" ; { #line 76 "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); } #line 42 "inweb/Chapter 1/Patterns.w" ; return wp; } #line 87 "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; match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, line, L" *from (%c+)")) { #line 102 "inweb/Chapter 1/Patterns.w" wp->based_on = Patterns__find(wp->patterned_for, mr.exp[0]); Regexp__dispose_of(&mr); return; } #line 90 "inweb/Chapter 1/Patterns.w" ; if (Regexp__match(&mr, line, L" *(%c+?) = (%c+)")) { #line 107 "inweb/Chapter 1/Patterns.w" if (Str__eq(mr.exp[0], TL_IS_94)) { wp->pattern_format = Formats__find_by_name(mr.exp[1]); } else if (Str__eq(mr.exp[0], TL_IS_95)) { wp->show_abbrevs = Patterns__yes_or_no(mr.exp[1], tfp); } else if (Str__eq(mr.exp[0], TL_IS_96)) { wp->number_sections = Patterns__yes_or_no(mr.exp[1], tfp); } else if (Str__eq(mr.exp[0], TL_IS_97)) { wp->default_range = Str__duplicate(mr.exp[1]); } else if (Str__eq(mr.exp[0], TL_IS_98)) { wp->tex_command = Str__duplicate(mr.exp[1]); } else if (Str__eq(mr.exp[0], TL_IS_99)) { wp->pdftex_command = Str__duplicate(mr.exp[1]); } else if (Str__eq(mr.exp[0], TL_IS_100)) { wp->open_command = Str__duplicate(mr.exp[1]); } else if ((Bibliographic__data_exists(wp->patterned_for->md, mr.exp[0])) || (Str__eq(mr.exp[0], TL_IS_101))) { Bibliographic__set_datum(wp->patterned_for->md, mr.exp[0], mr.exp[1]); } else { PRINT("Setting: %S\n", mr.exp[0]); Errors__in_text_file("no such pattern setting", tfp); } Regexp__dispose_of(&mr); return; } #line 91 "inweb/Chapter 1/Patterns.w" ; if (Regexp__match(&mr, line, L" *embed css *")) { #line 132 "inweb/Chapter 1/Patterns.w" wp->embed_CSS = TRUE; Regexp__dispose_of(&mr); return; } #line 92 "inweb/Chapter 1/Patterns.w" ; if (Regexp__match(&mr, line, L" *hierarchical *")) { #line 137 "inweb/Chapter 1/Patterns.w" wp->hierarchical = TRUE; Regexp__dispose_of(&mr); return; } #line 93 "inweb/Chapter 1/Patterns.w" ; if (Regexp__match(&mr, line, L" *use (%c+)")) { #line 146 "inweb/Chapter 1/Patterns.w" text_stream *leafname = Str__duplicate(mr.exp[0]); ADD_TO_LINKED_LIST(leafname, text_stream, wp->payloads); Regexp__dispose_of(&mr); return; } #line 94 "inweb/Chapter 1/Patterns.w" ; if (Regexp__match(&mr, line, L" *use-up (%c+)")) { #line 152 "inweb/Chapter 1/Patterns.w" text_stream *leafname = Str__duplicate(mr.exp[0]); ADD_TO_LINKED_LIST(leafname, text_stream, wp->up_payloads); Regexp__dispose_of(&mr); return; } #line 95 "inweb/Chapter 1/Patterns.w" ; if (Regexp__match(&mr, line, L" *%C%c*")) Errors__in_text_file("unrecognised pattern command", tfp); Regexp__dispose_of(&mr); } #line 158 "inweb/Chapter 1/Patterns.w" int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) { if (Str__eq(arg, TL_IS_102)) return TRUE; if (Str__eq(arg, TL_IS_103)) return FALSE; Errors__in_text_file("setting must be 'yes' or 'no'", tfp); return FALSE; } #line 176 "inweb/Chapter 1/Patterns.w" filename *Patterns__obtain_filename(weave_pattern *pattern, text_stream *leafname) { if (Str__prefix_eq(leafname, TL_IS_104, 3)) { Str__delete_first_character(leafname); Str__delete_first_character(leafname); Str__delete_first_character(leafname); } filename *F = Filenames__in_folder(pattern->pattern_location, leafname); if (TextFiles__exists(F)) return F; if (pattern->based_on) return Patterns__obtain_filename(pattern->based_on, leafname); return NULL; } #line 192 "inweb/Chapter 1/Patterns.w" void Patterns__copy_payloads_into_weave(web *W, weave_pattern *pattern) { text_stream *leafname; LOOP_OVER_LINKED_LIST(leafname, text_stream, pattern->payloads) { filename *F = Patterns__obtain_filename(pattern, leafname); Patterns__copy_file_into_weave(W, F); if (W->as_ebook) { filename *rel = Filenames__in_folder(NULL, leafname); Epub__note_image(W->as_ebook, rel); } } LOOP_OVER_LINKED_LIST(leafname, text_stream, pattern->up_payloads) { filename *F = Patterns__obtain_filename(pattern, leafname); Patterns__copy_up_file_into_weave(W, F); if (W->as_ebook) { filename *rel = Filenames__in_folder(NULL, leafname); Epub__note_image(W->as_ebook, rel); } } } #line 213 "inweb/Chapter 1/Patterns.w" void Patterns__copy_file_into_weave(web *W, filename *F) { pathname *H = W->redirect_weaves_to; if (H == NULL) H = Reader__woven_folder(W); Shell__copy(F, H, ""); } void Patterns__copy_up_file_into_weave(web *W, filename *F) { pathname *H = W->redirect_weaves_to; if (H == NULL) H = Reader__woven_folder(W); H = Pathnames__up(H); Shell__copy(F, H, ""); } #line 47 "inweb/Chapter 2/The Reader.w" #line 61 "inweb/Chapter 2/The Reader.w" #line 93 "inweb/Chapter 2/The Reader.w" #line 98 "inweb/Chapter 2/The Reader.w" web_md *Reader__load_web_md(pathname *P, filename *alt_F, module_search *I, int verbosely, int including_modules) { return WebMetadata__get(P, alt_F, default_inweb_syntax, I, verbosely, including_modules, path_to_inweb); } web *Reader__load_web(pathname *P, filename *alt_F, module_search *I, int verbosely, int including_modules) { web *W = CREATE(web); W->md = Reader__load_web_md(P, alt_F, I, verbosely, including_modules); tangle_target *main_target = NULL; { #line 135 "inweb/Chapter 2/The Reader.w" TEMPORARY_TEXT(IB); WRITE_TO(IB, "%s", INWEB_BUILD); web_bibliographic_datum *bd = Bibliographic__set_datum(W->md, TL_IS_105, IB); bd->declaration_permitted = FALSE; DISCARD_TEXT(IB); } #line 111 "inweb/Chapter 2/The Reader.w" ; { #line 142 "inweb/Chapter 2/The Reader.w" W->chapters = NEW_LINKED_LIST(chapter); W->headers = NEW_LINKED_LIST(filename); W->c_structures = NEW_LINKED_LIST(c_structure); 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->no_lines = 0; W->no_paragraphs = 0; text_stream *language_name = Bibliographic__get_datum(W->md, TL_IS_106); if (Str__len(language_name) > 0) W->main_language = Languages__find_by_name(language_name); main_target = Reader__add_tangle_target(W, W->main_language); } #line 112 "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 157 "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); } #line 118 "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 165 "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); if (Str__len(S->md->sect_independent_language) > 0) { programming_language *pl = Languages__find_by_name(S->md->sect_independent_language); 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); S->sect_range = Str__new(); } #line 126 "inweb/Chapter 2/The Reader.w" ; ADD_TO_LINKED_LIST(S, section, C->sections); } } { #line 194 "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 130 "inweb/Chapter 2/The Reader.w" ; return W; } #line 207 "inweb/Chapter 2/The Reader.w" void Reader__read_web(web *W, int verbosely) { 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, verbosely, (W->md->single_file)?TRUE:FALSE); } #line 221 "inweb/Chapter 2/The Reader.w" void Reader__read_file(web *W, chapter *C, filename *F, text_stream *titling_line, section *S, int verbosely, 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 243 "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 277 "inweb/Chapter 2/The Reader.w" source_line *sl = Lines__new_source_line(line, tfp); /* enter this in its section's linked list of lines: */ sl->owning_section = S; 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; /* and keep count: */ sl->owning_section->sect_extent++; sl->owning_section->owning_chapter->owning_web->no_lines++; } #line 247 "inweb/Chapter 2/The Reader.w" ; DISCARD_TEXT(line); } #line 231 "inweb/Chapter 2/The Reader.w" ; if (disregard_top) { #line 251 "inweb/Chapter 2/The Reader.w" TEMPORARY_TEXT(line); text_file_position *tfp = NULL; WRITE_TO(line, "Main."); { #line 277 "inweb/Chapter 2/The Reader.w" source_line *sl = Lines__new_source_line(line, tfp); /* enter this in its section's linked list of lines: */ sl->owning_section = S; 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; /* and keep count: */ sl->owning_section->sect_extent++; sl->owning_section->owning_chapter->owning_web->no_lines++; } #line 254 "inweb/Chapter 2/The Reader.w" ; Str__clear(line); { #line 277 "inweb/Chapter 2/The Reader.w" source_line *sl = Lines__new_source_line(line, tfp); /* enter this in its section's linked list of lines: */ sl->owning_section = S; 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; /* and keep count: */ sl->owning_section->sect_extent++; sl->owning_section->owning_chapter->owning_web->no_lines++; } #line 256 "inweb/Chapter 2/The Reader.w" ; DISCARD_TEXT(line); } #line 234 "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 (verbosely) PRINT("Read section: '%S' (%d lines)\n", S->md->sect_title, cl); } #line 264 "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 277 "inweb/Chapter 2/The Reader.w" source_line *sl = Lines__new_source_line(line, tfp); /* enter this in its section's linked list of lines: */ sl->owning_section = S; 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; /* and keep count: */ sl->owning_section->sect_extent++; sl->owning_section->owning_chapter->owning_web->no_lines++; } #line 273 "inweb/Chapter 2/The Reader.w" ; } #line 296 "inweb/Chapter 2/The Reader.w" pathname *Reader__woven_folder(web *W) { pathname *P = Pathnames__subfolder(W->md->path_to_web, TL_IS_107); 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__subfolder(W->md->path_to_web, TL_IS_108); 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->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; ADD_TO_LINKED_LIST(tt, tangle_target, W->tangle_targets); tt->symbols.analysis_hash_initialised = FALSE; 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_109)); 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->no_lines, (W->no_lines == 1)?"":"s"); } #line 41 "inweb/Chapter 2/Line Categories.w" #line 43 "inweb/Chapter 2/Line Categories.w" source_line *Lines__new_source_line(text_stream *line, text_file_position *tfp) { 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->colour_as = NULL; sl->is_commentary = FALSE; sl->function_defined = NULL; sl->preform_nonterminal_defined = NULL; sl->suppress_tangling = FALSE; sl->interface_line_identified = FALSE; if (tfp) sl->source = *tfp; else sl->source = TextFiles__nowhere(); sl->owning_section = NULL; sl->next_line = NULL; sl->owning_paragraph = NULL; return sl; } #line 75 "inweb/Chapter 2/Line Categories.w" #line 99 "inweb/Chapter 2/Line Categories.w" #line 104 "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 HEADING_START_LCAT: return "PB_PARAGRAPH_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 144 "inweb/Chapter 2/Line Categories.w" #line 17 "inweb/Chapter 2/The Parser.w" void Parser__parse_web(web *W, int inweb_mode, int sequential) { chapter *C; section *S; LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) { int section_counter = 1; LOOP_OVER_LINKED_LIST(S, section, C->sections) { { #line 36 "inweb/Chapter 2/The Parser.w" int comment_mode = TRUE; int code_lcat_for_body = NO_LCAT; programming_language *code_pl_for_body = 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 78 "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 44 "inweb/Chapter 2/The Parser.w" ; { #line 62 "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 45 "inweb/Chapter 2/The Parser.w" ; { #line 109 "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 129 "inweb/Chapter 2/The Parser.w" source_line *NL = Lines__new_source_line(TL_IS_112, &(L->source)); PL->next_line = NL; NL->next_line = L; L = PL; Regexp__dispose_of(&mr); continue; } #line 114 "inweb/Chapter 2/The Parser.w" ; } if ((PL) && (Regexp__match(&mr, L->text, L"@ *= *"))) { Str__clear(L->text); Str__copy(L->text, TL_IS_111); if (S->md->using_syntax < V2_SYNTAX) Parser__wrong_version(S->md->using_syntax, L, "implied paragraph breaks", V2_SYNTAX); { #line 129 "inweb/Chapter 2/The Parser.w" source_line *NL = Lines__new_source_line(TL_IS_112, &(L->source)); PL->next_line = NL; NL->next_line = L; L = PL; Regexp__dispose_of(&mr); continue; } #line 121 "inweb/Chapter 2/The Parser.w" ; } Regexp__dispose_of(&mr); } #line 46 "inweb/Chapter 2/The Parser.w" ; { #line 141 "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 165 "inweb/Chapter 2/The Parser.w" if (Str__eq_wide_string(L->text, L"Chapter Heading")) { comment_mode = TRUE; L->is_commentary = TRUE; L->category = CHAPTER_HEADING_LCAT; } } #line 145 "inweb/Chapter 2/The Parser.w" ; if (L->source.line_count <= 1) { #line 175 "inweb/Chapter 2/The Parser.w" match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, L->text, L"%[(%C+)%] (%C+/%C+): (%c+).")) { S->sect_namespace = Str__duplicate(mr.exp[0]); S->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; } else if (Regexp__match(&mr, L->text, L"(%C+/%C+): (%c+).")) { S->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; } 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]); { #line 204 "inweb/Chapter 2/The Parser.w" if (Str__len(S->sect_range) == 0) { if (sequential) { WRITE_TO(S->sect_range, "%S/", C->md->ch_range); WRITE_TO(S->sect_range, "s%d", section_counter); } else { text_stream *from = S->md->sect_title; int letters_from_each_word = 5; do { Str__clear(S->sect_range); WRITE_TO(S->sect_range, "%S/", C->md->ch_range); { #line 226 "inweb/Chapter 2/The Parser.w" int sn = 0, sw = Str__len(S->sect_range); if (Str__get_at(from, sn) == FOLDER_SEPARATOR) 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) != '-') { int l = 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(S->sect_range, sw++, l); Str__put_at(S->sect_range, sw, 0); letters_from_current_word++; } } } } sn++; } } #line 214 "inweb/Chapter 2/The Parser.w" ; if (--letters_from_each_word == 0) break; } while (Str__len(S->sect_range) > 5); { #line 249 "inweb/Chapter 2/The Parser.w" TEMPORARY_TEXT(original_range); Str__copy(original_range, S->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(S->sect_range); WRITE_TO(S->sect_range, "%S", original_range); Str__truncate(S->sect_range, Str__len(S->sect_range) - ldn); WRITE_TO(S->sect_range, "%d", disnum); } collision = FALSE; chapter *C; section *S2; LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) LOOP_OVER_LINKED_LIST(S2, section, C->sections) if ((S2 != S) && (Str__eq(S2->sect_range, S->sect_range))) { collision = TRUE; break; } } while (collision); DISCARD_TEXT(original_range); } #line 218 "inweb/Chapter 2/The Parser.w" ; } } } #line 190 "inweb/Chapter 2/The Parser.w" ; L->text_operand = Str__duplicate(mr.exp[1]); L->category = SECTION_HEADING_LCAT; } else if (Regexp__match(&mr, L->text, L"(%c+).")) { S->md->sect_title = Str__duplicate(mr.exp[0]); { #line 204 "inweb/Chapter 2/The Parser.w" if (Str__len(S->sect_range) == 0) { if (sequential) { WRITE_TO(S->sect_range, "%S/", C->md->ch_range); WRITE_TO(S->sect_range, "s%d", section_counter); } else { text_stream *from = S->md->sect_title; int letters_from_each_word = 5; do { Str__clear(S->sect_range); WRITE_TO(S->sect_range, "%S/", C->md->ch_range); { #line 226 "inweb/Chapter 2/The Parser.w" int sn = 0, sw = Str__len(S->sect_range); if (Str__get_at(from, sn) == FOLDER_SEPARATOR) 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) != '-') { int l = 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(S->sect_range, sw++, l); Str__put_at(S->sect_range, sw, 0); letters_from_current_word++; } } } } sn++; } } #line 214 "inweb/Chapter 2/The Parser.w" ; if (--letters_from_each_word == 0) break; } while (Str__len(S->sect_range) > 5); { #line 249 "inweb/Chapter 2/The Parser.w" TEMPORARY_TEXT(original_range); Str__copy(original_range, S->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(S->sect_range); WRITE_TO(S->sect_range, "%S", original_range); Str__truncate(S->sect_range, Str__len(S->sect_range) - ldn); WRITE_TO(S->sect_range, "%d", disnum); } collision = FALSE; chapter *C; section *S2; LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) LOOP_OVER_LINKED_LIST(S2, section, C->sections) if ((S2 != S) && (Str__eq(S2->sect_range, S->sect_range))) { collision = TRUE; break; } } while (collision); DISCARD_TEXT(original_range); } #line 218 "inweb/Chapter 2/The Parser.w" ; } } } #line 195 "inweb/Chapter 2/The Parser.w" ; L->text_operand = Str__duplicate(mr.exp[0]); L->category = SECTION_HEADING_LCAT; } Regexp__dispose_of(&mr); } #line 146 "inweb/Chapter 2/The Parser.w" ; { #line 280 "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_113); L->command_code = FIGURE_CMD; } else { if (S->md->using_syntax >= V2_SYNTAX) { Tags__add_by_name(L->owning_paragraph, TL_IS_114); L->command_code = FIGURE_CMD; Str__copy(L->text_operand, full_command); } else { Main__error_in_web(TL_IS_115, L); } } L->is_commentary = TRUE; DISCARD_TEXT(command_text); DISCARD_TEXT(full_command); } Regexp__dispose_of(&mr); } #line 147 "inweb/Chapter 2/The Parser.w" ; { #line 326 "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_116, L); else Macros__create(S, current_paragraph, L, para_macro_name); comment_mode = FALSE; L->is_commentary = FALSE; code_lcat_for_body = CODE_BODY_LCAT; /* code follows on subsequent lines */ code_pl_for_body = NULL; DISCARD_TEXT(para_macro_name); continue; } Regexp__dispose_of(&mr); } #line 148 "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); { #line 366 "inweb/Chapter 2/The Parser.w" L->category = BEGIN_CODE_LCAT; code_lcat_for_body = CODE_BODY_LCAT; 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_117))) { current_paragraph->placed_very_early = TRUE; } else if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_118))) { current_paragraph->placed_early = TRUE; } else if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_119))) { code_lcat_for_body = TEXT_EXTRACT_LCAT; code_pl_for_body = NULL; } else if ((current_paragraph) && (Regexp__match(&mr2, mr.exp[0], L"%(sample (%c+) code%)"))) { code_lcat_for_body = TEXT_EXTRACT_LCAT; code_pl_for_body = Languages__find_by_name(mr2.exp[0]); } else { Main__error_in_web(TL_IS_120, L); } } else if (Regexp__match(&mr, L->text, L"= *%C%c*")) { Main__error_in_web(TL_IS_121, L); } Regexp__dispose_of(&mr); Regexp__dispose_of(&mr2); continue; } #line 152 "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 348 "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 400 "inweb/Chapter 2/The Parser.w" if (Str__eq_wide_string(command_text, L"Purpose:")) { #line 447 "inweb/Chapter 2/The Parser.w" if (before_bar == FALSE) Main__error_in_web(TL_IS_123, 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 400 "inweb/Chapter 2/The Parser.w" else if (Str__eq_wide_string(command_text, L"Interface:")) { #line 456 "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_124, L); L->category = INTERFACE_LCAT; 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 401 "inweb/Chapter 2/The Parser.w" else if (Str__eq_wide_string(command_text, L"Definitions:")) { #line 470 "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_125, L); L->category = DEFINITIONS_LCAT; L->is_commentary = TRUE; before_bar = TRUE; next_par_number = 1; } #line 402 "inweb/Chapter 2/The Parser.w" else if (Regexp__match(&mr, command_text, L"----+")) { #line 482 "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_126, L); L->category = BAR_LCAT; L->is_commentary = TRUE; comment_mode = TRUE; S->barred = TRUE; before_bar = FALSE; next_par_number = 1; } #line 403 "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 499 "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; } #line 407 "inweb/Chapter 2/The Parser.w" else if (Str__eq_wide_string(command_text, L"d")) { #line 513 "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_for_section(S, L->text_operand, CONSTANT_COLOUR); comment_mode = FALSE; L->is_commentary = FALSE; Regexp__dispose_of(&mr); } #line 408 "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 513 "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_for_section(S, L->text_operand, CONSTANT_COLOUR); comment_mode = FALSE; L->is_commentary = FALSE; Regexp__dispose_of(&mr); } #line 412 "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 513 "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_for_section(S, L->text_operand, CONSTANT_COLOUR); comment_mode = FALSE; L->is_commentary = FALSE; Regexp__dispose_of(&mr); } #line 417 "inweb/Chapter 2/The Parser.w" ; } else if (Str__eq_wide_string(command_text, L"enum")) { #line 533 "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_127, 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_for_section(S, L->text_operand, CONSTANT_COLOUR); comment_mode = FALSE; L->is_commentary = FALSE; Regexp__dispose_of(&mr); } #line 418 "inweb/Chapter 2/The Parser.w" else if ((Str__eq_wide_string(command_text, L"e")) && (S->md->using_syntax >= V2_SYNTAX)) { #line 533 "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_127, 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_for_section(S, L->text_operand, CONSTANT_COLOUR); comment_mode = FALSE; L->is_commentary = FALSE; Regexp__dispose_of(&mr); } #line 420 "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 585 "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 632 "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; } if ((S->md->using_syntax == V1_SYNTAX) && (before_bar)) P->ornament = Str__duplicate(TL_IS_128); else P->ornament = Str__duplicate(TL_IS_129); 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(c_structure); P->taggings = NEW_LINKED_LIST(paragraph_tagging); P->under_section = S; S->sect_paragraphs++; ADD_TO_LINKED_LIST(P, paragraph, S->paragraphs); current_paragraph = P; } #line 601 "inweb/Chapter 2/The Parser.w" ; L->owning_paragraph = current_paragraph; W->no_paragraphs++; Regexp__dispose_of(&mr); } #line 439 "inweb/Chapter 2/The Parser.w" else Main__error_in_web(TL_IS_122, L); } } #line 357 "inweb/Chapter 2/The Parser.w" ; DISCARD_TEXT(remainder); DISCARD_TEXT(command_text); Regexp__dispose_of(&mr); continue; } #line 157 "inweb/Chapter 2/The Parser.w" ; if (comment_mode) { #line 666 "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 158 "inweb/Chapter 2/The Parser.w" ; if (comment_mode == FALSE) { #line 678 "inweb/Chapter 2/The Parser.w" if ((L->category != BEGIN_DEFINITION_LCAT) && (L->category != COMMAND_LCAT)) { L->category = code_lcat_for_body; if (L->category == TEXT_EXTRACT_LCAT) L->colour_as = code_pl_for_body; } 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 159 "inweb/Chapter 2/The Parser.w" ; } #line 47 "inweb/Chapter 2/The Parser.w" ; } DISCARD_TEXT(tag_list); { #line 97 "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; S->sect_purpose = Parser__extract_purpose(TL_IS_110, L?L->next_line: NULL, S, NULL); if (Str__len(S->sect_purpose) > 0) L->next_line->category = PURPOSE_LCAT; } } #line 50 "inweb/Chapter 2/The Parser.w" ; { #line 87 "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 51 "inweb/Chapter 2/The Parser.w" ; } #line 23 "inweb/Chapter 2/The Parser.w" ; section_counter++; } } LanguageMethods__further_parsing(W, W->main_language); } #line 630 "inweb/Chapter 2/The Parser.w" #line 697 "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 718 "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 available only in version %d syntax (you're using version %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_130, 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_131, 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(OUTPUT_STREAM, weave_target *wv, paragraph *P) { int d = 0, sense = TRUE; { #line 147 "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) { Formats__endnote(OUT, wv, 1); Formats__text(OUT, wv, TL_IS_133); } else { Formats__text(OUT, wv, TL_IS_134); } } else { Formats__text(OUT, wv, TL_IS_135); } Formats__text(OUT, wv, pt->the_tag->ifdef_symbol); } if (c > 0) { if (c == 1) Formats__text(OUT, wv, TL_IS_136); else Formats__text(OUT, wv, TL_IS_137); if (sense) Formats__text(OUT, wv, TL_IS_138); else Formats__text(OUT, wv, TL_IS_139); } } #line 137 "inweb/Chapter 2/Tags.w" ; sense = FALSE; { #line 147 "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) { Formats__endnote(OUT, wv, 1); Formats__text(OUT, wv, TL_IS_133); } else { Formats__text(OUT, wv, TL_IS_134); } } else { Formats__text(OUT, wv, TL_IS_135); } Formats__text(OUT, wv, pt->the_tag->ifdef_symbol); } if (c > 0) { if (c == 1) Formats__text(OUT, wv, TL_IS_136); else Formats__text(OUT, wv, TL_IS_137); if (sense) Formats__text(OUT, wv, TL_IS_138); else Formats__text(OUT, wv, TL_IS_139); } } #line 139 "inweb/Chapter 2/Tags.w" ; if (d > 0) { Formats__text(OUT, wv, TL_IS_132); Formats__endnote(OUT, wv, 2); } } #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_140, 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_141, 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_142, 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 = FIRST_IN_LINKED_LIST(macro_usage, P->defines_macro->macro_usages); if (mu) P->parent_paragraph = mu->used_in_paragraph; } } #line 88 "inweb/Chapter 2/Paragraph Numbering.w" ; { #line 104 "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) P->parent_paragraph = P2->parent_paragraph; break; } } } #line 89 "inweb/Chapter 2/Paragraph Numbering.w" ; { #line 117 "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 126 "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 136 "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 146 "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); 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; } #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->sect_range)) max_range_width = Str__len(S->sect_range); TEMPORARY_TEXT(main_title); WRITE_TO(main_title, "Chapter %S/%S", C->md->ch_range, 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, "Chapter %S/%S", C->md->ch_range, S->md->sect_title); PRINT("%4d %S", S->sect_extent, S->sect_range); for (int i = Str__len(S->sect_range); isect_language, S, (form == FUNCTIONS_SECTIONCAT)?TRUE:FALSE); PRINT("\n"); DISCARD_TEXT(main_title); } } } #line 107 "inweb/Chapter 3/The Analyser.w" void Analyser__analyse_code(web *W) { if (W->analysed) return; { #line 142 "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_143, L); } #line 110 "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 156 "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 117 "inweb/Chapter 3/The Analyser.w" ; break; case CODE_BODY_LCAT: { #line 153 "inweb/Chapter 3/The Analyser.w" Analyser__analyse_as_code(W, L, L->text, ANY_USAGE, 0); } #line 120 "inweb/Chapter 3/The Analyser.w" ; break; case PREFORM_GRAMMAR_LCAT: { #line 169 "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 123 "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) { 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; } 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; } } } #line 227 "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 into... */ 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 254 "inweb/Chapter 3/The Analyser.w" #line 264 "inweb/Chapter 3/The Analyser.w" #line 271 "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 (HT->analysis_hash_initialised == FALSE) { for (int i=0; ianalysis_hash[i] = NULL; HT->analysis_hash_initialised = TRUE; } 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->hash_key = Str__duplicate(text); hte->usages = NEW_LINKED_LIST(hash_table_entry_usage); 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 304 "inweb/Chapter 3/The Analyser.w" void Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) { hash_table_entry *hte = Analyser__find_hash_entry(HT, p, TRUE); hte->reserved_word |= (1 << e); } void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) { Analyser__mark_reserved_word(&(S->sect_target->symbols), p, e); } 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->reserved_word & (1 << e))) 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); } #line 336 "inweb/Chapter 3/The Analyser.w" #line 340 "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_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages) if (L->owning_paragraph == hteu->usage_recorded_at) 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 362 "inweb/Chapter 3/The Analyser.w" void Analyser__write_makefile(web *W, filename *F, module_search *I) { filename *prototype = Filenames__in_folder(W->md->path_to_web, TL_IS_144); if (!(TextFiles__exists(prototype))) prototype = Filenames__in_folder(path_to_inweb_materials, TL_IS_145); Makefiles__write(W, prototype, F, I); } void Analyser__write_gitignore(web *W, filename *F) { filename *prototype = Filenames__in_folder(W->md->path_to_web, TL_IS_146); if (!(TextFiles__exists(prototype))) prototype = Filenames__in_folder(path_to_inweb_materials, TL_IS_147); Git__write_gitignore(W, prototype, F); } #line 18 "inweb/Chapter 3/The Swarm.w" weave_target *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, int docs_mode, 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, docs_mode, 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->sect_range, range)) S->sect_weave = Swarm__weave_subset(W, S->sect_range, FALSE, tag, pattern, to, into, docs_mode, breadcrumbs, navigation); } Swarm__weave_index_templates(W, range, pattern, (to)?TRUE:FALSE, into, navigation, breadcrumbs, docs_mode); } #line 52 "inweb/Chapter 3/The Swarm.w" weave_target *Swarm__weave_subset(web *W, text_stream *range, int open_afterwards, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, int docs_mode, linked_list *breadcrumbs, filename *navigation) { weave_target *wt = NULL; if (no_inweb_errors == 0) { Analyser__analyse_code(W); { #line 88 "inweb/Chapter 3/The Swarm.w" wt = CREATE(weave_target); wt->weave_web = W; wt->weave_range = Str__duplicate(range); wt->pattern = pattern; wt->theme_match = tag; wt->booklet_title = Str__new(); wt->format = pattern->pattern_format; wt->post_processing_results = NULL; wt->cover_sheet_to_use = Str__new(); wt->self_contained = FALSE; wt->docs_mode = docs_mode; wt->navigation = navigation; wt->breadcrumbs = breadcrumbs; if (Reader__web_has_one_section(W)) wt->self_contained = TRUE; Str__copy(wt->cover_sheet_to_use, TL_IS_148); TEMPORARY_TEXT(leafname); { #line 124 "inweb/Chapter 3/The Swarm.w" match_results mr = Regexp__create_mr(); if (Str__eq_wide_string(range, L"0")) { wt->booklet_title = Str__new_from_wide_string(L"Complete Program"); if (W->md->single_file) { Filenames__write_unextended_leafname(leafname, W->md->single_file); } else { WRITE_TO(leafname, "Complete"); } if (wt->theme_match) { #line 156 "inweb/Chapter 3/The Swarm.w" Str__clear(wt->booklet_title); WRITE_TO(wt->booklet_title, "Extracts: %S", wt->theme_match->tag_name); Str__copy(leafname, wt->theme_match->tag_name); } #line 132 "inweb/Chapter 3/The Swarm.w" ; } else if (Regexp__match(&mr, range, L"%d+")) { Str__clear(wt->booklet_title); WRITE_TO(wt->booklet_title, "Chapter %S", range); Str__copy(leafname, wt->booklet_title); } else if (Regexp__match(&mr, range, L"%[A-O]")) { Str__clear(wt->booklet_title); WRITE_TO(wt->booklet_title, "Appendix %S", range); Str__copy(leafname, wt->booklet_title); } else if (Str__eq_wide_string(range, L"P")) { wt->booklet_title = Str__new_from_wide_string(L"Preliminaries"); Str__copy(leafname, wt->booklet_title); } else { Str__copy(wt->booklet_title, range); Str__copy(leafname, wt->booklet_title); Str__clear(wt->cover_sheet_to_use); } LOOP_THROUGH_TEXT(P, leafname) if ((Str__get(P) == '/') || (Str__get(P) == ' ')) Str__put(P, '-'); WRITE_TO(leafname, "%S", Formats__file_extension(wt->format)); Regexp__dispose_of(&mr); } #line 105 "inweb/Chapter 3/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__get_path_to(W->md->single_file); } if (to) { wt->weave_to = to; wt->self_contained = TRUE; } else wt->weave_to = Filenames__in_folder(H, leafname); DISCARD_TEXT(leafname); } #line 58 "inweb/Chapter 3/The Swarm.w" ; if (Weaver__weave_source(W, wt) == 0) /* i.e., the number of lines woven was zero */ Errors__fatal("empty weave request"); Formats__post_process_weave(wt, open_afterwards); /* e.g., run through TeX */ { #line 163 "inweb/Chapter 3/The Swarm.w" PRINT("[%S: %S -> %f", wt->booklet_title, wt->format->format_name, wt->weave_to); Formats__report_on_post_processing(wt); PRINT("]\n"); } #line 62 "inweb/Chapter 3/The Swarm.w" ; } return wt; } #line 86 "inweb/Chapter 3/The Swarm.w" #line 172 "inweb/Chapter 3/The Swarm.w" void Swarm__weave_index_templates(web *W, text_stream *range, weave_pattern *pattern, int self_contained, pathname *into, filename *F, linked_list *crumbs, int docs) { if (!(Bibliographic__data_exists(W->md, TL_IS_149))) Bibliographic__set_datum(W->md, TL_IS_150, TL_IS_151); text_stream *index_leaf = NULL; if (W->md->chaptered) index_leaf = TL_IS_152; else index_leaf = TL_IS_153; filename *OUT = Patterns__obtain_filename(pattern, index_leaf); if (OUT == NULL) OUT = Patterns__obtain_filename(pattern, TL_IS_154); if (OUT) Indexer__run(W, range, OUT, TL_IS_155, NULL, pattern, into, F, crumbs, docs); if (self_contained == FALSE) Patterns__copy_payloads_into_weave(W, pattern); } #line 11 "inweb/Chapter 3/The Indexer.w" void Indexer__cover_sheet_maker(OUTPUT_STREAM, web *W, text_stream *unextended_leafname, weave_target *wt, int halves) { cover_sheet_state state; { #line 40 "inweb/Chapter 3/The Indexer.w" state.halves = halves; state.WEAVE_COVER_TO = OUT; state.target = wt; } #line 14 "inweb/Chapter 3/The Indexer.w" ; TEMPORARY_TEXT(extended_leafname); WRITE_TO(extended_leafname, "%S%S", unextended_leafname, Formats__file_extension(wt->format)); filename *cs_filename = Patterns__obtain_filename(wt->pattern, extended_leafname); DISCARD_TEXT(extended_leafname); TextFiles__read(cs_filename, FALSE, "can't open cover sheet file", TRUE, Indexer__scan_cover_line, NULL, (void *) &state); } #line 38 "inweb/Chapter 3/The Indexer.w" #line 49 "inweb/Chapter 3/The Indexer.w" void Indexer__scan_cover_line(text_stream *line, text_file_position *tfp, void *v_state) { cover_sheet_state *state = (cover_sheet_state *) v_state; text_stream *OUT = state->WEAVE_COVER_TO; int include = FALSE; if (((state->halves & WEAVE_FIRST_HALF) && ((state->halves & IN_SECOND_HALF) == 0)) || ((state->halves & WEAVE_SECOND_HALF) && (state->halves & IN_SECOND_HALF))) include = TRUE; TEMPORARY_TEXT(matter); Str__copy(matter, line); match_results mr = Regexp__create_mr(); if ((include) && ((state->target->self_contained) || (state->target->pattern->embed_CSS)) && (Regexp__match(&mr, matter, L" *%target->pattern, mr.exp[0]); Indexer__transcribe_CSS(matter, CSS_file); } else { while (Regexp__match(&mr, matter, L"(%c*?)%[%[(%c*?)%]%](%c*)")) { text_stream *left = mr.exp[0]; text_stream *command = mr.exp[1]; text_stream *right = mr.exp[2]; if (include) WRITE("%S", left); { #line 82 "inweb/Chapter 3/The Indexer.w" match_results mr2 = Regexp__create_mr(); if (Str__eq_wide_string(command, L"Code")) { state->halves |= IN_SECOND_HALF; } else if (Str__eq_wide_string(command, L"Cover Sheet")) { if (include) { #line 99 "inweb/Chapter 3/The Indexer.w" if (state->target->pattern->based_on) { weave_pattern *saved = state->target->pattern; state->target->pattern = state->target->pattern->based_on; Indexer__cover_sheet_maker(OUT, state->target->weave_web, TL_IS_156, state->target, (state->halves & (WEAVE_FIRST_HALF + WEAVE_SECOND_HALF))); state->target->pattern = saved; } else { Errors__in_text_file("cover sheet recursively includes itself", tfp); } } #line 86 "inweb/Chapter 3/The Indexer.w" ; } else if (Regexp__match(&mr2, command, L"Navigation")) { if (include) { #line 111 "inweb/Chapter 3/The Indexer.w" pathname *P = Filenames__get_path_to(state->target->weave_to); Indexer__nav_column(OUT, P, state->target->weave_web, state->target->weave_range, state->target->pattern, state->target->navigation); } #line 88 "inweb/Chapter 3/The Indexer.w" ; } else if (Regexp__match(&mr2, command, L"Template (%c*?)")) { if (include) { #line 116 "inweb/Chapter 3/The Indexer.w" pathname *P = Filenames__get_path_to(state->target->weave_to); filename *CF = Patterns__obtain_filename(state->target->pattern, mr2.exp[0]); if (CF == NULL) Errors__in_text_file("pattern does not provide this template file", tfp); else Indexer__run(state->target->weave_web, state->target->weave_range, CF, NULL, OUT, state->target->pattern, P, state->target->navigation, NULL, FALSE); } #line 90 "inweb/Chapter 3/The Indexer.w" ; } else if (Bibliographic__data_exists(state->target->weave_web->md, command)) { if (include) { #line 126 "inweb/Chapter 3/The Indexer.w" WRITE("%S", Bibliographic__get_datum(state->target->weave_web->md, command)); } #line 92 "inweb/Chapter 3/The Indexer.w" ; } else { if (include) WRITE("%S", command); } Regexp__dispose_of(&mr2); } #line 72 "inweb/Chapter 3/The Indexer.w" ; Str__copy(matter, right); } } Regexp__dispose_of(&mr); if (include) WRITE("%S\n", matter); DISCARD_TEXT(matter); } #line 131 "inweb/Chapter 3/The Indexer.w" void Indexer__nav_column(OUTPUT_STREAM, pathname *P, web *W, text_stream *range, weave_pattern *pattern, filename *nav) { if (nav) { if (TextFiles__exists(nav)) Indexer__run(W, range, nav, NULL, OUT, pattern, P, NULL, NULL, FALSE); else Errors__fatal_with_file("unable to find navigation file", nav); } else { if (pattern->hierarchical) { filename *F = Filenames__in_folder(Pathnames__up(P), TL_IS_157); if (TextFiles__exists(F)) Indexer__run(W, range, F, NULL, OUT, pattern, P, NULL, NULL, FALSE); } filename *F = Filenames__in_folder(P, TL_IS_158); if (TextFiles__exists(F)) Indexer__run(W, range, F, NULL, OUT, pattern, P, NULL, NULL, FALSE); } } #line 180 "inweb/Chapter 3/The Indexer.w" contents_processor Indexer__new_processor(text_stream *range) { contents_processor cp; cp.no_tlines = 0; cp.restrict_to_range = Str__duplicate(range); cp.stack_pointer = 0; return cp; } #line 194 "inweb/Chapter 3/The Indexer.w" void Indexer__run(web *W, text_stream *range, filename *template_filename, text_stream *contents_page_leafname, text_stream *write_to, weave_pattern *pattern, pathname *P, filename *nav_file, linked_list *crumbs, int docs) { contents_processor actual_cp = Indexer__new_processor(range); actual_cp.nav_web = W; actual_cp.nav_pattern = pattern; actual_cp.nav_path = P; actual_cp.nav_file = nav_file; actual_cp.crumbs = crumbs; actual_cp.docs_mode = docs; contents_processor *cp = &actual_cp; text_stream TO_struct; text_stream *OUT = &TO_struct; { #line 249 "inweb/Chapter 3/The Indexer.w" TextFiles__read(template_filename, FALSE, "can't find contents template", TRUE, Indexer__save_template_line, NULL, cp); if (TRACE_CI_EXECUTION) PRINT("Read template <%f>: %d line(s)\n", template_filename, cp->no_tlines); } #line 207 "inweb/Chapter 3/The Indexer.w" ; { #line 264 "inweb/Chapter 3/The Indexer.w" pathname *H = W->redirect_weaves_to; if (H == NULL) H = Reader__woven_folder(W); if (write_to) OUT = write_to; else { filename *Contents = Filenames__in_folder(H, contents_page_leafname); 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_159, TL_IS_160); PRINT("[Index file: %f]\n", Contents); } } #line 208 "inweb/Chapter 3/The Indexer.w" ; int lpos = 0; /* This is our program counter: a line number in the template */ while (lpos < cp->no_tlines) { match_results mr = Regexp__create_mr(); TEMPORARY_TEXT(tl); Str__copy(tl, cp->tlines[lpos++]); /* Fetch the line at the program counter and advance */ { #line 225 "inweb/Chapter 3/The Indexer.w" if (Regexp__match(&mr, tl, L"(%c*?) ")) Str__copy(tl, mr.exp[0]); /* Strip trailing spaces */ if (TRACE_CI_EXECUTION) { #line 279 "inweb/Chapter 3/The Indexer.w" PRINT("%04d: %S\nStack:", lpos-1, tl); for (int j=0; jstack_pointer; j++) { if (cp->repeat_stack_level[j] == CHAPTER_LEVEL) PRINT(" %d: %S/%S", j, ((chapter *) CONTENT_IN_ITEM(cp->repeat_stack_variable[j], chapter))->md->ch_range, ((chapter *) CONTENT_IN_ITEM(cp->repeat_stack_threshold[j], chapter))->md->ch_range); else if (cp->repeat_stack_level[j] == SECTION_LEVEL) PRINT(" %d: %S/%S", j, ((section *) CONTENT_IN_ITEM(cp->repeat_stack_variable[j], section))->sect_range, ((section *) CONTENT_IN_ITEM(cp->repeat_stack_threshold[j], section))->sect_range); } PRINT("\n"); } #line 227 "inweb/Chapter 3/The Indexer.w" ; if ((pattern->embed_CSS) && (Regexp__match(&mr, tl, L" *%chapters) LOOP_OVER_LINKED_LIST(S, section, C->sections) if (Str__eq(S->sect_range, mr.exp[0])) { Indexer__start_CI_loop(cp, SECTION_LEVEL, S_item, S_item, lpos); Regexp__dispose_of(&mr); goto CYCLE; } LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) if (Str__eq(C->md->ch_range, mr.exp[0])) { Indexer__start_CI_loop(cp, 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", template_filename, lpos); Regexp__dispose_of(&mr); goto CYCLE; } } #line 238 "inweb/Chapter 3/The Indexer.w" ; { #line 323 "inweb/Chapter 3/The Indexer.w" int loop_level = 0; 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, W->chapters); while ((CI) && (CONTENT_IN_ITEM(CI, chapter)->md->imported)) CI = NEXT_ITEM_IN_LINKED_LIST(CI, chapter); if (loop_level == CHAPTER_LEVEL) { from = CI; to = LAST_ITEM_IN_LINKED_LIST(chapter, W->chapters); if (Str__eq_wide_string(cp->restrict_to_range, L"0") == FALSE) { chapter *C; LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) if (Str__eq(C->md->ch_range, cp->restrict_to_range)) { from = C_item; to = from; break; } } } if (loop_level == SECTION_LEVEL) { chapter *within_chapter = CONTENT_IN_ITEM(Indexer__heading_topmost_on_stack(cp, 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, W->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); } } if (from) Indexer__start_CI_loop(cp, loop_level, from, to, lpos); goto CYCLE; } } #line 239 "inweb/Chapter 3/The Indexer.w" ; { #line 365 "inweb/Chapter 3/The Indexer.w" if ((Regexp__match(&mr, command, L"End Repeat")) || (Regexp__match(&mr, command, L"End Select"))) { if (cp->stack_pointer <= 0) Errors__at_position("stack underflow on contents template", template_filename, lpos); if (cp->repeat_stack_level[cp->stack_pointer-1] == SECTION_LEVEL) { linked_list_item *SI = cp->repeat_stack_variable[cp->stack_pointer-1]; if ((SI == cp->repeat_stack_threshold[cp->stack_pointer-1]) || (NEXT_ITEM_IN_LINKED_LIST(SI, section) == NULL)) Indexer__end_CI_loop(cp); else { cp->repeat_stack_variable[cp->stack_pointer-1] = NEXT_ITEM_IN_LINKED_LIST(SI, section); lpos = cp->repeat_stack_startpos[cp->stack_pointer-1]; /* Back round loop */ } } else { linked_list_item *CI = cp->repeat_stack_variable[cp->stack_pointer-1]; if (CI == cp->repeat_stack_threshold[cp->stack_pointer-1]) Indexer__end_CI_loop(cp); else { cp->repeat_stack_variable[cp->stack_pointer-1] = NEXT_ITEM_IN_LINKED_LIST(CI, chapter); lpos = cp->repeat_stack_startpos[cp->stack_pointer-1]; /* Back round loop */ } } goto CYCLE; } } #line 240 "inweb/Chapter 3/The Indexer.w" ; DISCARD_TEXT(command); } { #line 394 "inweb/Chapter 3/The Indexer.w" for (int rstl = cp->stack_pointer-1; rstl >= 0; rstl--) if (cp->repeat_stack_level[cp->stack_pointer-1] == SECTION_LEVEL) { linked_list_item *SI = cp->repeat_stack_threshold[cp->stack_pointer-1]; if (NEXT_ITEM_IN_LINKED_LIST(SI, section) == cp->repeat_stack_variable[cp->stack_pointer-1]) goto CYCLE; } } #line 243 "inweb/Chapter 3/The Indexer.w" ; { #line 440 "inweb/Chapter 3/The Indexer.w" int slen, spos; while ((spos = Regexp__find_expansion(tl, '[', '[', ']', ']', &slen)) >= 0) { TEMPORARY_TEXT(left_part); TEMPORARY_TEXT(varname); TEMPORARY_TEXT(right_part); Str__substr(left_part, Str__start(tl), Str__at(tl, spos)); Str__substr(varname, Str__at(tl, spos+2), Str__at(tl, spos+slen-2)); Str__substr(right_part, Str__at(tl, spos+slen), Str__end(tl)); TEMPORARY_TEXT(substituted); match_results mr = Regexp__create_mr(); if (Bibliographic__data_exists(W->md, varname)) { { #line 495 "inweb/Chapter 3/The Indexer.w" Str__copy(substituted, Bibliographic__get_datum(W->md, varname)); } #line 453 "inweb/Chapter 3/The Indexer.w" ; } else if (Regexp__match(&mr, varname, L"Navigation")) { Indexer__nav_column(substituted, cp->nav_path, cp->nav_web, cp->restrict_to_range, cp->nav_pattern, cp->nav_file); } else if (Regexp__match(&mr, varname, L"Breadcrumbs")) { HTMLFormat__drop_initial_breadcrumbs(substituted, cp->crumbs, cp->docs_mode); } else if (Regexp__match(&mr, varname, L"Modules")) { { #line 554 "inweb/Chapter 3/The Indexer.w" module *M = W->md->as_module; int L = LinkedLists__len(M->dependencies); if (L > 0) { WRITE_TO(substituted, "

Together with the following imported module%s:\n", (L==1)?"":"s"); WRITE_TO(substituted, "

    \n"); Indexer__list_module(substituted, W->md->as_module, FALSE); WRITE_TO(substituted, "
\n"); } } #line 460 "inweb/Chapter 3/The Indexer.w" ; } else if (Regexp__match(&mr, varname, L"Chapter (%c+)")) { text_stream *detail = mr.exp[0]; chapter *C = CONTENT_IN_ITEM( Indexer__heading_topmost_on_stack(cp, CHAPTER_LEVEL), chapter); if (C == NULL) Errors__at_position("no chapter is currently selected", template_filename, lpos); else { #line 507 "inweb/Chapter 3/The Indexer.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, pattern)) { ; } else { WRITE_TO(substituted, "%S for %S", varname, C->md->ch_title); } } #line 468 "inweb/Chapter 3/The Indexer.w" ; } else if (Regexp__match(&mr, varname, L"Section (%c+)")) { text_stream *detail = mr.exp[0]; section *S = CONTENT_IN_ITEM( Indexer__heading_topmost_on_stack(cp, SECTION_LEVEL), section); if (S == NULL) Errors__at_position("no section is currently selected", template_filename, lpos); else { #line 522 "inweb/Chapter 3/The Indexer.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->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")) { TEMPORARY_TEXT(linkto); Str__copy(linkto, S->sect_range); LOOP_THROUGH_TEXT(P, linkto) if ((Str__get(P) == '/') || (Str__get(P) == ' ')) Str__put(P, '-'); WRITE_TO(linkto, ".html"); Str__copy(substituted, linkto); DISCARD_TEXT(linkto); } 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, pattern)) { ; } else { WRITE_TO(substituted, "%S for %S", varname, S->md->sect_title); } } #line 476 "inweb/Chapter 3/The Indexer.w" ; } else if (Regexp__match(&mr, varname, L"Complete (%c+)")) { text_stream *detail = mr.exp[0]; { #line 500 "inweb/Chapter 3/The Indexer.w" if (swarm_leader) if (Formats__substitute_post_processing_data(substituted, swarm_leader, detail, pattern) == FALSE) WRITE_TO(substituted, "%S for complete web", detail); } #line 479 "inweb/Chapter 3/The Indexer.w" ; } else { WRITE_TO(substituted, "%S", varname); } Str__clear(tl); WRITE_TO(tl, "%S%S%S", left_part, substituted, right_part); Regexp__dispose_of(&mr); DISCARD_TEXT(left_part); DISCARD_TEXT(varname); DISCARD_TEXT(substituted); DISCARD_TEXT(right_part); } } #line 244 "inweb/Chapter 3/The Indexer.w" ; } #line 215 "inweb/Chapter 3/The Indexer.w" ; WRITE("%S\n", tl); /* Copy the now finished line to the output */ DISCARD_TEXT(tl); CYCLE: ; Regexp__dispose_of(&mr); } if (write_to == NULL) STREAM_CLOSE(OUT); } #line 257 "inweb/Chapter 3/The Indexer.w" void Indexer__save_template_line(text_stream *line, text_file_position *tfp, void *void_cp) { contents_processor *cp = (contents_processor *) void_cp; if (cp->no_tlines < MAX_TEMPLATE_LINES) cp->tlines[cp->no_tlines++] = Str__duplicate(line); } #line 409 "inweb/Chapter 3/The Indexer.w" linked_list_item *Indexer__heading_topmost_on_stack(contents_processor *cp, int level) { for (int rstl = cp->stack_pointer-1; rstl >= 0; rstl--) if (cp->repeat_stack_level[rstl] == level) return cp->repeat_stack_variable[rstl]; return NULL; } #line 420 "inweb/Chapter 3/The Indexer.w" void Indexer__start_CI_loop(contents_processor *cp, int level, linked_list_item *from, linked_list_item *to, int pos) { if (cp->stack_pointer < CI_STACK_CAPACITY) { cp->repeat_stack_level[cp->stack_pointer] = level; cp->repeat_stack_variable[cp->stack_pointer] = from; cp->repeat_stack_threshold[cp->stack_pointer] = to; cp->repeat_stack_startpos[cp->stack_pointer++] = pos; } } void Indexer__end_CI_loop(contents_processor *cp) { cp->stack_pointer--; } #line 566 "inweb/Chapter 3/The Indexer.w" void Indexer__list_module(OUTPUT_STREAM, module *M, int list_this) { if (list_this) { WRITE("
  • %S - ", M->module_name); TEMPORARY_TEXT(url); WRITE_TO(url, "%p", M->module_location); Readme__write_var(OUT, url, TL_IS_161); DISCARD_TEXT(url); WRITE("

  • "); } module *N; LOOP_OVER_LINKED_LIST(N, module, M->dependencies) Indexer__list_module(OUT, N, TRUE); } #line 583 "inweb/Chapter 3/The Indexer.w" void Indexer__transcribe_CSS(OUTPUT_STREAM, filename *CSS_file) { WRITE("\n"); } void Indexer__copy_CSS(text_stream *line, text_file_position *tfp, void *X) { text_stream *OUT = (text_stream *) X; WRITE("%S\n", line); } #line 16 "inweb/Chapter 3/The Weaver.w" int Weaver__weave_source(web *W, weave_target *wv) { 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); { #line 37 "inweb/Chapter 3/The Weaver.w" TEMPORARY_TEXT(banner); WRITE_TO(banner, "Weave of '%S' generated by %s", wv->booklet_title, INWEB_BUILD); Formats__top(OUT, wv, banner); DISCARD_TEXT(banner); } #line 22 "inweb/Chapter 3/The Weaver.w" ; if ((Str__len(wv->cover_sheet_to_use) > 0) && (Reader__web_has_one_section(W) == FALSE)) { #line 43 "inweb/Chapter 3/The Weaver.w" if (!(Bibliographic__data_exists(W->md, TL_IS_162))) Bibliographic__set_datum(W->md, TL_IS_163, wv->booklet_title); Indexer__cover_sheet_maker(OUT, W, wv->cover_sheet_to_use, wv, WEAVE_FIRST_HALF); } #line 24 "inweb/Chapter 3/The Weaver.w" ; int lines_woven = 0; section *latest_section = NULL; { #line 48 "inweb/Chapter 3/The Weaver.w" weaver_state state_at; weaver_state *state = &state_at; { #line 99 "inweb/Chapter 3/The Weaver.w" state->kind_of_material = REGULAR_MATERIAL; state->line_break_pending = FALSE; state->next_heading_without_vertical_skip = FALSE; state->show_section_toc_soon = FALSE; state->horizontal_rule_just_drawn = FALSE; state->in_run_of_definitions = FALSE; state->last_extract_from = NULL; state->last_endnoted_para = NULL; state->substantive_comment = FALSE; state->chaptermark = Str__new(); state->sectionmark = Str__new(); } #line 49 "inweb/Chapter 3/The Weaver.w" ; chapter *C; section *S; LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) if (C->md->imported == FALSE) { Str__clear(state->chaptermark); LOOP_OVER_LINKED_LIST(S, section, C->sections) if (Reader__range_within(S->sect_range, wv->weave_range)) { latest_section = S; LanguageMethods__begin_weave(S, wv); Str__clear(state->sectionmark); { #line 114 "inweb/Chapter 3/The Weaver.w" paragraph *current_paragraph = NULL; for (source_line *L = S->first_line; L; L = L->next_line) { if ((Tags__tagged_with(L->owning_paragraph, wv->theme_match)) && (LanguageMethods__skip_in_weaving(S->sect_language, wv, L) == FALSE)) { lines_woven++; { #line 126 "inweb/Chapter 3/The Weaver.w" /* In principle, all of these source lines should be woven, but... */ { #line 150 "inweb/Chapter 3/The Weaver.w" if (L->category == INTERFACE_BODY_LCAT) continue; if (L->category == PURPOSE_BODY_LCAT) continue; if (L->category == BEGIN_CODE_LCAT) { state->line_break_pending = FALSE; continue; } } #line 127 "inweb/Chapter 3/The Weaver.w" ; { #line 161 "inweb/Chapter 3/The Weaver.w" if (L->category == COMMAND_LCAT) { if (L->command_code == PAGEBREAK_CMD) Formats__pagebreak(OUT, wv); if (L->command_code == GRAMMAR_INDEX_CMD) InCSupport__weave_grammar_index(OUT); if (L->command_code == FIGURE_CMD) { #line 170 "inweb/Chapter 3/The Weaver.w" text_stream *figname = L->text_operand; match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, figname, L"(%d+)cm: (%c+)")) { if (S->md->using_syntax > V1_SYNTAX) Parser__wrong_version(S->md->using_syntax, L, "[[Figure: Xcm:...]]", V1_SYNTAX); Formats__figure(OUT, wv, mr.exp[1], Str__atoi(mr.exp[0], 0), -1, NULL); } else if (Regexp__match(&mr, figname, L"(%c+) width (%d+)cm")) { if (S->md->using_syntax < V2_SYNTAX) Parser__wrong_version(S->md->using_syntax, L, "[[F width Xcm]]", V2_SYNTAX); Formats__figure(OUT, wv, mr.exp[0], Str__atoi(mr.exp[1], 0), -1, NULL); } else if (Regexp__match(&mr, figname, L"(%c+) height (%d+)cm")) { if (S->md->using_syntax < V2_SYNTAX) Parser__wrong_version(S->md->using_syntax, L, "[[F height Xcm]]", V2_SYNTAX); Formats__figure(OUT, wv, mr.exp[0], -1, Str__atoi(mr.exp[1], 0), NULL); } else if (Regexp__match(&mr, figname, L"(%c+txt) as (%c+)")) { if (S->md->using_syntax < V2_SYNTAX) Parser__wrong_version(S->md->using_syntax, L, "[[F as L]]", V2_SYNTAX); programming_language *pl = Languages__find_by_name(mr.exp[1]); Formats__figure(OUT, wv, mr.exp[0], -1, -1, pl); } else { Formats__figure(OUT, wv, figname, -1, -1, NULL); } Regexp__dispose_of(&mr); } #line 164 "inweb/Chapter 3/The Weaver.w" ; /* Otherwise assume it was a tangler command, and ignore it here */ continue; } } #line 128 "inweb/Chapter 3/The Weaver.w" ; /* Some of the more baroque front matter of a section... */ { #line 200 "inweb/Chapter 3/The Weaver.w" if (L->category == PURPOSE_LCAT) { Formats__subheading(OUT, wv, 2, S->sect_purpose, NULL); Weaver__weave_table_of_contents(OUT, wv, S); continue; } } #line 131 "inweb/Chapter 3/The Weaver.w" ; { #line 209 "inweb/Chapter 3/The Weaver.w" if ((state->show_section_toc_soon == 1) && (Regexp__string_is_white_space(L->text))) { state->show_section_toc_soon = FALSE; if (Weaver__weave_table_of_contents(OUT, wv, S)) state->horizontal_rule_just_drawn = TRUE; else state->horizontal_rule_just_drawn = FALSE; } } #line 132 "inweb/Chapter 3/The Weaver.w" ; { #line 221 "inweb/Chapter 3/The Weaver.w" if (L->category == INTERFACE_LCAT) { state->horizontal_rule_just_drawn = FALSE; continue; } } #line 133 "inweb/Chapter 3/The Weaver.w" ; { #line 229 "inweb/Chapter 3/The Weaver.w" if (L->category == DEFINITIONS_LCAT) { Formats__subheading(OUT, wv, 2, TL_IS_166, NULL); state->next_heading_without_vertical_skip = TRUE; state->horizontal_rule_just_drawn = FALSE; continue; } } #line 134 "inweb/Chapter 3/The Weaver.w" ; { #line 241 "inweb/Chapter 3/The Weaver.w" if (L->category == BAR_LCAT) { { #line 643 "inweb/Chapter 3/The Weaver.w" int mode_now = state->kind_of_material; if (state->kind_of_material != REGULAR_MATERIAL) { state->kind_of_material = REGULAR_MATERIAL; Formats__change_material(OUT, wv, mode_now, state->kind_of_material, TRUE); } if ((current_paragraph) && (current_paragraph != state->last_endnoted_para)) { state->last_endnoted_para = current_paragraph; Weaver__show_endnotes_on_previous_paragraph(OUT, wv, current_paragraph); } if (L) current_paragraph = L->owning_paragraph; } #line 242 "inweb/Chapter 3/The Weaver.w" ; state->kind_of_material = REGULAR_MATERIAL; state->next_heading_without_vertical_skip = TRUE; if (state->horizontal_rule_just_drawn == FALSE) Formats__bar(OUT, wv); continue; } } #line 135 "inweb/Chapter 3/The Weaver.w" ; /* The crucial junction point between modes... */ { #line 492 "inweb/Chapter 3/The Weaver.w" if ((L->category == HEADING_START_LCAT) || (L->category == PARAGRAPH_START_LCAT) || (L->category == CHAPTER_HEADING_LCAT) || (L->category == SECTION_HEADING_LCAT)) { state->in_run_of_definitions = FALSE; { #line 643 "inweb/Chapter 3/The Weaver.w" int mode_now = state->kind_of_material; if (state->kind_of_material != REGULAR_MATERIAL) { state->kind_of_material = REGULAR_MATERIAL; Formats__change_material(OUT, wv, mode_now, state->kind_of_material, TRUE); } if ((current_paragraph) && (current_paragraph != state->last_endnoted_para)) { state->last_endnoted_para = current_paragraph; Weaver__show_endnotes_on_previous_paragraph(OUT, wv, current_paragraph); } if (L) current_paragraph = L->owning_paragraph; } #line 497 "inweb/Chapter 3/The Weaver.w" ; if (wv->theme_match) { #line 527 "inweb/Chapter 3/The Weaver.w" if ((L->owning_paragraph) && (L->owning_paragraph->starts_on_new_page)) Formats__pagebreak(OUT, wv); } #line 499 "inweb/Chapter 3/The Weaver.w" ; LanguageMethods__reset_syntax_colouring(S->sect_language); /* a precaution: limits bad colouring accidents to one para */ int weight = 0; if (L->category == HEADING_START_LCAT) weight = 1; if (L->category == SECTION_HEADING_LCAT) weight = 2; if (L->category == CHAPTER_HEADING_LCAT) weight = 3; { #line 540 "inweb/Chapter 3/The Weaver.w" if (weight == 3) { Str__copy(state->chaptermark, L->text_operand); Str__clear(state->sectionmark); } if (weight == 2) { Str__copy(state->sectionmark, L->text_operand); if (wv->pattern->show_abbrevs == FALSE) Str__clear(state->chaptermark); else if (Str__len(S->sect_range) > 0) Str__copy(state->chaptermark, S->sect_range); if (Str__len(state->chaptermark) > 0) { Str__clear(state->sectionmark); WRITE_TO(state->sectionmark, " - %S", L->text_operand); } } } #line 506 "inweb/Chapter 3/The Weaver.w" ; text_stream *TeX_macro = NULL; { #line 570 "inweb/Chapter 3/The Weaver.w" switch (weight) { case 0: TeX_macro = TL_IS_173; break; case 1: TeX_macro = TL_IS_174; break; case 2: TeX_macro = TL_IS_175; break; default: TeX_macro = TL_IS_176; break; } if (wv->theme_match) { #line 589 "inweb/Chapter 3/The Weaver.w" switch (weight) { case 0: TeX_macro = TL_IS_179; break; case 1: TeX_macro = TL_IS_180; break; case 2: TeX_macro = TL_IS_181; break; default: TeX_macro = TL_IS_182; break; } if (weight >= 0) { weight = 0; } text_stream *cap = Tags__retrieve_caption(L->owning_paragraph, wv->theme_match); if (Str__len(cap) > 0) { Formats__subheading(OUT, wv, 1, cap, C->md->ch_title); state->last_extract_from = S; } else if (state->last_extract_from != S) { state->last_extract_from = S; TEMPORARY_TEXT(extr); WRITE_TO(extr, "From %S: %S", C->md->ch_title, S->md->sect_title); Formats__subheading(OUT, wv, 1, extr, C->md->ch_title); DISCARD_TEXT(extr); } } #line 576 "inweb/Chapter 3/The Weaver.w" ; if ((state->next_heading_without_vertical_skip) && (weight < 2)) { state->next_heading_without_vertical_skip = FALSE; switch (weight) { case 0: TeX_macro = TL_IS_177; break; case 1: TeX_macro = TL_IS_178; break; } } } #line 509 "inweb/Chapter 3/The Weaver.w" ; TEMPORARY_TEXT(heading_text); { #line 609 "inweb/Chapter 3/The Weaver.w" if (weight == 3) { TEMPORARY_TEXT(brief_title); match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, C->md->ch_title, L"%c*?: (%c*)")) Str__copy(brief_title, mr.exp[0]); else Str__copy(brief_title, C->md->ch_title); WRITE_TO(heading_text, "%S: %S", C->md->ch_range, brief_title); DISCARD_TEXT(brief_title); Regexp__dispose_of(&mr); } else if ((weight == 2) && (Reader__web_has_one_section(W))) { Str__copy(heading_text, Bibliographic__get_datum(W->md, TL_IS_183)); } else { if ((weight == 2) && (wv->pattern->number_sections) && (S->printed_number >= 0)) WRITE_TO(heading_text, "%d. ", S->printed_number); WRITE_TO(heading_text, "%S", L->text_operand); } } #line 512 "inweb/Chapter 3/The Weaver.w" ; Formats__paragraph_heading(OUT, wv, TeX_macro, S, L->owning_paragraph, heading_text, state->chaptermark, state->sectionmark, weight); DISCARD_TEXT(heading_text); if (weight == 0) state->substantive_comment = FALSE; else state->substantive_comment = TRUE; { #line 631 "inweb/Chapter 3/The Weaver.w" if (Str__len(L->text_operand2) > 0) { TEMPORARY_TEXT(matter); WRITE_TO(matter, "%S\n", L->text_operand2); Formats__text(OUT, wv, matter); DISCARD_TEXT(matter); state->substantive_comment = TRUE; } } #line 520 "inweb/Chapter 3/The Weaver.w" ; if (weight == 3) Formats__chapter_title_page(OUT, wv, C); continue; } } #line 138 "inweb/Chapter 3/The Weaver.w" ; /* With all exotica dealt with, we now just have material to weave verbatim... */ TEMPORARY_TEXT(matter); Str__copy(matter, L->text); if (L->is_commentary) { #line 254 "inweb/Chapter 3/The Weaver.w" { #line 266 "inweb/Chapter 3/The Weaver.w" if (L->category == SOURCE_DISPLAY_LCAT) { Formats__display_line(OUT, wv, L->text_operand); continue; } } #line 254 "inweb/Chapter 3/The Weaver.w" ; { #line 275 "inweb/Chapter 3/The Weaver.w" if (Regexp__string_is_white_space(matter)) { if ((L->next_line) && (L->next_line->category == COMMENT_BODY_LCAT) && (state->substantive_comment)) { match_results mr = Regexp__create_mr(); if ((state->kind_of_material != CODE_MATERIAL) || (Regexp__match(&mr, matter, L"\t|(%c*)|(%c*?)"))) Formats__blank_line(OUT, wv, TRUE); Regexp__dispose_of(&mr); } continue; } } #line 255 "inweb/Chapter 3/The Weaver.w" ; { #line 291 "inweb/Chapter 3/The Weaver.w" match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, matter, L"%(...%) (%c*)")) { /* continue single */ Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL, state->substantive_comment); state->kind_of_material = REGULAR_MATERIAL; Formats__item(OUT, wv, 1, TL_IS_167); Str__copy(matter, mr.exp[0]); } else if (Regexp__match(&mr, matter, L"%(-...%) (%c*)")) { /* continue double */ Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL, state->substantive_comment); state->kind_of_material = REGULAR_MATERIAL; Formats__item(OUT, wv, 2, TL_IS_168); Str__copy(matter, mr.exp[0]); } else if (Regexp__match(&mr, matter, L"%((%i+)%) (%c*)")) { /* begin single */ Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL, state->substantive_comment); state->kind_of_material = REGULAR_MATERIAL; Formats__item(OUT, wv, 1, mr.exp[0]); Str__copy(matter, mr.exp[1]); } else if (Regexp__match(&mr, matter, L"%(-(%i+)%) (%c*)")) { /* begin double */ Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL, state->substantive_comment); state->kind_of_material = REGULAR_MATERIAL; Formats__item(OUT, wv, 2, mr.exp[0]); Str__copy(matter, mr.exp[1]); } Regexp__dispose_of(&mr); } #line 256 "inweb/Chapter 3/The Weaver.w" ; { #line 323 "inweb/Chapter 3/The Weaver.w" match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, matter, L"\t|(%c*)|(%c*?)")) { if (state->kind_of_material != CODE_MATERIAL) { Formats__change_material(OUT, wv, state->kind_of_material, CODE_MATERIAL, TRUE); state->kind_of_material = CODE_MATERIAL; } TEMPORARY_TEXT(original); Str__copy(original, mr.exp[0]); Str__copy(matter, mr.exp[1]); TEMPORARY_TEXT(colouring); for (int i=0; ikind_of_material != REGULAR_MATERIAL) { Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL, TRUE); state->kind_of_material = REGULAR_MATERIAL; } Regexp__dispose_of(&mr); } #line 257 "inweb/Chapter 3/The Weaver.w" ; state->substantive_comment = TRUE; WRITE_TO(matter, "\n"); Formats__text(OUT, wv, matter); continue; } #line 142 "inweb/Chapter 3/The Weaver.w" else { #line 351 "inweb/Chapter 3/The Weaver.w" { #line 387 "inweb/Chapter 3/The Weaver.w" int mode_now = state->kind_of_material; if (state->kind_of_material != CODE_MATERIAL) { if (L->category == MACRO_DEFINITION_LCAT) state->kind_of_material = MACRO_MATERIAL; else if ((L->category == BEGIN_DEFINITION_LCAT) || (L->category == CONT_DEFINITION_LCAT)) state->kind_of_material = 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)) state->kind_of_material = DEFINITION_MATERIAL; else state->kind_of_material = CODE_MATERIAL; Formats__change_material(OUT, wv, mode_now, state->kind_of_material, state->substantive_comment); state->line_break_pending = FALSE; } } #line 351 "inweb/Chapter 3/The Weaver.w" ; { #line 409 "inweb/Chapter 3/The Weaver.w" if (state->line_break_pending) { Formats__blank_line(OUT, wv, FALSE); state->line_break_pending = FALSE; } if (Regexp__string_is_white_space(matter)) { state->line_break_pending = TRUE; continue; } } #line 352 "inweb/Chapter 3/The Weaver.w" ; int tab_stops_of_indentation = 0; { #line 422 "inweb/Chapter 3/The Weaver.w" int spaces_in = 0; while (Characters__is_space_or_tab(Str__get_first_char(matter))) { if (Str__get_first_char(matter) == '\t') { spaces_in = 0; tab_stops_of_indentation++; } else { spaces_in++; if (spaces_in == 4) { tab_stops_of_indentation++; spaces_in = 0; } } Str__delete_first_character(matter); } } #line 355 "inweb/Chapter 3/The Weaver.w" ; TEMPORARY_TEXT(prefatory); TEMPORARY_TEXT(concluding_comment); { #line 442 "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 359 "inweb/Chapter 3/The Weaver.w" ; { #line 457 "inweb/Chapter 3/The Weaver.w" 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_171); 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_172); Str__copy(matter, mr.exp[0]); } Regexp__dispose_of(&mr); } #line 360 "inweb/Chapter 3/The Weaver.w" ; if (LanguageMethods__weave_code_line(OUT, S->sect_language, wv, W, C, S, L, matter, concluding_comment)) continue; TEMPORARY_TEXT(colouring); LanguageMethods__syntax_colour(OUT, S->sect_language, wv, W, C, S, L, matter, colouring); int found = 0; { #line 468 "inweb/Chapter 3/The Weaver.w" match_results mr = Regexp__create_mr(); while (Regexp__match(&mr, matter, L"(%c*?)%@%<(%c*?)%@%>(%c*)")) { Str__copy(matter, mr.exp[2]); para_macro *pmac = Macros__find_by_name(mr.exp[1], S); Formats__source_code(OUT, wv, tab_stops_of_indentation, prefatory, mr.exp[0], colouring, concluding_comment, (found == 0)?TRUE:FALSE, FALSE, TRUE); LanguageMethods__reset_syntax_colouring(S->sect_language); found++; int defn = (L->owning_paragraph == pmac->defining_paragraph)?TRUE:FALSE; if (defn) state->in_run_of_definitions = FALSE; Formats__para_macro(OUT, wv, pmac, defn); if (defn) Str__clear(matter); TEMPORARY_TEXT(temp); int L = Str__len(colouring); for (int i = L - Str__len(matter); i < L; i++) PUT_TO(temp, Str__get_at(colouring, i)); Str__copy(colouring, temp); DISCARD_TEXT(temp); } Regexp__dispose_of(&mr); } #line 369 "inweb/Chapter 3/The Weaver.w" ; if (Str__len(prefatory) > 0) { state->in_run_of_definitions = TRUE; } else { if (state->in_run_of_definitions) Formats__after_definitions(OUT, wv); state->in_run_of_definitions = FALSE; } Formats__source_code(OUT, wv, tab_stops_of_indentation, prefatory, matter, colouring, concluding_comment, (found == 0)?TRUE:FALSE, TRUE, TRUE); DISCARD_TEXT(colouring); DISCARD_TEXT(concluding_comment); DISCARD_TEXT(prefatory); continue; } #line 143 "inweb/Chapter 3/The Weaver.w" ; DISCARD_TEXT(matter); } #line 119 "inweb/Chapter 3/The Weaver.w" ; } } source_line *L = NULL; { #line 643 "inweb/Chapter 3/The Weaver.w" int mode_now = state->kind_of_material; if (state->kind_of_material != REGULAR_MATERIAL) { state->kind_of_material = REGULAR_MATERIAL; Formats__change_material(OUT, wv, mode_now, state->kind_of_material, TRUE); } if ((current_paragraph) && (current_paragraph != state->last_endnoted_para)) { state->last_endnoted_para = current_paragraph; Weaver__show_endnotes_on_previous_paragraph(OUT, wv, current_paragraph); } if (L) current_paragraph = L->owning_paragraph; } #line 123 "inweb/Chapter 3/The Weaver.w" ; } #line 60 "inweb/Chapter 3/The Weaver.w" ; } } } #line 27 "inweb/Chapter 3/The Weaver.w" ; if ((Str__len(wv->cover_sheet_to_use) > 0) && (Reader__web_has_one_section(W) == FALSE)) { #line 65 "inweb/Chapter 3/The Weaver.w" if (!(Bibliographic__data_exists(W->md, TL_IS_164))) Bibliographic__set_datum(W->md, TL_IS_165, wv->booklet_title); Indexer__cover_sheet_maker(OUT, W, wv->cover_sheet_to_use, wv, WEAVE_SECOND_HALF); } #line 29 "inweb/Chapter 3/The Weaver.w" ; { #line 70 "inweb/Chapter 3/The Weaver.w" TEMPORARY_TEXT(rennab); WRITE_TO(rennab, "End of weave"); Formats__tail(OUT, wv, rennab, latest_section); DISCARD_TEXT(rennab); } #line 30 "inweb/Chapter 3/The Weaver.w" ; STREAM_CLOSE(OUT); return lines_woven; } #line 82 "inweb/Chapter 3/The Weaver.w" #line 97 "inweb/Chapter 3/The Weaver.w" #line 659 "inweb/Chapter 3/The Weaver.w" void Weaver__show_endnotes_on_previous_paragraph(OUTPUT_STREAM, weave_target *wv, paragraph *P) { Tags__show_endnote_on_ifdefs(OUT, wv, P); if (P->defines_macro) { #line 672 "inweb/Chapter 3/The Weaver.w" Formats__endnote(OUT, wv, 1); Formats__text(OUT, wv, TL_IS_184); int ct = 0; macro_usage *mu; LOOP_OVER_LINKED_LIST(mu, macro_usage, P->defines_macro->macro_usages) ct++; if (ct == 1) Formats__text(OUT, wv, TL_IS_185); 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) Formats__text(OUT, wv, TL_IS_186); else Formats__text(OUT, wv, TL_IS_187); } else { Formats__text(OUT, wv, TL_IS_188); } Formats__locale(OUT, wv, mu->used_in_paragraph, NULL); used_flag = TRUE; k++; switch (mu->multiplicity) { case 1: break; case 2: Formats__text(OUT, wv, TL_IS_189); break; case 3: Formats__text(OUT, wv, TL_IS_190); break; case 4: Formats__text(OUT, wv, TL_IS_191); break; case 5: Formats__text(OUT, wv, TL_IS_192); break; default: { TEMPORARY_TEXT(mt); WRITE_TO(mt, " (%d times)", mu->multiplicity); Formats__text(OUT, wv, mt); DISCARD_TEXT(mt); break; } } } } Formats__text(OUT, wv, TL_IS_193); Formats__endnote(OUT, wv, 2); } #line 662 "inweb/Chapter 3/The Weaver.w" ; function *fn; LOOP_OVER_LINKED_LIST(fn, function, P->functions) { #line 711 "inweb/Chapter 3/The Weaver.w" Formats__endnote(OUT, wv, 1); hash_table_entry *hte = Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section, fn->function_name, FALSE); Formats__text(OUT, wv, TL_IS_194); Formats__text(OUT, wv, 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 735 "inweb/Chapter 3/The Weaver.w" if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_198); 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 (last_cited_in != P->under_section) Formats__text(OUT, wv, TL_IS_199); else Formats__text(OUT, wv, TL_IS_200); } Formats__text(OUT, wv, hteu->usage_recorded_at->under_section->sect_range); Formats__text(OUT, wv, TL_IS_201); } if (count_under++ > 0) Formats__text(OUT, wv, TL_IS_202); Formats__locale(OUT, wv, hteu->usage_recorded_at, NULL); last_cited_in = hteu->usage_recorded_at->under_section; } #line 724 "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 735 "inweb/Chapter 3/The Weaver.w" if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_198); 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 (last_cited_in != P->under_section) Formats__text(OUT, wv, TL_IS_199); else Formats__text(OUT, wv, TL_IS_200); } Formats__text(OUT, wv, hteu->usage_recorded_at->under_section->sect_range); Formats__text(OUT, wv, TL_IS_201); } if (count_under++ > 0) Formats__text(OUT, wv, TL_IS_202); Formats__locale(OUT, wv, hteu->usage_recorded_at, NULL); last_cited_in = hteu->usage_recorded_at->under_section; } #line 727 "inweb/Chapter 3/The Weaver.w" ; if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_195); if ((last_cited_in != P->under_section) && (last_cited_in)) Formats__text(OUT, wv, TL_IS_196); Formats__text(OUT, wv, TL_IS_197); Formats__endnote(OUT, wv, 2); } #line 665 "inweb/Chapter 3/The Weaver.w" ; c_structure *st; LOOP_OVER_LINKED_LIST(st, c_structure, P->structures) { #line 752 "inweb/Chapter 3/The Weaver.w" Formats__endnote(OUT, wv, 1); Formats__text(OUT, wv, TL_IS_203); Formats__text(OUT, wv, 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) Formats__text(OUT, wv, TL_IS_204); else { Formats__text(OUT, wv, TL_IS_205); int c = 0; LOOP_OVER(S, section) if ((S->scratch_flag) && (S != P->under_section)) { if (c++ > 0) Formats__text(OUT, wv, TL_IS_206); Formats__text(OUT, wv, S->sect_range); } if (P->under_section->scratch_flag) Formats__text(OUT, wv, TL_IS_207); } Formats__text(OUT, wv, TL_IS_208); Formats__endnote(OUT, wv, 2); } #line 668 "inweb/Chapter 3/The Weaver.w" ; } #line 796 "inweb/Chapter 3/The Weaver.w" int Weaver__weave_table_of_contents(OUTPUT_STREAM, weave_target *wv, 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; Formats__toc(OUT, wv, 1, S->sect_range, TL_IS_209, NULL); noteworthy = 0; LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs) if ((P->weight > 0) && ((S->barred == FALSE) || (P->above_bar == FALSE))) { if (noteworthy > 0) Formats__toc(OUT, wv, 2, TL_IS_210, TL_IS_211, NULL); TEMPORARY_TEXT(loc); WRITE_TO(loc, "%S%S", P->ornament, P->paragraph_number); Formats__toc(OUT, wv, 3, loc, P->first_line_in_paragraph->text_operand, P); DISCARD_TEXT(loc); noteworthy++; } Formats__toc(OUT, wv, 4, TL_IS_212, TL_IS_213, NULL); return TRUE; } #line 14 "inweb/Chapter 3/The Tangler.w" void Tangler__go(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 39 "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 71 "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 87 "inweb/Chapter 3/The Tangler.w" if (L->owning_paragraph == NULL) Main__error_in_web(TL_IS_214, 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 76 "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 87 "inweb/Chapter 3/The Tangler.w" if (L->owning_paragraph == NULL) Main__error_in_web(TL_IS_214, 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 81 "inweb/Chapter 3/The Tangler.w" ; LanguageMethods__close_ifdef(OUT, lang, L->text_operand, FALSE); } Enumerations__define_extents(OUT, target, lang); } #line 49 "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 100 "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" ; LanguageMethods__additional_tangling(lang, W, target); } #line 109 "inweb/Chapter 3/The Tangler.w" void Tangler__tangle_paragraph(OUTPUT_STREAM, paragraph *P) { Tags__open_ifdefs(OUT, P); int contiguous = FALSE; for (source_line *L = P->first_line_in_paragraph; ((L) && (L->owning_paragraph == P)); L = L->next_line) { if (LanguageMethods__will_insert_in_tangle(P->under_section->sect_language, L)) { { #line 134 "inweb/Chapter 3/The Tangler.w" if (contiguous == FALSE) { contiguous = TRUE; LanguageMethods__insert_line_marker(OUT, P->under_section->sect_language, L); } } #line 115 "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 134 "inweb/Chapter 3/The Tangler.w" if (contiguous == FALSE) { contiguous = TRUE; LanguageMethods__insert_line_marker(OUT, P->under_section->sect_language, L); } } #line 121 "inweb/Chapter 3/The Tangler.w" ; Tangler__tangle_code(OUT, L->text, P->under_section, L); WRITE("\n"); } } Tags__close_ifdefs(OUT, P); } #line 144 "inweb/Chapter 3/The Tangler.w" void Tangler__tangle_code(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 176 "inweb/Chapter 3/The Tangler.w" TEMPORARY_TEXT(temp); Str__copy(temp, original); Str__truncate(temp, mpos); LanguageMethods__tangle_code(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_215, 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_code(OUT, rest, S, L); DISCARD_TEXT(rest); DISCARD_TEXT(temp); } #line 150 "inweb/Chapter 3/The Tangler.w" else if (spos >= 0) { #line 216 "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_code(OUT, rest, S, L); DISCARD_TEXT(rest); DISCARD_TEXT(temp); } #line 152 "inweb/Chapter 3/The Tangler.w" else LanguageMethods__tangle_code(OUT, S->sect_language, original); /* this is usually what happens */ } #line 241 "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) { programming_language *pl; { #line 21 "inweb/Chapter 4/Programming Languages.w" LOOP_OVER(pl, programming_language) if (Str__eq(lname, pl->language_name)) return pl; } #line 12 "inweb/Chapter 4/Programming Languages.w" ; { #line 26 "inweb/Chapter 4/Programming Languages.w" pathname *P = Languages__default_directory(); TEMPORARY_TEXT(leaf); WRITE_TO(leaf, "%S.ildf", lname); filename *F = Filenames__in_folder(P, leaf); DISCARD_TEXT(leaf); if (TextFiles__exists(F) == FALSE) Errors__fatal_with_text( "unsupported programming language '%S'", lname); pl = Languages__read_definition(F); } #line 13 "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 39 "inweb/Chapter 4/Programming Languages.w" programming_language *Languages__default(void) { return Languages__find_by_name(TL_IS_216); } void Languages__show(OUTPUT_STREAM) { WRITE("Inweb can see the following programming language definitions:\n\n"); programming_language *pl; LOOP_OVER(pl, programming_language) WRITE("%S: %S\n", pl->language_name, pl->language_details); } #line 53 "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 (Str__get_last_char(leafname) != FOLDER_SEPARATOR) { filename *F = Filenames__in_folder(P, leafname); Languages__read_definition(F); } } DISCARD_TEXT(leafname); Directories__close(D); } pathname *Languages__default_directory(void) { return Pathnames__subfolder(path_to_inweb, TL_IS_217); } #line 114 "inweb/Chapter 4/Programming Languages.w" #line 126 "inweb/Chapter 4/Programming Languages.w" programming_language *Languages__read_definition(filename *F) { programming_language *pl = CREATE(programming_language); { #line 140 "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->reserved_words = NEW_LINKED_LIST(reserved_word); pl->built_in_keywords.analysis_hash_initialised = FALSE; pl->program = NULL; pl->methods = Methods__new_set(); } #line 129 "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 183 "inweb/Chapter 4/Programming Languages.w" if (pl->C_like) CLike__make_c_like(pl); if (Str__eq(pl->language_name, TL_IS_218)) InCSupport__add_features(pl); ACMESupport__add_fallbacks(pl); } #line 135 "inweb/Chapter 4/Programming Languages.w" ; return pl; } #line 190 "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 287 "inweb/Chapter 4/Programming Languages.w" if (Str__eq(line, TL_IS_248)) { 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"runs of (%c+) {")) { colouring_rule *rule = Languages__new_rule(state->current_block); int r = UNQUOTED_COLOUR; if (Str__ne(mr.exp[0], TL_IS_249)) r = Languages__colour(mr.exp[0], tfp); rule->execute_block = Languages__new_block(state->current_block, 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); 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 199 "inweb/Chapter 4/Programming Languages.w" else { #line 208 "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, mr.exp[0], Languages__colour(mr.exp[1], tfp), tfp); } else if (Regexp__match(&mr, line, L"keyword (%C+)")) { Languages__reserved(pl, mr.exp[0], 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_219)) pl->language_name = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_220)) pl->language_details = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_221)) pl->file_extension = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_222)) pl->line_comment = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_223)) pl->whole_line_comment = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_224)) pl->multiline_comment_open = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_225)) pl->multiline_comment_close = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_226)) pl->string_literal = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_227)) pl->string_literal_escape = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_228)) pl->character_literal = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_229)) pl->character_literal_escape = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_230)) pl->binary_literal_prefix = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_231)) pl->octal_literal_prefix = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_232)) pl->hexadecimal_literal_prefix = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_233)) pl->negative_literal_prefix = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_234)) pl->shebang = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_235)) pl->line_marker = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_236)) pl->before_macro_expansion = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_237)) pl->after_macro_expansion = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_238)) pl->start_definition = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_239)) pl->prolong_definition = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_240)) pl->end_definition = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_241)) pl->start_ifdef = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_242)) pl->start_ifndef = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_243)) pl->end_ifdef = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_244)) pl->end_ifndef = Languages__text(value, tfp); else if (Str__eq(key, TL_IS_245)) pl->C_like = Languages__boolean(value, tfp); else if (Str__eq(key, TL_IS_246)) pl->suppress_disclaimer = Languages__boolean(value, tfp); else if (Str__eq(key, TL_IS_247)) pl->supports_namespaces = Languages__boolean(value, tfp); else { Errors__in_text_file("unknown property name before ':'", tfp); } } else { Errors__in_text_file("line in language definition illegible", tfp); } } #line 200 "inweb/Chapter 4/Programming Languages.w" ; Regexp__dispose_of(&mr); } #line 342 "inweb/Chapter 4/Programming Languages.w" #line 344 "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; return block; } #line 386 "inweb/Chapter 4/Programming Languages.w" #line 388 "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->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->set_to_colour = NOT_A_COLOUR; rule->set_prefix_to_colour = NOT_A_COLOUR; rule->execute_block = NULL; rule->debug = FALSE; return rule; } #line 405 "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 416 "inweb/Chapter 4/Programming Languages.w" if (Regexp__match(&mr, premiss, L"keyword of (%c+)")) { PRINT("Keyw of %S\n", mr.exp[0]); 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); } 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); } 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); } else if (Regexp__match(&mr, premiss, L"suffix (%c+)")) { rule->match_prefix = UNSPACED_RULE_SUFFIX; rule->match_text = Languages__text(mr.exp[0], tfp); } 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); } 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); } else if (Regexp__match(&mr, premiss, L"colou*r (%c+)")) { rule->match_colour = Languages__colour(mr.exp[0], tfp); } else if (Str__len(premiss) > 0) { rule->match_text = Languages__text(premiss, tfp); } } #line 410 "inweb/Chapter 4/Programming Languages.w" ; { #line 446 "inweb/Chapter 4/Programming Languages.w" if (Str__eq(action, TL_IS_250)) { 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_251)) { rule->debug = TRUE; } else { Errors__in_text_file("action after '=>' illegible", tfp); } } #line 411 "inweb/Chapter 4/Programming Languages.w" ; Regexp__dispose_of(&mr); } #line 474 "inweb/Chapter 4/Programming Languages.w" reserved_word *Languages__reserved(programming_language *pl, text_stream *W, int 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 = C; ADD_TO_LINKED_LIST(rw, reserved_word, pl->reserved_words); Analyser__mark_reserved_word(&(pl->built_in_keywords), rw->word, C); return rw; } #line 511 "inweb/Chapter 4/Programming Languages.w" int 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_252)) return STRING_COLOUR; else if (Str__eq(T, TL_IS_253)) return FUNCTION_COLOUR; else if (Str__eq(T, TL_IS_254)) return DEFINITION_COLOUR; else if (Str__eq(T, TL_IS_255)) return RESERVED_COLOUR; else if (Str__eq(T, TL_IS_256)) return ELEMENT_COLOUR; else if (Str__eq(T, TL_IS_257)) return IDENTIFIER_COLOUR; else if (Str__eq(T, TL_IS_258)) return CHAR_LITERAL_COLOUR; else if (Str__eq(T, TL_IS_259)) return CONSTANT_COLOUR; else if (Str__eq(T, TL_IS_260)) return PLAIN_COLOUR; else if (Str__eq(T, TL_IS_261)) return EXTRACT_COLOUR; else if (Str__eq(T, TL_IS_262)) return COMMENT_COLOUR; else { Errors__in_text_file("no such !colour", tfp); return PLAIN_COLOUR; } } #line 536 "inweb/Chapter 4/Programming Languages.w" int Languages__boolean(text_stream *T, text_file_position *tfp) { if (Str__eq(T, TL_IS_263)) return TRUE; else if (Str__eq(T, TL_IS_264)) return FALSE; else { Errors__in_text_file("must be true or false", tfp); return FALSE; } } #line 550 "inweb/Chapter 4/Programming Languages.w" text_stream *Languages__text(text_stream *T, text_file_position *tfp) { text_stream *V = Str__new(); if (Str__len(T) > 0) { int bareword = TRUE, 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 == '\\') && (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 { PUT_TO(V, c); } } } return V; } #line 38 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(FURTHER_PARSING_PAR_MTID, programming_language *pl, web *W) void LanguageMethods__further_parsing(web *W, programming_language *pl) { VMETHOD_CALL(pl, FURTHER_PARSING_PAR_MTID, W); } #line 49 "inweb/Chapter 4/Language Methods.w" #line 51 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(SUBCATEGORISE_LINE_PAR_MTID, programming_language *pl, source_line *L) void LanguageMethods__subcategorise_line(programming_language *pl, source_line *L) { VMETHOD_CALL(pl, SUBCATEGORISE_LINE_PAR_MTID, L); } #line 62 "inweb/Chapter 4/Language Methods.w" #line 64 "inweb/Chapter 4/Language Methods.w" IMETHOD_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; IMETHOD_CALL(rv, pl, PARSE_COMMENT_TAN_MTID, line, before, within); return rv; } #line 82 "inweb/Chapter 4/Language Methods.w" #line 84 "inweb/Chapter 4/Language Methods.w" VMETHOD_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) { VMETHOD_CALL(pl, SHEBANG_TAN_MTID, OUT, W, target); } #line 93 "inweb/Chapter 4/Language Methods.w" #line 95 "inweb/Chapter 4/Language Methods.w" IMETHOD_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; IMETHOD_CALLV(rv, pl, SUPPRESS_DISCLAIMER_TAN_MTID); if (rv == FALSE) LanguageMethods__comment(OUT, pl, TL_IS_265); } #line 107 "inweb/Chapter 4/Language Methods.w" #line 109 "inweb/Chapter 4/Language Methods.w" VMETHOD_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) { VMETHOD_CALL(pl, ADDITIONAL_EARLY_MATTER_TAN_MTID, OUT, W, target); } #line 123 "inweb/Chapter 4/Language Methods.w" #line 125 "inweb/Chapter 4/Language Methods.w" IMETHOD_TYPE(START_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *term, text_stream *start, section *S, source_line *L) IMETHOD_TYPE(PROLONG_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *more, section *S, source_line *L) IMETHOD_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; IMETHOD_CALL(rv, pl, START_DEFN_TAN_MTID, OUT, term, start, S, L); if (rv == FALSE) Main__error_in_web(TL_IS_266, L); } void LanguageMethods__prolong_definition(OUTPUT_STREAM, programming_language *pl, text_stream *more, section *S, source_line *L) { int rv = FALSE; IMETHOD_CALL(rv, pl, PROLONG_DEFN_TAN_MTID, OUT, more, S, L); if (rv == FALSE) Main__error_in_web(TL_IS_267, L); } void LanguageMethods__end_definition(OUTPUT_STREAM, programming_language *pl, section *S, source_line *L) { int rv = FALSE; IMETHOD_CALL(rv, pl, END_DEFN_TAN_MTID, OUT, S, L); } #line 155 "inweb/Chapter 4/Language Methods.w" #line 157 "inweb/Chapter 4/Language Methods.w" IMETHOD_TYPE(ADDITIONAL_PREDECLARATIONS_TAN_MTID, programming_language *pl, text_stream *OUT, web *W) void LanguageMethods__additional_predeclarations(OUTPUT_STREAM, programming_language *pl, web *W) { VMETHOD_CALL(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, OUT, W); } #line 168 "inweb/Chapter 4/Language Methods.w" #line 170 "inweb/Chapter 4/Language Methods.w" IMETHOD_TYPE(SUPPRESS_EXPANSION_TAN_MTID, programming_language *pl, text_stream *material) int LanguageMethods__allow_expansion(programming_language *pl, text_stream *material) { int rv = FALSE; IMETHOD_CALL(rv, pl, SUPPRESS_EXPANSION_TAN_MTID, material); return (rv)?FALSE:TRUE; } #line 182 "inweb/Chapter 4/Language Methods.w" #line 184 "inweb/Chapter 4/Language Methods.w" IMETHOD_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; IMETHOD_CALL(rv, pl, TANGLE_COMMAND_TAN_MTID, OUT, data); return rv; } #line 199 "inweb/Chapter 4/Language Methods.w" #line 201 "inweb/Chapter 4/Language Methods.w" IMETHOD_TYPE(WILL_TANGLE_EXTRA_LINE_TAN_MTID, programming_language *pl, source_line *L) VMETHOD_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; IMETHOD_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) { VMETHOD_CALL(pl, TANGLE_EXTRA_LINE_TAN_MTID, OUT, L); } #line 218 "inweb/Chapter 4/Language Methods.w" #line 220 "inweb/Chapter 4/Language Methods.w" VMETHOD_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) { VMETHOD_CALL(pl, INSERT_LINE_MARKER_TAN_MTID, OUT, L); } #line 231 "inweb/Chapter 4/Language Methods.w" #line 233 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(BEFORE_MACRO_EXPANSION_TAN_MTID, programming_language *pl, text_stream *OUT, para_macro *pmac) VMETHOD_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) { VMETHOD_CALL(pl, BEFORE_MACRO_EXPANSION_TAN_MTID, OUT, pmac); } void LanguageMethods__after_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) { VMETHOD_CALL(pl, AFTER_MACRO_EXPANSION_TAN_MTID, OUT, pmac); } #line 248 "inweb/Chapter 4/Language Methods.w" #line 250 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(OPEN_IFDEF_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) VMETHOD_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) { VMETHOD_CALL(pl, OPEN_IFDEF_TAN_MTID, OUT, symbol, sense); } void LanguageMethods__close_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) { VMETHOD_CALL(pl, CLOSE_IFDEF_TAN_MTID, OUT, symbol, sense); } #line 262 "inweb/Chapter 4/Language Methods.w" #line 264 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(COMMENT_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *comm) void LanguageMethods__comment(OUTPUT_STREAM, programming_language *pl, text_stream *comm) { VMETHOD_CALL(pl, COMMENT_TAN_MTID, OUT, comm); } #line 274 "inweb/Chapter 4/Language Methods.w" #line 276 "inweb/Chapter 4/Language Methods.w" IMETHOD_TYPE(TANGLE_CODE_UNUSUALLY_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *original) void LanguageMethods__tangle_code(OUTPUT_STREAM, programming_language *pl, text_stream *original) { int rv = FALSE; IMETHOD_CALL(rv, pl, TANGLE_CODE_UNUSUALLY_TAN_MTID, OUT, original); if (rv == FALSE) WRITE("%S", original); } #line 286 "inweb/Chapter 4/Language Methods.w" #line 288 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(GNABEHS_TAN_MTID, programming_language *pl, text_stream *OUT, web *W) void LanguageMethods__gnabehs(OUTPUT_STREAM, programming_language *pl, web *W) { VMETHOD_CALL(pl, GNABEHS_TAN_MTID, OUT, W); } #line 298 "inweb/Chapter 4/Language Methods.w" #line 300 "inweb/Chapter 4/Language Methods.w" VMETHOD_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) { VMETHOD_CALL(pl, ADDITIONAL_TANGLING_TAN_MTID, W, target); } #line 310 "inweb/Chapter 4/Language Methods.w" #line 312 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(BEGIN_WEAVE_WEA_MTID, programming_language *pl, section *S, weave_target *wv) void LanguageMethods__begin_weave(section *S, weave_target *wv) { VMETHOD_CALL(S->sect_language, BEGIN_WEAVE_WEA_MTID, S, wv); } #line 320 "inweb/Chapter 4/Language Methods.w" #line 322 "inweb/Chapter 4/Language Methods.w" IMETHOD_TYPE(SKIP_IN_WEAVING_WEA_MTID, programming_language *pl, weave_target *wv, source_line *L) int LanguageMethods__skip_in_weaving(programming_language *pl, weave_target *wv, source_line *L) { int rv = FALSE; IMETHOD_CALL(rv, pl, SKIP_IN_WEAVING_WEA_MTID, wv, L); return rv; } #line 335 "inweb/Chapter 4/Language Methods.w" #line 337 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(RESET_SYNTAX_COLOURING_WEA_MTID, programming_language *pl) void LanguageMethods__reset_syntax_colouring(programming_language *pl) { VMETHOD_CALLV(pl, RESET_SYNTAX_COLOURING_WEA_MTID); } #line 345 "inweb/Chapter 4/Language Methods.w" #line 347 "inweb/Chapter 4/Language Methods.w" int colouring_state = PLAIN_COLOUR; IMETHOD_TYPE(SYNTAX_COLOUR_WEA_MTID, programming_language *pl, text_stream *OUT, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) int LanguageMethods__syntax_colour(OUTPUT_STREAM, programming_language *pl, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) { Str__copy(colouring, matter); 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; if (colour_as) IMETHOD_CALL(rv, colour_as, SYNTAX_COLOUR_WEA_MTID, OUT, wv, W, C, S, L, matter, colouring); return rv; } #line 368 "inweb/Chapter 4/Language Methods.w" #line 370 "inweb/Chapter 4/Language Methods.w" IMETHOD_TYPE(WEAVE_CODE_LINE_WEA_MTID, programming_language *pl, text_stream *OUT, weave_target *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_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) { int rv = FALSE; IMETHOD_CALL(rv, pl, WEAVE_CODE_LINE_WEA_MTID, OUT, wv, W, C, S, L, matter, concluding_comment); return rv; } #line 382 "inweb/Chapter 4/Language Methods.w" #line 384 "inweb/Chapter 4/Language Methods.w" VMETHOD_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) VMETHOD_CALL(pl, NOTIFY_NEW_TAG_WEA_MTID, tag); } #line 400 "inweb/Chapter 4/Language Methods.w" #line 402 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(CATALOGUE_ANA_MTID, programming_language *pl, section *S, int functions_too) void LanguageMethods__catalogue(programming_language *pl, section *S, int functions_too) { VMETHOD_CALL(pl, CATALOGUE_ANA_MTID, S, functions_too); } #line 415 "inweb/Chapter 4/Language Methods.w" #line 417 "inweb/Chapter 4/Language Methods.w" VMETHOD_TYPE(EARLY_PREWEAVE_ANALYSIS_ANA_MTID, programming_language *pl, web *W) VMETHOD_TYPE(LATE_PREWEAVE_ANALYSIS_ANA_MTID, programming_language *pl, web *W) void LanguageMethods__early_preweave_analysis(programming_language *pl, web *W) { VMETHOD_CALL(pl, EARLY_PREWEAVE_ANALYSIS_ANA_MTID, W); } void LanguageMethods__late_preweave_analysis(programming_language *pl, web *W) { VMETHOD_CALL(pl, LATE_PREWEAVE_ANALYSIS_ANA_MTID, W); } #line 430 "inweb/Chapter 4/Language Methods.w" #line 432 "inweb/Chapter 4/Language Methods.w" IMETHOD_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; IMETHOD_CALL(rv, pl, SHARE_ELEMENT_ANA_MTID, element_name); return rv; } #line 442 "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_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 54 "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 78 "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_code(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_code(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); } } 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 = FALSE, non_white_space = FALSE, c_position = -1, c_end = -1; for (int i=0; imultiline_comment_close)) { c_mode = 0; c_end = i; i += Str__len(pl->multiline_comment_close) - 1; } } else { if ((c_mode == 0) && (!(Characters__is_whitespace(c)))) non_white_space = TRUE; if ((c == Str__get_first_char(pl->string_literal_escape)) && (q_mode == 2)) i += 1; if ((c == Str__get_first_char(pl->character_literal_escape)) && (q_mode == 1)) i += 1; if (c == Str__get_first_char(pl->string_literal)) { if (q_mode == 0) q_mode = 2; else if (q_mode == 2) q_mode = 0; } if (c == Str__get_first_char(pl->character_literal)) { if (q_mode == 0) q_mode = 1; else if (q_mode == 1) q_mode = 0; } if (ACMESupport__text_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; } if (ACMESupport__text_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; } if (ACMESupport__text_at(line, i, pl->whole_line_comment)) { int material_exists = FALSE; for (int j=0; jwhole_line_comment) - 1; } } } } if ((c_position >= 0) && (non_white_space == FALSE)) { Str__clear(part_before_comment); 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 222 "inweb/Chapter 4/ACME Support.w" int ACMESupport__suppress_disclaimer(programming_language *pl) { return pl->suppress_disclaimer; } #line 229 "inweb/Chapter 4/ACME Support.w" void ACMESupport__begin_weave(programming_language *pl, section *S, weave_target *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 238 "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, text_stream *OUT, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) { 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, OUT, ht, matter, colouring, FALSE); } #line 16 "inweb/Chapter 4/The Painter.w" void Painter__reset_syntax_colouring(programming_language *pl) { colouring_state = PLAIN_COLOUR; } #line 36 "inweb/Chapter 4/The Painter.w" int Painter__syntax_colour(programming_language *pl, text_stream *OUT, 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++) { int skip = 0, 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 = CHAR_LITERAL_COLOUR; break; } if (Painter__identifier_at(pl, matter, colouring, i)) one_off = IDENTIFIER_COLOUR; break; } case CHAR_LITERAL_COLOUR: { wchar_t c = Str__get_at(matter, i); if (c == squote) will_be = PLAIN_COLOUR; if (c == squote_escape) skip = 1; break; } case STRING_COLOUR: { wchar_t c = Str__get_at(matter, i); if (c == dquote) will_be = PLAIN_COLOUR; if (c == dquote_escape) skip = 1; break; } } if (one_off >= 0) Str__put_at(colouring, i, (char) one_off); else Str__put_at(colouring, i, (char) colouring_state); if (will_be >= 0) colouring_state = (char) will_be; if (skip > 0) i += skip; } } #line 58 "inweb/Chapter 4/The Painter.w" ; { #line 105 "inweb/Chapter 4/The Painter.w" int base = -1, dec_possible = TRUE; for (int i=from; i <= to; i++) { if ((Str__get_at(colouring, i) == PLAIN_COLOUR) || (Str__get_at(colouring, i) == IDENTIFIER_COLOUR)) { wchar_t c = Str__get_at(matter, i); if (ACMESupport__text_at(matter, i, pl->binary_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 (ACMESupport__text_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 (ACMESupport__text_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 ((ACMESupport__text_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 59 "inweb/Chapter 4/The Painter.w" ; { #line 190 "inweb/Chapter 4/The Painter.w" if (pl->program) Painter__execute(HT, pl->program, matter, colouring, from, to); } #line 60 "inweb/Chapter 4/The Painter.w" ; } #line 166 "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 199 "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) { 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); break; case CHARACTERS_CRULE_RUN: for (int i=from; i<=to; i++) Painter__execute_rule(HT, rule, matter, colouring, i, i); break; case INSTANCES_CRULE_RUN: { int L = Str__len(block->run_instance) - 1; if (L >= 0) for (int i=from; i<=to - L; i++) if (ACMESupport__text_at(matter, i, block->run_instance)) { Painter__execute_rule(HT, rule, matter, colouring, i, i+L); i += L; } break; } default: { int ident_from = -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 != CHAR_LITERAL_COLOUR)))) { if (ident_from == -1) ident_from = i; } else { if (ident_from >= 0) Painter__execute_rule(HT, rule, matter, colouring, ident_from, i-1); ident_from = -1; } } if (ident_from >= 0) Painter__execute_rule(HT, rule, matter, colouring, ident_from, to); break; } } } DISCARD_TEXT(colouring_at_start); } #line 250 "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) { if (Painter__satisfies(HT, rule, matter, colouring, from, to)) Painter__follow(HT, rule, matter, colouring, from, to); } #line 267 "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) { 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 (ACMESupport__text_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 = from + Str__len(rule->match_text); 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 (ACMESupport__text_at(matter, pos, rule->match_text) == FALSE) return FALSE; rule->fix_position = pos; } else { if (Str__ne(matter, rule->match_text)) 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, 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 315 "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); else if (rule->debug) { #line 331 "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 319 "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 9 "inweb/Chapter 4/C-Like Languages.w" void CLike__make_c_like(programming_language *pl) { METHOD_ADD(pl, FURTHER_PARSING_PAR_MTID, CLike__further_parsing); 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); METHOD_ADD(pl, CATALOGUE_ANA_MTID, CLike__catalogue); METHOD_ADD(pl, EARLY_PREWEAVE_ANALYSIS_ANA_MTID, CLike__analyse_code); METHOD_ADD(pl, LATE_PREWEAVE_ANALYSIS_ANA_MTID, CLike__post_analysis); } #line 37 "inweb/Chapter 4/C-Like Languages.w" int cc_sp = 0; source_line *cc_stack[MAX_CONDITIONAL_COMPILATION_STACK]; c_structure *first_cst_alphabetically = NULL; void CLike__further_parsing(programming_language *self, web *W) { { #line 97 "inweb/Chapter 4/C-Like Languages.w" c_structure *current_str = NULL; chapter *C; section *S; LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) { match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, L->text, L"typedef struct (%i+) %c*{%c*")) { { #line 134 "inweb/Chapter 4/C-Like Languages.w" c_structure *str = CREATE(c_structure); { #line 142 "inweb/Chapter 4/C-Like Languages.w" str->structure_name = Str__duplicate(mr.exp[0]); str->typedef_begins = L; str->tangled = FALSE; str->typedef_ends = NULL; str->incorporates = NEW_LINKED_LIST(c_structure); str->elements = NEW_LINKED_LIST(structure_element); } #line 135 "inweb/Chapter 4/C-Like Languages.w" ; Analyser__mark_reserved_word_for_section(L->owning_section, str->structure_name, RESERVED_COLOUR); { #line 150 "inweb/Chapter 4/C-Like Languages.w" ADD_TO_LINKED_LIST(str, c_structure, W->c_structures); ADD_TO_LINKED_LIST(str, c_structure, L->owning_paragraph->structures); } #line 137 "inweb/Chapter 4/C-Like Languages.w" ; { #line 154 "inweb/Chapter 4/C-Like Languages.w" str->next_cst_alphabetically = NULL; if (first_cst_alphabetically == NULL) first_cst_alphabetically = str; else { int placed = FALSE; c_structure *last = NULL; for (c_structure *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 138 "inweb/Chapter 4/C-Like Languages.w" ; current_str = str; } #line 104 "inweb/Chapter 4/C-Like Languages.w" ; Tags__add_by_name(L->owning_paragraph, TL_IS_271); } 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 185 "inweb/Chapter 4/C-Like Languages.w" TEMPORARY_TEXT(p); Str__copy(p, L->text); Str__trim_white_space(p); { #line 207 "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 188 "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 225 "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 191 "inweb/Chapter 4/C-Like Languages.w" ; { #line 231 "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 192 "inweb/Chapter 4/C-Like Languages.w" ; if (Str__in_range(pos)) { match_results mr = Regexp__create_mr(); TEMPORARY_TEXT(elname); { #line 238 "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 196 "inweb/Chapter 4/C-Like Languages.w" ; { #line 259 "inweb/Chapter 4/C-Like Languages.w" Analyser__mark_reserved_word_for_section(L->owning_section, 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(W->main_language, elname)) elt->allow_sharing = TRUE; ADD_TO_LINKED_LIST(elt, structure_element, current_str->elements); } #line 197 "inweb/Chapter 4/C-Like Languages.w" ; DISCARD_TEXT(elname); Regexp__dispose_of(&mr); } } DISCARD_TEXT(p); } #line 110 "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 42 "inweb/Chapter 4/C-Like Languages.w" ; { #line 281 "inweb/Chapter 4/C-Like Languages.w" c_structure *current_str; LOOP_OVER(current_str, c_structure) { for (source_line *L = current_str->typedef_begins; ((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 294 "inweb/Chapter 4/C-Like Languages.w" text_stream *used_structure = mr.exp[0]; c_structure *str; LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures) if ((str != current_str) && (Str__eq(used_structure, str->structure_name))) ADD_TO_LINKED_LIST(str, c_structure, current_str->incorporates); } #line 288 "inweb/Chapter 4/C-Like Languages.w" ; Regexp__dispose_of(&mr); } } } #line 43 "inweb/Chapter 4/C-Like Languages.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 59 "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_269, 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_270, L); else cc_sp--; } } #line 51 "inweb/Chapter 4/C-Like Languages.w" ; { #line 312 "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 339 "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 316 "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 356 "inweb/Chapter 4/C-Like Languages.w" { #line 376 "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 356 "inweb/Chapter 4/C-Like Languages.w" ; Analyser__mark_reserved_word_for_section(L->owning_section, fname, FUNCTION_COLOUR); function *fn = CREATE(function); { #line 413 "inweb/Chapter 4/C-Like Languages.w" fn->function_name = Str__duplicate(fname); fn->function_arguments = Str__duplicate(arguments); fn->function_type = Str__new(); WRITE_TO(fn->function_type, "%S%S %S", qualifiers, ftype, asts); fn->within_namespace = FALSE; fn->called_from_other_sections = FALSE; fn->call_freely = FALSE; if (Str__eq_wide_string(fn->function_name, L"isdigit")) fn->call_freely = TRUE; fn->function_header_at = L; fn->no_conditionals = cc_sp; for (int i=0; iwithin_conditionals[i] = cc_stack[i]; } #line 359 "inweb/Chapter 4/C-Like Languages.w" ; { #line 427 "inweb/Chapter 4/C-Like Languages.w" paragraph *P = L->owning_paragraph; if (P) ADD_TO_LINKED_LIST(fn, function, P->functions); L->function_defined = fn; } #line 360 "inweb/Chapter 4/C-Like Languages.w" ; if (W->main_language->supports_namespaces) { #line 432 "inweb/Chapter 4/C-Like Languages.w" text_stream *declared_namespace = NULL; 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(S->sect_namespace, L"Main::"))) declared_namespace = TL_IS_272; if ((Str__ne(declared_namespace, S->sect_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, S->sect_namespace); else if (Str__len(S->sect_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, S->sect_namespace); Main__error_in_web(err_mess, L); DISCARD_TEXT(err_mess); } Regexp__dispose_of(&mr); } #line 362 "inweb/Chapter 4/C-Like Languages.w" ; } #line 323 "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 52 "inweb/Chapter 4/C-Like Languages.w" ; } if (cc_sp > 0) Main__error_in_web(TL_IS_268, NULL); } #line 132 "inweb/Chapter 4/C-Like Languages.w" #line 257 "inweb/Chapter 4/C-Like Languages.w" #line 408 "inweb/Chapter 4/C-Like Languages.w" #line 459 "inweb/Chapter 4/C-Like Languages.w" c_structure *CLike__find_structure(web *W, text_stream *name) { c_structure *str; LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures) if (Str__eq(name, str->structure_name)) return str; return NULL; } #line 473 "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 502 "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_code(OUT, L->text, S, L); WRITE("\n"); Tags__close_ifdefs(OUT, L->owning_paragraph); } } #line 521 "inweb/Chapter 4/C-Like Languages.w" void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) { { #line 550 "inweb/Chapter 4/C-Like Languages.w" c_structure *str; LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures) str->tangled = FALSE; LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures) CLike__tangle_structure(OUT, self, str); } #line 522 "inweb/Chapter 4/C-Like Languages.w" ; { #line 531 "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_code(OUT, W->main_language, L->text); WRITE("\n"); Tags__close_ifdefs(OUT, L->owning_paragraph); } } #line 523 "inweb/Chapter 4/C-Like Languages.w" ; { #line 592 "inweb/Chapter 4/C-Like Languages.w" chapter *C; section *S; LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) if ((L->function_defined) && (L->owning_paragraph->placed_very_early == FALSE)) { 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_code(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; c_structure *embodied = NULL; LOOP_OVER_LINKED_LIST(embodied, c_structure, str->incorporates) CLike__tangle_structure(OUT, self, embodied); str->tangled = TRUE; Tags__open_ifdefs(OUT, str->typedef_begins->owning_paragraph); LanguageMethods__insert_line_marker(OUT, self, str->typedef_begins); for (source_line *L = str->typedef_begins; 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->typedef_begins->owning_paragraph); } #line 626 "inweb/Chapter 4/C-Like Languages.w" void CLike__catalogue(programming_language *self, section *S, int functions_too) { c_structure *str; LOOP_OVER(str, c_structure) if (str->typedef_begins->owning_section == S) PRINT(" %S ", str->structure_name); if (functions_too) { function *fn; LOOP_OVER(fn, function) if (fn->function_header_at->owning_section == S) PRINT("\n %S", fn->function_name); } } #line 643 "inweb/Chapter 4/C-Like Languages.w" void CLike__analyse_code(programming_language *self, web *W) { function *fn; LOOP_OVER(fn, function) Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section, fn->function_name, TRUE); c_structure *str; structure_element *elt; LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures) 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 665 "inweb/Chapter 4/C-Like Languages.w" void CLike__post_analysis(programming_language *self, web *W) { int check_namespaces = FALSE; if (Str__eq_wide_string(Bibliographic__get_datum(W->md, TL_IS_273), L"On")) check_namespaces = TRUE; function *fn; LOOP_OVER(fn, 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_274, fn->function_header_at); else Main__error_in_web( TL_IS_275, fn->function_header_at); } } } #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_CODE_UNUSUALLY_TAN_MTID, InCSupport__tangle_code); 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, EARLY_PREWEAVE_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)) { { #line 66 "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 79 "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 217 "inweb/Chapter 4/InC Support.w" 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 243 "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 230 "inweb/Chapter 4/InC Support.w" ; { #line 253 "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 288 "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 267 "inweb/Chapter 4/InC Support.w" ; DISCARD_TEXT(var_given); DISCARD_TEXT(type_given); } DISCARD_TEXT(to_scan); Regexp__dispose_of(&mr); } #line 231 "inweb/Chapter 4/InC Support.w" ; Regexp__dispose_of(&mr); } } #line 84 "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 69 "inweb/Chapter 4/InC Support.w" ; if (form != NOT_A_NONTERMINAL) { #line 121 "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 135 "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 127 "inweb/Chapter 4/InC Support.w" ; { #line 145 "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 128 "inweb/Chapter 4/InC Support.w" ; { #line 160 "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 129 "inweb/Chapter 4/InC Support.w" ; { #line 177 "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 131 "inweb/Chapter 4/InC Support.w" ; { #line 200 "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 132 "inweb/Chapter 4/InC Support.w" ; } #line 70 "inweb/Chapter 4/InC Support.w" ; DISCARD_TEXT(pntname); DISCARD_TEXT(header); } #line 45 "inweb/Chapter 4/InC Support.w" ; { #line 304 "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 315 "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 346 "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 323 "inweb/Chapter 4/InC Support.w" ; DISCARD_TEXT(lit); } #line 311 "inweb/Chapter 4/InC Support.w" ; } } #line 46 "inweb/Chapter 4/InC Support.w" } } #line 117 "inweb/Chapter 4/InC Support.w" #line 286 "inweb/Chapter 4/InC Support.w" #line 336 "inweb/Chapter 4/InC Support.w" #line 367 "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 391 "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 415 "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 444 "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 478 "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 499 "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 556 "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 574 "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) { WRITE("\t\tcase %d: ", c); { #line 611 "inweb/Chapter 4/InC Support.w" match_results mr = Regexp__create_mr(); if (!Regexp__match(&mr, formula, L"@<%c*")) { if (pnt->takes_pointer_result) WRITE("*XP = "); else WRITE("*X = "); } 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) == ']')) { 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)); } } Tangler__tangle_code(OUT, expanded, AL->owning_section, AL); DISCARD_TEXT(expanded); Regexp__dispose_of(&mr); } #line 582 "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 562 "inweb/Chapter 4/InC Support.w" else { #line 571 "inweb/Chapter 4/InC Support.w" WRITE("\t*X = R[0];\n"); } #line 563 "inweb/Chapter 4/InC Support.w" ; WRITE("\treturn TRUE;\n"); } #line 507 "inweb/Chapter 4/InC Support.w" ; WRITE("}\n"); } } #line 636 "inweb/Chapter 4/InC Support.w" void InCSupport__tangle_code(programming_language *self, text_stream *OUT, text_stream *original) { int fcall_pos = -1; for (int i = 0; i < Str__len(original); i++) { { #line 678 "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 639 "inweb/Chapter 4/InC Support.w" ; if (Str__get_at(original, i) == '<') { if (Str__get_at(original, i+1) == '<') { { #line 690 "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 642 "inweb/Chapter 4/InC Support.w" ; } else { { #line 722 "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 644 "inweb/Chapter 4/InC Support.w" ; } } if (i == fcall_pos) { fcall_pos = -1; WRITE(", NULL, NULL"); } PUT(Str__get_at(original, i)); } } #line 756 "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 770 "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_280; if (Str__eq_wide_string(name, L"rp")) return TL_IS_281; nonterminal_variable *ntv; LOOP_OVER(ntv, nonterminal_variable) if (Str__eq(ntv->ntv_name, name)) return ntv->ntv_identifier; return NULL; } #line 791 "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_folder(P, TL_IS_282); 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_283)) WRITE("language %S\n", Bibliographic__get_datum(W->md, TL_IS_284)); { #line 826 "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 808 "inweb/Chapter 4/InC Support.w" ; STREAM_CLOSE(OUT); } } #line 853 "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->sect_range); int said_something = FALSE; { #line 900 "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->sect_range); } WRITE("\n\n"); } } #line 864 "inweb/Chapter 4/InC Support.w" ; { #line 875 "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->sect_range); } WRITE("\n\n"); } } #line 865 "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 929 "inweb/Chapter 4/InC Support.w" int skipping_internal = FALSE, preform_production_count = 0; int InCSupport__skip_in_weaving(programming_language *self, weave_target *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 946 "inweb/Chapter 4/InC Support.w" int InCSupport__weave_code_line(programming_language *self, text_stream *OUT, weave_target *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 960 "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 967 "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 17 "inweb/Chapter 5/Weave Formats.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); ENABLE_METHOD_CALLS(wf); 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/Weave Formats.w" text_stream *Formats__file_extension(weave_format *wf) { return wf->woven_extension; } #line 48 "inweb/Chapter 5/Weave Formats.w" void Formats__create_weave_formats(void) { TeX__create(); PlainText__create(); HTMLFormat__create(); } #line 67 "inweb/Chapter 5/Weave Formats.w" #line 69 "inweb/Chapter 5/Weave Formats.w" IMETHOD_TYPE(BEGIN_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern) VMETHOD_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; IMETHOD_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) { VMETHOD_CALL(pattern->pattern_format, END_WEAVING_FOR_MTID, W, pattern); } #line 89 "inweb/Chapter 5/Weave Formats.w" #line 91 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(TOP_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *comment) void Formats__top(OUTPUT_STREAM, weave_target *wv, text_stream *comment) { weave_format *wf = wv->format; VMETHOD_CALL(wf, TOP_FOR_MTID, OUT, wv, comment); } #line 106 "inweb/Chapter 5/Weave Formats.w" #line 108 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(TOC_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) void Formats__toc(OUTPUT_STREAM, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) { weave_format *wf = wv->format; VMETHOD_CALL(wf, TOC_FOR_MTID, OUT, wv, stage, text1, text2, P); } #line 121 "inweb/Chapter 5/Weave Formats.w" #line 123 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(CHAPTER_TP_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, chapter *C) void Formats__chapter_title_page(OUTPUT_STREAM, weave_target *wv, chapter *C) { weave_format *wf = wv->format; VMETHOD_CALL(wf, CHAPTER_TP_FOR_MTID, OUT, wv, C); } #line 141 "inweb/Chapter 5/Weave Formats.w" #line 143 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(SUBHEADING_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int level, text_stream *heading, text_stream *addendum) void Formats__subheading(OUTPUT_STREAM, weave_target *wv, int level, text_stream *heading, text_stream *addendum) { weave_format *wf = wv->format; VMETHOD_CALL(wf, SUBHEADING_FOR_MTID, OUT, wv, level, heading, addendum); } #line 165 "inweb/Chapter 5/Weave Formats.w" #line 167 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(PARAGRAPH_HEADING_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) void Formats__paragraph_heading(OUTPUT_STREAM, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) { weave_format *wf = wv->format; VMETHOD_CALL(wf, PARAGRAPH_HEADING_FOR_MTID, OUT, wv, TeX_macro, S, P, heading_text, chaptermark, sectionmark, weight); } #line 183 "inweb/Chapter 5/Weave Formats.w" #line 185 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(SOURCE_CODE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) void Formats__source_code(OUTPUT_STREAM, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) { weave_format *wf = wv->format; VMETHOD_CALL(wf, SOURCE_CODE_FOR_MTID, OUT, wv, tab_stops_of_indentation, prefatory, matter, colouring, concluding_comment, starts, finishes, code_mode); } #line 203 "inweb/Chapter 5/Weave Formats.w" #line 205 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(INLINE_CODE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int pre) void Formats__source_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) { weave_format *wf = wv->format; VMETHOD_CALL(wf, INLINE_CODE_FOR_MTID, OUT, wv, TRUE); TEMPORARY_TEXT(colouring); for (int i=0; i< Str__len(fragment); i++) PUT_TO(colouring, EXTRACT_COLOUR); Formats__source_code(OUT, wv, 0, TL_IS_285, fragment, colouring, TL_IS_286, FALSE, FALSE, TRUE); DISCARD_TEXT(colouring); VMETHOD_CALL(wf, INLINE_CODE_FOR_MTID, OUT, wv, FALSE); } #line 220 "inweb/Chapter 5/Weave Formats.w" #line 222 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(DISPLAY_LINE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *from) void Formats__display_line(OUTPUT_STREAM, weave_target *wv, text_stream *from) { weave_format *wf = wv->format; VMETHOD_CALL(wf, DISPLAY_LINE_FOR_MTID, OUT, wv, from); } #line 241 "inweb/Chapter 5/Weave Formats.w" #line 243 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(ITEM_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int depth, text_stream *label) void Formats__item(OUTPUT_STREAM, weave_target *wv, int depth, text_stream *label) { weave_format *wf = wv->format; VMETHOD_CALL(wf, ITEM_FOR_MTID, OUT, wv, depth, label); } #line 254 "inweb/Chapter 5/Weave Formats.w" #line 256 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(BAR_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv) void Formats__bar(OUTPUT_STREAM, weave_target *wv) { weave_format *wf = wv->format; VMETHOD_CALL(wf, BAR_FOR_MTID, OUT, wv); } #line 267 "inweb/Chapter 5/Weave Formats.w" #line 269 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(FIGURE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) void Formats__figure(OUTPUT_STREAM, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) { weave_format *wf = wv->format; VMETHOD_CALL(wf, FIGURE_FOR_MTID, OUT, wv, figname, w, h, pl); } #line 282 "inweb/Chapter 5/Weave Formats.w" #line 284 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(PARA_MACRO_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) void Formats__para_macro(OUTPUT_STREAM, weave_target *wv, para_macro *pmac, int defn) { weave_format *wf = wv->format; VMETHOD_CALL(wf, PARA_MACRO_FOR_MTID, OUT, wv, pmac, defn); } #line 296 "inweb/Chapter 5/Weave Formats.w" #line 298 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(PAGEBREAK_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv) void Formats__pagebreak(OUTPUT_STREAM, weave_target *wv) { weave_format *wf = wv->format; VMETHOD_CALL(wf, PAGEBREAK_FOR_MTID, OUT, wv); } #line 310 "inweb/Chapter 5/Weave Formats.w" #line 312 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(BLANK_LINE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int in_comment) void Formats__blank_line(OUTPUT_STREAM, weave_target *wv, int in_comment) { weave_format *wf = wv->format; VMETHOD_CALL(wf, BLANK_LINE_FOR_MTID, OUT, wv, in_comment); } #line 325 "inweb/Chapter 5/Weave Formats.w" #line 327 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(AFTER_DEFINITIONS_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv) void Formats__after_definitions(OUTPUT_STREAM, weave_target *wv) { weave_format *wf = wv->format; VMETHOD_CALL(wf, AFTER_DEFINITIONS_FOR_MTID, OUT, wv); } #line 340 "inweb/Chapter 5/Weave Formats.w" #line 342 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(CHANGE_MATERIAL_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int old_material, int new_material, int content) void Formats__change_material(OUTPUT_STREAM, weave_target *wv, int old_material, int new_material, int content) { weave_format *wf = wv->format; VMETHOD_CALL(wf, CHANGE_MATERIAL_FOR_MTID, OUT, wv, old_material, new_material, content); } #line 356 "inweb/Chapter 5/Weave Formats.w" #line 358 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(CHANGE_COLOUR_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int col, int in_code) void Formats__change_colour(OUTPUT_STREAM, weave_target *wv, int col, int in_code) { weave_format *wf = wv->format; VMETHOD_CALL(wf, CHANGE_COLOUR_FOR_MTID, OUT, wv, col, in_code); } #line 371 "inweb/Chapter 5/Weave Formats.w" void Formats__text(OUTPUT_STREAM, weave_target *wv, text_stream *id) { Formats__text_r(OUT, wv, id, FALSE); } void Formats__text_r(OUTPUT_STREAM, weave_target *wv, text_stream *id, int within) { for (int i=0; i < Str__len(id); i++) { if (Str__get_at(id, i) == '\\') i++; else if (Str__get_at(id, i) == '|') { TEMPORARY_TEXT(before); Str__copy(before, id); Str__truncate(before, i); TEMPORARY_TEXT(after); Str__substr(after, Str__at(id, i+1), Str__end(id)); Formats__text_r(OUT, wv, before, within); Formats__text_r(OUT, wv, after, (within)?FALSE:TRUE); DISCARD_TEXT(before); DISCARD_TEXT(after); return; } } if (within) { Formats__source_fragment(OUT, wv, id); } else { Formats__text_fragment(OUT, wv, id); } } #line 405 "inweb/Chapter 5/Weave Formats.w" #line 407 "inweb/Chapter 5/Weave Formats.w" IMETHOD_TYPE(PRESERVE_MATH_MODE_FOR_MTID, weave_format *wf, text_stream *matter, text_stream *id) VMETHOD_TYPE(COMMENTARY_TEXT_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *matter) void Formats__text_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) { weave_format *wf = wv->format; TEMPORARY_TEXT(matter); int rv = FALSE; IMETHOD_CALL(rv, wf, PRESERVE_MATH_MODE_FOR_MTID, matter, fragment); if (rv == FALSE) TeX__remove_math_mode(matter, fragment); else Str__copy(matter, fragment); VMETHOD_CALL(wf, COMMENTARY_TEXT_FOR_MTID, OUT, wv, matter); DISCARD_TEXT(matter); } #line 428 "inweb/Chapter 5/Weave Formats.w" #line 430 "inweb/Chapter 5/Weave Formats.w" IMETHOD_TYPE(PREFORM_DOCUMENT_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) int Formats__preform_document(OUTPUT_STREAM, weave_target *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; IMETHOD_CALL(rv, wf, PREFORM_DOCUMENT_FOR_MTID, OUT, wv, W, C, S, L, matter, concluding_comment); return rv; } #line 448 "inweb/Chapter 5/Weave Formats.w" #line 450 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(ENDNOTE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int end) void Formats__endnote(OUTPUT_STREAM, weave_target *wv, int end) { weave_format *wf = wv->format; VMETHOD_CALL(wf, ENDNOTE_FOR_MTID, OUT, wv, end); } #line 462 "inweb/Chapter 5/Weave Formats.w" #line 464 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(LOCALE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) void Formats__locale(OUTPUT_STREAM, weave_target *wv, paragraph *par1, paragraph *par2) { weave_format *wf = wv->format; VMETHOD_CALL(wf, LOCALE_FOR_MTID, OUT, wv, par1, par2); } #line 475 "inweb/Chapter 5/Weave Formats.w" #line 477 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(TAIL_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) void Formats__tail(OUTPUT_STREAM, weave_target *wv, text_stream *comment, section *S) { weave_format *wf = wv->format; VMETHOD_CALL(wf, TAIL_FOR_MTID, OUT, wv, comment, S); } #line 492 "inweb/Chapter 5/Weave Formats.w" #line 494 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(POST_PROCESS_POS_MTID, weave_format *wf, weave_target *wv, int open_afterwards) void Formats__post_process_weave(weave_target *wv, int open_afterwards) { VMETHOD_CALL(wv->format, POST_PROCESS_POS_MTID, wv, open_afterwards); } #line 503 "inweb/Chapter 5/Weave Formats.w" #line 505 "inweb/Chapter 5/Weave Formats.w" VMETHOD_TYPE(POST_PROCESS_REPORT_POS_MTID, weave_format *wf, weave_target *wv) void Formats__report_on_post_processing(weave_target *wv) { VMETHOD_CALL(wv->format, POST_PROCESS_REPORT_POS_MTID, wv); } #line 515 "inweb/Chapter 5/Weave Formats.w" #line 517 "inweb/Chapter 5/Weave Formats.w" IMETHOD_TYPE(INDEX_PDFS_POS_MTID, weave_format *wf) int Formats__index_pdfs(text_stream *format) { weave_format *wf = Formats__find_by_name(format); if (wf == NULL) return FALSE; int rv = FALSE; IMETHOD_CALLV(rv, wf, INDEX_PDFS_POS_MTID); return rv; } #line 530 "inweb/Chapter 5/Weave Formats.w" #line 532 "inweb/Chapter 5/Weave Formats.w" IMETHOD_TYPE(POST_PROCESS_SUBSTITUTE_POS_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *detail, weave_pattern *pattern) int Formats__substitute_post_processing_data(OUTPUT_STREAM, weave_target *wv, text_stream *detail, weave_pattern *pattern) { int rv = FALSE; IMETHOD_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_287, TL_IS_288); METHOD_ADD(wf, TOP_FOR_MTID, PlainText__top); METHOD_ADD(wf, SUBHEADING_FOR_MTID, PlainText__subheading); METHOD_ADD(wf, TOC_FOR_MTID, PlainText__toc); METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, PlainText__chapter_title_page); METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, PlainText__paragraph_heading); METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, PlainText__source_code); METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, PlainText__display_line); METHOD_ADD(wf, ITEM_FOR_MTID, PlainText__item); METHOD_ADD(wf, BAR_FOR_MTID, PlainText__bar); METHOD_ADD(wf, PARA_MACRO_FOR_MTID, PlainText__para_macro); METHOD_ADD(wf, BLANK_LINE_FOR_MTID, PlainText__blank_line); METHOD_ADD(wf, ENDNOTE_FOR_MTID, PlainText__endnote); METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, PlainText__commentary_text); METHOD_ADD(wf, LOCALE_FOR_MTID, PlainText__locale); METHOD_ADD(wf, TAIL_FOR_MTID, PlainText__tail); } #line 32 "inweb/Chapter 5/Plain Text Format.w" void PlainText__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) { WRITE("[%S]\n", comment); } #line 38 "inweb/Chapter 5/Plain Text Format.w" void PlainText__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) { WRITE("%S:\n", comment); if ((level == 2) && (head)) { Formats__text(OUT, wv, head); WRITE("\n\n"); } } #line 45 "inweb/Chapter 5/Plain Text Format.w" void PlainText__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) { switch (stage) { case 1: WRITE("%S.", text1); break; case 2: WRITE("; "); break; case 3: WRITE("%S %S", text1, text2); break; case 4: WRITE("\n\n"); break; } } #line 56 "inweb/Chapter 5/Plain Text Format.w" void PlainText__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv, chapter *C) { WRITE("%S\n\n", C->md->rubric); section *S; LOOP_OVER_LINKED_LIST(S, section, C->sections) WRITE(" %S: %S\n %S\n", S->sect_range, S->md->sect_title, S->sect_purpose); } #line 66 "inweb/Chapter 5/Plain Text Format.w" void PlainText__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) { if (P) { WRITE("\n"); Formats__locale(OUT, wv, P, NULL); WRITE(". %S ", heading_text); } else { WRITE("%S\n\n", heading_text); } } #line 79 "inweb/Chapter 5/Plain Text Format.w" void PlainText__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) { if (starts) { for (int i=0; i 0) WRITE("%S ", prefatory); } WRITE("%S", matter); if (finishes) { if (Str__len(concluding_comment) > 0) WRITE("[%S]", concluding_comment); WRITE("\n"); } } #line 96 "inweb/Chapter 5/Plain Text Format.w" void PlainText__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *from) { WRITE(" %S\n", from); } #line 102 "inweb/Chapter 5/Plain Text Format.w" void PlainText__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) { if (depth == 1) WRITE("%-4s ", label); else WRITE("%-8s ", label); } #line 109 "inweb/Chapter 5/Plain Text Format.w" void PlainText__bar(weave_format *self, text_stream *OUT, weave_target *wv) { WRITE("\n----------------------------------------------------------------------\n\n"); } #line 114 "inweb/Chapter 5/Plain Text Format.w" void PlainText__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) { WRITE("<%S (%S)>%s", pmac->macro_name, pmac->defining_paragraph->paragraph_number, (defn)?" =":""); } #line 122 "inweb/Chapter 5/Plain Text Format.w" void PlainText__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) { WRITE("\n"); } #line 128 "inweb/Chapter 5/Plain Text Format.w" void PlainText__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) { WRITE("\n"); } #line 134 "inweb/Chapter 5/Plain Text Format.w" void PlainText__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) { WRITE("%S", id); } #line 140 "inweb/Chapter 5/Plain Text Format.w" void PlainText__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) { WRITE("%S%S", par1->ornament, par1->paragraph_number); if (par2) WRITE("-%S", par2->paragraph_number); } #line 147 "inweb/Chapter 5/Plain Text Format.w" void PlainText__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) { WRITE("[%S]\n", comment); } #line 9 "inweb/Chapter 5/TeX Format.w" void TeX__create(void) { { #line 16 "inweb/Chapter 5/TeX Format.w" weave_format *wf = Formats__create_weave_format(TL_IS_289, TL_IS_290); { #line 40 "inweb/Chapter 5/TeX Format.w" METHOD_ADD(wf, TOP_FOR_MTID, TeX__top); METHOD_ADD(wf, SUBHEADING_FOR_MTID, TeX__subheading); METHOD_ADD(wf, TOC_FOR_MTID, TeX__toc); METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, TeX__chapter_title_page); METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, TeX__paragraph_heading); METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, TeX__source_code); METHOD_ADD(wf, INLINE_CODE_FOR_MTID, TeX__inline_code); METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, TeX__display_line); METHOD_ADD(wf, ITEM_FOR_MTID, TeX__item); METHOD_ADD(wf, BAR_FOR_MTID, TeX__bar); METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro); METHOD_ADD(wf, PAGEBREAK_FOR_MTID, TeX__pagebreak); METHOD_ADD(wf, BLANK_LINE_FOR_MTID, TeX__blank_line); METHOD_ADD(wf, AFTER_DEFINITIONS_FOR_MTID, TeX__after_definitions); METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, TeX__change_material); METHOD_ADD(wf, ENDNOTE_FOR_MTID, TeX__endnote); METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, TeX__commentary_text); METHOD_ADD(wf, LOCALE_FOR_MTID, TeX__locale); METHOD_ADD(wf, TAIL_FOR_MTID, TeX__tail); METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX__preform_document); METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute); METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes); } #line 17 "inweb/Chapter 5/TeX Format.w" ; } #line 10 "inweb/Chapter 5/TeX Format.w" ; { #line 20 "inweb/Chapter 5/TeX Format.w" weave_format *wf = Formats__create_weave_format(TL_IS_291, TL_IS_292); { #line 40 "inweb/Chapter 5/TeX Format.w" METHOD_ADD(wf, TOP_FOR_MTID, TeX__top); METHOD_ADD(wf, SUBHEADING_FOR_MTID, TeX__subheading); METHOD_ADD(wf, TOC_FOR_MTID, TeX__toc); METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, TeX__chapter_title_page); METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, TeX__paragraph_heading); METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, TeX__source_code); METHOD_ADD(wf, INLINE_CODE_FOR_MTID, TeX__inline_code); METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, TeX__display_line); METHOD_ADD(wf, ITEM_FOR_MTID, TeX__item); METHOD_ADD(wf, BAR_FOR_MTID, TeX__bar); METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro); METHOD_ADD(wf, PAGEBREAK_FOR_MTID, TeX__pagebreak); METHOD_ADD(wf, BLANK_LINE_FOR_MTID, TeX__blank_line); METHOD_ADD(wf, AFTER_DEFINITIONS_FOR_MTID, TeX__after_definitions); METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, TeX__change_material); METHOD_ADD(wf, ENDNOTE_FOR_MTID, TeX__endnote); METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, TeX__commentary_text); METHOD_ADD(wf, LOCALE_FOR_MTID, TeX__locale); METHOD_ADD(wf, TAIL_FOR_MTID, TeX__tail); METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX__preform_document); METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute); METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes); } #line 21 "inweb/Chapter 5/TeX Format.w" ; METHOD_ADD(wf, POST_PROCESS_POS_MTID, TeX__post_process_DVI); METHOD_ADD(wf, POST_PROCESS_POS_MTID, TeX__post_process_report); METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute); METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes); } #line 11 "inweb/Chapter 5/TeX Format.w" ; { #line 28 "inweb/Chapter 5/TeX Format.w" weave_format *wf = Formats__create_weave_format(TL_IS_293, TL_IS_294); METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro_PDF_1); { #line 40 "inweb/Chapter 5/TeX Format.w" METHOD_ADD(wf, TOP_FOR_MTID, TeX__top); METHOD_ADD(wf, SUBHEADING_FOR_MTID, TeX__subheading); METHOD_ADD(wf, TOC_FOR_MTID, TeX__toc); METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, TeX__chapter_title_page); METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, TeX__paragraph_heading); METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, TeX__source_code); METHOD_ADD(wf, INLINE_CODE_FOR_MTID, TeX__inline_code); METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, TeX__display_line); METHOD_ADD(wf, ITEM_FOR_MTID, TeX__item); METHOD_ADD(wf, BAR_FOR_MTID, TeX__bar); METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro); METHOD_ADD(wf, PAGEBREAK_FOR_MTID, TeX__pagebreak); METHOD_ADD(wf, BLANK_LINE_FOR_MTID, TeX__blank_line); METHOD_ADD(wf, AFTER_DEFINITIONS_FOR_MTID, TeX__after_definitions); METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, TeX__change_material); METHOD_ADD(wf, ENDNOTE_FOR_MTID, TeX__endnote); METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, TeX__commentary_text); METHOD_ADD(wf, LOCALE_FOR_MTID, TeX__locale); METHOD_ADD(wf, TAIL_FOR_MTID, TeX__tail); METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX__preform_document); METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute); METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes); } #line 30 "inweb/Chapter 5/TeX Format.w" ; METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro_PDF_2); METHOD_ADD(wf, CHANGE_COLOUR_FOR_MTID, TeX__change_colour_PDF); METHOD_ADD(wf, FIGURE_FOR_MTID, TeX__figure_PDF); METHOD_ADD(wf, POST_PROCESS_POS_MTID, TeX__post_process_PDF); METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute); METHOD_ADD(wf, INDEX_PDFS_POS_MTID, TeX__yes); METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes); } #line 12 "inweb/Chapter 5/TeX Format.w" ; } #line 67 "inweb/Chapter 5/TeX Format.w" int TeX__yes(weave_format *self) { return TRUE; } #line 72 "inweb/Chapter 5/TeX Format.w" void TeX__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) { WRITE("%% %S\n", comment); { #line 85 "inweb/Chapter 5/TeX Format.w" filename *Macros = Patterns__obtain_filename(wv->pattern, TL_IS_295); FILE *MACROS = Filenames__fopen(Macros, "r"); if (MACROS == NULL) Errors__fatal_with_file("can't open file of TeX macros", Macros); while (TRUE) { int c = fgetc(MACROS); if (c == EOF) break; PUT(c); } fclose(MACROS); } #line 74 "inweb/Chapter 5/TeX Format.w" ; } #line 96 "inweb/Chapter 5/TeX Format.w" void TeX__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) { switch (level) { case 1: WRITE("\\par\\noindent{\\bf %S}\\mark{%S}\\medskip\n", comment, head); break; case 2: WRITE("\\smallskip\\par\\noindent{\\it %S}\\smallskip\\noindent\n", comment); if (head) Formats__text(OUT, wv, head); break; } } #line 112 "inweb/Chapter 5/TeX Format.w" void TeX__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) { switch (stage) { case 1: if (wv->pattern->show_abbrevs) WRITE("\\medskip\\hrule\\smallskip\\par\\noindent{\\usagefont %S.", text1); else WRITE("\\medskip\\hrule\\smallskip\\par\\noindent{\\usagefont "); break; case 2: WRITE("; "); break; case 3: WRITE("%S~%S", text1, text2); break; case 4: WRITE("}\\par\\medskip\\hrule\\bigskip\n"); break; } } #line 134 "inweb/Chapter 5/TeX Format.w" void TeX__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv, chapter *C) { WRITE("%S\\medskip\n", C->md->rubric); section *S; LOOP_OVER_LINKED_LIST(S, section, C->sections) { WRITE("\\smallskip\\noindent "); if (wv->pattern->number_sections) WRITE("%d. ", S->printed_number); if (wv->pattern->show_abbrevs) WRITE("|%S|: ", S->sect_range); WRITE("{\\it %S}\\qquad\n%S", S->md->sect_title, S->sect_purpose); } } #line 147 "inweb/Chapter 5/TeX Format.w" text_stream *P_literal = NULL; void TeX__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) { 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); WRITE_TO(mark, "%S%S\\quad$\\%S$%S", chaptermark, sectionmark, orn, N); 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) && ((S->md->is_a_singleton) || (wv->pattern->show_abbrevs == FALSE))) 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->sect_range); DISCARD_TEXT(mark); DISCARD_TEXT(modified); Regexp__dispose_of(&mr); } #line 180 "inweb/Chapter 5/TeX Format.w" void TeX__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) { if (code_mode == FALSE) WRITE("\\smallskip\\par\\noindent"); if (starts) { { #line 212 "inweb/Chapter 5/TeX Format.w" for (int i=0; i 0) WRITE("{\\ninebf %S} ", prefatory); WRITE("|"); } 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 216 "inweb/Chapter 5/TeX Format.w" if (colour_wanted != current_colour) { Formats__change_colour(OUT, wv, colour_wanted, TRUE); current_colour = colour_wanted; } } #line 192 "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 216 "inweb/Chapter 5/TeX Format.w" if (colour_wanted != current_colour) { Formats__change_colour(OUT, wv, colour_wanted, TRUE); current_colour = colour_wanted; } } #line 196 "inweb/Chapter 5/TeX Format.w" ; if (finishes) { WRITE("|"); if (Str__len(concluding_comment) > 0) { if ((Str__len(matter) > 0) || (!starts)) WRITE("\\hfill\\quad "); WRITE("{\\ttninepoint\\it %S}", concluding_comment); } WRITE("\n"); } } #line 222 "inweb/Chapter 5/TeX Format.w" void TeX__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) { WRITE("|"); } #line 228 "inweb/Chapter 5/TeX Format.w" void TeX__change_colour_PDF(weave_format *self, text_stream *OUT, weave_target *wv, 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 245 "inweb/Chapter 5/TeX Format.w" void TeX__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *text) { WRITE("\\quotesource{%S}\n", text); } #line 251 "inweb/Chapter 5/TeX Format.w" void TeX__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) { if (Str__len(label) > 0) { if (depth == 1) WRITE("\\item{(%S)}", label); else WRITE("\\itemitem{(%S)}", label); } else { if (depth == 1) WRITE("\\item{}"); else WRITE("\\itemitem{}"); } } #line 263 "inweb/Chapter 5/TeX Format.w" void TeX__bar(weave_format *self, text_stream *OUT, weave_target *wv) { WRITE("\\par\\medskip\\noindent\\hrule\\medskip\\noindent\n"); } #line 275 "inweb/Chapter 5/TeX Format.w" void TeX__figure_PDF(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) { WRITE("\\pdfximage"); if (w >= 0) WRITE(" width %d cm{../Figures/%S}\n", w, figname); else if (h >= 0) WRITE(" height %d cm{../Figures/%S}\n", h, figname); else WRITE("{../Figures/%S}\n", figname); WRITE("\\smallskip\\noindent" "\\hbox to\\hsize{\\hfill\\pdfrefximage \\pdflastximage\\hfill}" "\\smallskip\n"); } #line 297 "inweb/Chapter 5/TeX Format.w" void TeX__para_macro_PDF_1(weave_format *self, text_stream *OUT, weave_target *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); } void TeX__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) { WRITE("$\\langle${\\xreffont"); Formats__change_colour(OUT, wv, DEFINITION_COLOUR, FALSE); WRITE("%S ", pmac->macro_name); WRITE("{\\sevenss %S}}", pmac->defining_paragraph->paragraph_number); Formats__change_colour(OUT, wv, PLAIN_COLOUR, FALSE); WRITE("$\\rangle$ "); } void TeX__para_macro_PDF_2(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) { if (defn) WRITE("$\\equiv$|"); else WRITE("\\pdfendlink|"); } #line 324 "inweb/Chapter 5/TeX Format.w" void TeX__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) { WRITE("\\vfill\\eject\n"); } #line 329 "inweb/Chapter 5/TeX Format.w" void TeX__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) { if (in_comment) WRITE("\\smallskip\\par\\noindent%%\n"); else WRITE("\\smallskip\n"); } #line 336 "inweb/Chapter 5/TeX Format.w" void TeX__after_definitions(weave_format *self, text_stream *OUT, weave_target *wv) { WRITE("\\smallskip\n"); } #line 341 "inweb/Chapter 5/TeX Format.w" void TeX__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) { if (end == 1) { WRITE("\\par\\noindent\\penalty10000\n"); WRITE("{\\usagefont "); } else { WRITE("}\\smallskip\n"); } } #line 351 "inweb/Chapter 5/TeX Format.w" void TeX__commentary_text(weave_format *self, text_stream *OUT, weave_target *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 374 "inweb/Chapter 5/TeX Format.w" void TeX__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) { WRITE("$\\%S$%S", par1->ornament, par1->paragraph_number); if (par2) WRITE("-%S", par2->paragraph_number); } #line 381 "inweb/Chapter 5/TeX Format.w" void TeX__change_material(weave_format *self, text_stream *OUT, weave_target *wv, int old_material, int new_material, int content) { if (old_material != new_material) { switch (old_material) { case REGULAR_MATERIAL: switch (new_material) { case CODE_MATERIAL: WRITE("\\beginlines\n"); break; case DEFINITION_MATERIAL: WRITE("\\beginlines\n"); break; case MACRO_MATERIAL: WRITE("\\beginlines\n"); break; } break; default: if (new_material == REGULAR_MATERIAL) WRITE("\\endlines\n"); break; } } } #line 407 "inweb/Chapter 5/TeX Format.w" void TeX__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) { WRITE("%% %S\n", comment); WRITE("\\end\n"); } #line 417 "inweb/Chapter 5/TeX Format.w" int TeX__preform_document(weave_format *self, text_stream *OUT, web *W, weave_target *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 434 "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->min_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 422 "inweb/Chapter 5/TeX Format.w" ; return TRUE; } else { if (L->category == PREFORM_GRAMMAR_LCAT) { { #line 450 "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 (concluding_comment) Formats__text(OUT, wv, concluding_comment); WRITE("}"); } WRITE("\n"); DISCARD_TEXT(label); DISCARD_TEXT(problem); Regexp__dispose_of(&mr); } #line 426 "inweb/Chapter 5/TeX Format.w" ; return TRUE; } } return FALSE; } #line 496 "inweb/Chapter 5/TeX Format.w" void TeX__post_process_PDF(weave_format *self, weave_target *wv, int open) { RunningTeX__post_process_weave(wv, open, FALSE); } void TeX__post_process_DVI(weave_format *self, weave_target *wv, int open) { RunningTeX__post_process_weave(wv, open, TRUE); } #line 504 "inweb/Chapter 5/TeX Format.w" void TeX__post_process_report(weave_format *self, weave_target *wv) { RunningTeX__report_on_post_processing(wv); } #line 509 "inweb/Chapter 5/TeX Format.w" int TeX__post_process_substitute(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *detail, weave_pattern *pattern) { return RunningTeX__substitute_post_processing_data(OUT, wv, detail); } #line 522 "inweb/Chapter 5/TeX Format.w" void TeX__remove_math_mode(OUTPUT_STREAM, text_stream *text) { TEMPORARY_TEXT(math_matter); TeX__remove_math_mode_range(math_matter, text, 0, Str__len(text)-1); WRITE("%S", math_matter); DISCARD_TEXT(math_matter); } void TeX__remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) { for (int i=from; i <= to; i++) { { #line 553 "inweb/Chapter 5/TeX Format.w" if ((Str__get_at(text, i) == '\\') && (Str__get_at(text, i+1) == 'o') && (Str__get_at(text, i+2) == 'v') && (Str__get_at(text, i+3) == 'e') && (Str__get_at(text, i+4) == 'r') && (Str__get_at(text, i+5) == '{')) { int bl = 1; int j = i-1; for (; j >= from; j--) { wchar_t c = Str__get_at(text, j); if (c == '{') { bl--; if (bl == 0) break; } if (c == '}') bl++; } TeX__remove_math_mode_range(OUT, text, from, j-1); WRITE("(("); TeX__remove_math_mode_range(OUT, text, j+2, i-2); WRITE(") / ("); j=i+6; bl = 1; for (; j <= to; j++) { wchar_t c = Str__get_at(text, j); if (c == '}') { bl--; if (bl == 0) break; } if (c == '{') bl++; } TeX__remove_math_mode_range(OUT, text, i+6, j-1); WRITE("))"); TeX__remove_math_mode_range(OUT, text, j+2, to); return; } } #line 531 "inweb/Chapter 5/TeX Format.w" ; } for (int i=from; i <= to; i++) { { #line 589 "inweb/Chapter 5/TeX Format.w" if ((Str__get_at(text, i) == '{') && (Str__get_at(text, i+1) == '\\') && (((Str__get_at(text, i+2) == 'r') && (Str__get_at(text, i+3) == 'm')) || ((Str__get_at(text, i+2) == 'i') && (Str__get_at(text, i+3) == 't'))) && (Str__get_at(text, i+4) == ' ')) { TeX__remove_math_mode_range(OUT, text, from, i-1); int j=i+5; for (; j <= to; j++) if (Str__get_at(text, j) == '}') break; TeX__remove_math_mode_range(OUT, text, i+5, j-1); TeX__remove_math_mode_range(OUT, text, j+1, to); return; } } #line 534 "inweb/Chapter 5/TeX Format.w" ; { #line 607 "inweb/Chapter 5/TeX Format.w" if ((Str__get_at(text, i) == '\\') && (Str__get_at(text, i+1) == 's') && (Str__get_at(text, i+2) == 'q') && (Str__get_at(text, i+3) == 'r') && (Str__get_at(text, i+4) == 't') && (Str__get_at(text, i+5) == '{')) { if ((Str__get_at(text, i-4) == '{') && (Str__get_at(text, i-3) == '}') && (Str__get_at(text, i-2) == '^') && (Str__get_at(text, i-1) == '3')) { TeX__remove_math_mode_range(OUT, text, from, i-5); WRITE(" curt("); } else { TeX__remove_math_mode_range(OUT, text, from, i-1); WRITE(" sqrt("); } int j=i+6, bl = 1; for (; j <= to; j++) { wchar_t c = Str__get_at(text, j); if (c == '}') { bl--; if (bl == 0) break; } if (c == '{') bl++; } TeX__remove_math_mode_range(OUT, text, i+6, j-1); WRITE(")"); TeX__remove_math_mode_range(OUT, text, j+1, to); return; } } #line 535 "inweb/Chapter 5/TeX Format.w" ; } int math_mode = FALSE; for (int i=from; i <= to; i++) { switch (Str__get_at(text, i)) { case '$': if (Str__get_at(text, i+1) == '$') i++; math_mode = (math_mode)?FALSE:TRUE; break; case '~': if (math_mode) WRITE(" "); else WRITE("~"); break; case '\\': { #line 637 "inweb/Chapter 5/TeX Format.w" TEMPORARY_TEXT(macro); i++; while ((i < Str__len(text)) && (Characters__isalpha(Str__get_at(text, i)))) PUT_TO(macro, Str__get_at(text, i++)); if (Str__eq(macro, TL_IS_296)) { #line 749 "inweb/Chapter 5/TeX Format.w" if (Str__get_at(text, i) == '\\') { Str__clear(macro); i++; while ((i < Str__len(text)) && (Characters__isalpha(Str__get_at(text, i)))) PUT_TO(macro, Str__get_at(text, i++)); if (Str__eq(macro, TL_IS_390)) PUT((wchar_t) 0x2204); else if (Str__eq(macro, TL_IS_391)) { PUT((wchar_t) 0x00AC); PUT((wchar_t) 0x2200); } else { PRINT("Don't know how to apply '\\not' to '\\%S'\n", macro); } } else { PRINT("Don't know how to apply '\\not' here\n"); } } #line 641 "inweb/Chapter 5/TeX Format.w" else { #line 647 "inweb/Chapter 5/TeX Format.w" if (Str__eq(macro, TL_IS_297)) WRITE("<="); else if (Str__eq(macro, TL_IS_298)) WRITE(">="); else if (Str__eq(macro, TL_IS_299)) WRITE("~"); else if (Str__eq(macro, TL_IS_300)) WRITE(""); else if (Str__eq(macro, TL_IS_301)) WRITE(""); else if (Str__eq(macro, TL_IS_302)) WRITE(""); else if (Str__eq(macro, TL_IS_303)) WRITE("=>"); else if (Str__eq(macro, TL_IS_304)) WRITE("<=>"); else if (Str__eq(macro, TL_IS_305)) WRITE("-->"); else if (Str__eq(macro, TL_IS_306)) WRITE("-->"); else if (Str__eq(macro, TL_IS_307)) WRITE("-->"); else if (Str__eq(macro, TL_IS_308)) WRITE("<--"); else if (Str__eq(macro, TL_IS_309)) WRITE("<--"); else if (Str__eq(macro, TL_IS_310)) WRITE("{"); else if (Str__eq(macro, TL_IS_311)) WRITE("|"); else if (Str__eq(macro, TL_IS_312)) WRITE("}"); else if (Str__eq(macro, TL_IS_313)) WRITE("."); else if (Str__eq(macro, TL_IS_314)) WRITE("..."); else if (Str__eq(macro, TL_IS_315)) WRITE("..."); else if (Str__eq(macro, TL_IS_316)) WRITE("*"); else if (Str__eq(macro, TL_IS_317)) WRITE(" "); else if (Str__eq(macro, TL_IS_318)) WRITE(" "); else if (Str__eq(macro, TL_IS_319)) WRITE("TeX"); else if (Str__eq(macro, TL_IS_320)) WRITE("!="); else if (Str__eq(macro, TL_IS_321)) WRITE("!="); else if (Str__eq(macro, TL_IS_322)) WRITE("l"); else if (Str__eq(macro, TL_IS_323)) WRITE("log"); else if (Str__eq(macro, TL_IS_324)) WRITE("exp"); else if (Str__eq(macro, TL_IS_325)) WRITE("sin"); else if (Str__eq(macro, TL_IS_326)) WRITE("cos"); else if (Str__eq(macro, TL_IS_327)) WRITE("tan"); else if (Str__eq(macro, TL_IS_328)) WRITE("T"); else if (Str__eq(macro, TL_IS_329)) PUT((wchar_t) 0x0391); else if (Str__eq(macro, TL_IS_330)) PUT((wchar_t) 0x0392); else if (Str__eq(macro, TL_IS_331)) PUT((wchar_t) 0x0393); else if (Str__eq(macro, TL_IS_332)) PUT((wchar_t) 0x0394); else if (Str__eq(macro, TL_IS_333)) PUT((wchar_t) 0x0395); else if (Str__eq(macro, TL_IS_334)) PUT((wchar_t) 0x0396); else if (Str__eq(macro, TL_IS_335)) PUT((wchar_t) 0x0397); else if (Str__eq(macro, TL_IS_336)) PUT((wchar_t) 0x0398); else if (Str__eq(macro, TL_IS_337)) PUT((wchar_t) 0x0399); else if (Str__eq(macro, TL_IS_338)) PUT((wchar_t) 0x039A); else if (Str__eq(macro, TL_IS_339)) PUT((wchar_t) 0x039B); else if (Str__eq(macro, TL_IS_340)) PUT((wchar_t) 0x039C); else if (Str__eq(macro, TL_IS_341)) PUT((wchar_t) 0x039D); else if (Str__eq(macro, TL_IS_342)) PUT((wchar_t) 0x039E); else if (Str__eq(macro, TL_IS_343)) PUT((wchar_t) 0x039F); else if (Str__eq(macro, TL_IS_344)) PUT((wchar_t) 0x03A0); else if (Str__eq(macro, TL_IS_345)) PUT((wchar_t) 0x03A1); else if (Str__eq(macro, TL_IS_346)) PUT((wchar_t) 0x03A2); else if (Str__eq(macro, TL_IS_347)) PUT((wchar_t) 0x03A3); else if (Str__eq(macro, TL_IS_348)) PUT((wchar_t) 0x03A4); else if (Str__eq(macro, TL_IS_349)) PUT((wchar_t) 0x03A5); else if (Str__eq(macro, TL_IS_350)) PUT((wchar_t) 0x03A6); else if (Str__eq(macro, TL_IS_351)) PUT((wchar_t) 0x03A7); else if (Str__eq(macro, TL_IS_352)) PUT((wchar_t) 0x03A8); else if (Str__eq(macro, TL_IS_353)) PUT((wchar_t) 0x03A9); else if (Str__eq(macro, TL_IS_354)) PUT((wchar_t) 0x03B1); else if (Str__eq(macro, TL_IS_355)) PUT((wchar_t) 0x03B2); else if (Str__eq(macro, TL_IS_356)) PUT((wchar_t) 0x03B3); else if (Str__eq(macro, TL_IS_357)) PUT((wchar_t) 0x03B4); else if (Str__eq(macro, TL_IS_358)) PUT((wchar_t) 0x03B5); else if (Str__eq(macro, TL_IS_359)) PUT((wchar_t) 0x03B6); else if (Str__eq(macro, TL_IS_360)) PUT((wchar_t) 0x03B7); else if (Str__eq(macro, TL_IS_361)) PUT((wchar_t) 0x03B8); else if (Str__eq(macro, TL_IS_362)) PUT((wchar_t) 0x03B9); else if (Str__eq(macro, TL_IS_363)) PUT((wchar_t) 0x03BA); else if (Str__eq(macro, TL_IS_364)) PUT((wchar_t) 0x03BB); else if (Str__eq(macro, TL_IS_365)) PUT((wchar_t) 0x03BC); else if (Str__eq(macro, TL_IS_366)) PUT((wchar_t) 0x03BD); else if (Str__eq(macro, TL_IS_367)) PUT((wchar_t) 0x03BE); else if (Str__eq(macro, TL_IS_368)) PUT((wchar_t) 0x03BF); else if (Str__eq(macro, TL_IS_369)) PUT((wchar_t) 0x03C0); else if (Str__eq(macro, TL_IS_370)) PUT((wchar_t) 0x03C1); else if (Str__eq(macro, TL_IS_371)) PUT((wchar_t) 0x03C2); else if (Str__eq(macro, TL_IS_372)) PUT((wchar_t) 0x03C3); else if (Str__eq(macro, TL_IS_373)) PUT((wchar_t) 0x03C4); else if (Str__eq(macro, TL_IS_374)) PUT((wchar_t) 0x03C5); else if (Str__eq(macro, TL_IS_375)) PUT((wchar_t) 0x03C6); else if (Str__eq(macro, TL_IS_376)) PUT((wchar_t) 0x03C7); else if (Str__eq(macro, TL_IS_377)) PUT((wchar_t) 0x03C8); else if (Str__eq(macro, TL_IS_378)) PUT((wchar_t) 0x03C9); else if (Str__eq(macro, TL_IS_379)) PUT((wchar_t) 0x2203); else if (Str__eq(macro, TL_IS_380)) PUT((wchar_t) 0x2208); else if (Str__eq(macro, TL_IS_381)) PUT((wchar_t) 0x2200); else if (Str__eq(macro, TL_IS_382)) PUT((wchar_t) 0x2229); else if (Str__eq(macro, TL_IS_383)) PUT((wchar_t) 0x2205); else if (Str__eq(macro, TL_IS_384)) PUT((wchar_t) 0x2286); else if (Str__eq(macro, TL_IS_385)) PUT((wchar_t) 0x2227); else if (Str__eq(macro, TL_IS_386)) PUT((wchar_t) 0x2228); else if (Str__eq(macro, TL_IS_387)) PUT((wchar_t) 0x00AC); else if (Str__eq(macro, TL_IS_388)) PUT((wchar_t) 0x03A3); else if (Str__eq(macro, TL_IS_389)) PUT((wchar_t) 0x03A0); else { if (Str__len(macro) > 0) PRINT("Passing through unknown TeX macro \\%S: %S", macro, text); WRITE("\\%S", macro); } } #line 642 "inweb/Chapter 5/TeX Format.w" ; DISCARD_TEXT(macro); i--; } #line 544 "inweb/Chapter 5/TeX Format.w" ; break; default: PUT(Str__get_at(text, i)); break; } } } #line 6 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__create(void) { { #line 12 "inweb/Chapter 5/HTML Formats.w" weave_format *wf = Formats__create_weave_format(TL_IS_392, TL_IS_393); METHOD_ADD(wf, TOP_FOR_MTID, HTMLFormat__top); { #line 24 "inweb/Chapter 5/HTML Formats.w" METHOD_ADD(wf, SUBHEADING_FOR_MTID, HTMLFormat__subheading); METHOD_ADD(wf, TOC_FOR_MTID, HTMLFormat__toc); METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, HTMLFormat__paragraph_heading); METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, HTMLFormat__source_code); METHOD_ADD(wf, INLINE_CODE_FOR_MTID, HTMLFormat__inline_code); METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, HTMLFormat__display_line); METHOD_ADD(wf, ITEM_FOR_MTID, HTMLFormat__item); METHOD_ADD(wf, BAR_FOR_MTID, HTMLFormat__bar); METHOD_ADD(wf, FIGURE_FOR_MTID, HTMLFormat__figure); METHOD_ADD(wf, PARA_MACRO_FOR_MTID, HTMLFormat__para_macro); METHOD_ADD(wf, PAGEBREAK_FOR_MTID, HTMLFormat__pagebreak); METHOD_ADD(wf, BLANK_LINE_FOR_MTID, HTMLFormat__blank_line); METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, HTMLFormat__change_material); METHOD_ADD(wf, CHANGE_COLOUR_FOR_MTID, HTMLFormat__change_colour); METHOD_ADD(wf, ENDNOTE_FOR_MTID, HTMLFormat__endnote); METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, HTMLFormat__commentary_text); METHOD_ADD(wf, LOCALE_FOR_MTID, HTMLFormat__locale); METHOD_ADD(wf, TAIL_FOR_MTID, HTMLFormat__tail); } #line 14 "inweb/Chapter 5/HTML Formats.w" ; } #line 7 "inweb/Chapter 5/HTML Formats.w" ; { #line 17 "inweb/Chapter 5/HTML Formats.w" weave_format *wf = Formats__create_weave_format(TL_IS_394, TL_IS_395); METHOD_ADD(wf, TOP_FOR_MTID, HTMLFormat__top_EPUB); { #line 24 "inweb/Chapter 5/HTML Formats.w" METHOD_ADD(wf, SUBHEADING_FOR_MTID, HTMLFormat__subheading); METHOD_ADD(wf, TOC_FOR_MTID, HTMLFormat__toc); METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, HTMLFormat__paragraph_heading); METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, HTMLFormat__source_code); METHOD_ADD(wf, INLINE_CODE_FOR_MTID, HTMLFormat__inline_code); METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, HTMLFormat__display_line); METHOD_ADD(wf, ITEM_FOR_MTID, HTMLFormat__item); METHOD_ADD(wf, BAR_FOR_MTID, HTMLFormat__bar); METHOD_ADD(wf, FIGURE_FOR_MTID, HTMLFormat__figure); METHOD_ADD(wf, PARA_MACRO_FOR_MTID, HTMLFormat__para_macro); METHOD_ADD(wf, PAGEBREAK_FOR_MTID, HTMLFormat__pagebreak); METHOD_ADD(wf, BLANK_LINE_FOR_MTID, HTMLFormat__blank_line); METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, HTMLFormat__change_material); METHOD_ADD(wf, CHANGE_COLOUR_FOR_MTID, HTMLFormat__change_colour); METHOD_ADD(wf, ENDNOTE_FOR_MTID, HTMLFormat__endnote); METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, HTMLFormat__commentary_text); METHOD_ADD(wf, LOCALE_FOR_MTID, HTMLFormat__locale); METHOD_ADD(wf, TAIL_FOR_MTID, HTMLFormat__tail); } #line 19 "inweb/Chapter 5/HTML Formats.w" ; METHOD_ADD(wf, BEGIN_WEAVING_FOR_MTID, HTMLFormat__begin_weaving_EPUB); METHOD_ADD(wf, END_WEAVING_FOR_MTID, HTMLFormat__end_weaving_EPUB); } #line 8 "inweb/Chapter 5/HTML Formats.w" ; } #line 55 "inweb/Chapter 5/HTML Formats.w" int html_in_para = HTML_OUT; /* one of the above */ int item_depth = 0; /* for |HTML_IN_LI| only: how many lists we're nested inside */ void HTMLFormat__p(OUTPUT_STREAM, char *class) { if (class) HTML_OPEN_WITH("p", "class=\"%s\"", class) else HTML_OPEN("p"); html_in_para = HTML_IN_P; } void HTMLFormat__cp(OUTPUT_STREAM) { HTML_CLOSE("p"); WRITE("\n"); html_in_para = HTML_OUT; } void HTMLFormat__pre(OUTPUT_STREAM, char *class) { if (class) HTML_OPEN_WITH("pre", "class=\"%s\"", class) else HTML_OPEN("pre"); WRITE("\n"); INDENT; html_in_para = HTML_IN_PRE; } void HTMLFormat__cpre(OUTPUT_STREAM) { OUTDENT; HTML_CLOSE("pre"); WRITE("\n"); html_in_para = HTML_OUT; } #line 85 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__go_to_depth(OUTPUT_STREAM, int depth) { if (html_in_para != HTML_IN_LI) HTMLFormat__exit_current_paragraph(OUT); if (item_depth == depth) { HTML_CLOSE("li"); } else { while (item_depth < depth) { HTML_OPEN_WITH("ul", "class=\"items\""); item_depth++; } while (item_depth > depth) { HTML_CLOSE("li"); HTML_CLOSE("ul"); WRITE("\n"); item_depth--; } } if (depth > 0) { HTML_OPEN("li"); html_in_para = HTML_IN_LI; } else { html_in_para = HTML_OUT; } } #line 110 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__exit_current_paragraph(OUTPUT_STREAM) { switch (html_in_para) { case HTML_IN_P: HTMLFormat__cp(OUT); break; case HTML_IN_PRE: HTMLFormat__cpre(OUT); break; case HTML_IN_LI: HTMLFormat__go_to_depth(OUT, 0); break; } } #line 122 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__breadcrumb(OUTPUT_STREAM, text_stream *text, text_stream *link) { if (link) { HTML_OPEN("li"); HTML__begin_link(OUT, link); WRITE("%S", text); HTML__end_link(OUT); HTML_CLOSE("li"); } else { HTML_OPEN("li"); HTML_OPEN("b"); WRITE("%S", text); HTML_CLOSE("b"); HTML_CLOSE("li"); } } #line 142 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) { HTML__declare_as_HTML(OUT, FALSE); Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_396, wv, WEAVE_FIRST_HALF); if (wv->self_contained == FALSE) { filename *CSS = Patterns__obtain_filename(wv->pattern, TL_IS_397); if (wv->pattern->hierarchical) Patterns__copy_up_file_into_weave(wv->weave_web, CSS); else Patterns__copy_file_into_weave(wv->weave_web, CSS); } HTML__comment(OUT, comment); html_in_para = HTML_OUT; } void HTMLFormat__top_EPUB(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) { HTML__declare_as_HTML(OUT, TRUE); Epub__note_page(wv->weave_web->as_ebook, wv->weave_to, wv->booklet_title, TL_IS_398); Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_399, wv, WEAVE_FIRST_HALF); HTML__comment(OUT, comment); html_in_para = HTML_OUT; } #line 165 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) { HTMLFormat__exit_current_paragraph(OUT); switch (level) { case 1: HTML__heading(OUT, "h3", comment); break; case 2: HTMLFormat__p(OUT, "purpose"); WRITE("%S", comment); if (head) { WRITE(": "); Formats__text(OUT, wv, head); } HTMLFormat__cp(OUT); break; } } #line 182 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) { HTMLFormat__exit_current_paragraph(OUT); switch (stage) { case 1: HTML_OPEN_WITH("ul", "class=\"toc\""); HTML_OPEN("li"); break; case 2: HTML_CLOSE("li"); HTML_OPEN("li"); break; case 3: { TEMPORARY_TEXT(TEMP) HTMLFormat__xref(TEMP, wv, P, NULL, TRUE); HTML__begin_link(OUT, TEMP); DISCARD_TEXT(TEMP) WRITE("%s%S", (Str__get_first_char(P->ornament) == 'S')?"§":"¶", P->paragraph_number); WRITE(". %S", text2); HTML__end_link(OUT); break; } case 4: HTML_CLOSE("li"); HTML_CLOSE("ul"); HTML__hr(OUT, "tocbar"); WRITE("\n"); break; } } #line 214 "inweb/Chapter 5/HTML Formats.w" section *page_section = NULL; int crumbs_dropped = FALSE; void HTMLFormat__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) { page_section = S; if (weight == 3) return; /* Skip chapter headings */ HTMLFormat__exit_current_paragraph(OUT); if (P) { HTMLFormat__p(OUT, "inwebparagraph"); TEMPORARY_TEXT(TEMP) HTMLFormat__xref(TEMP, wv, P, NULL, FALSE); HTML__anchor(OUT, TEMP); DISCARD_TEXT(TEMP) HTML_OPEN("b"); WRITE("%s%S", (Str__get_first_char(P->ornament) == 'S')?"§":"¶", P->paragraph_number); WRITE(". %S%s ", heading_text, (Str__len(heading_text) > 0)?".":""); HTML_CLOSE("b"); } else { if (wv->self_contained == FALSE) { if (crumbs_dropped == FALSE) { filename *C = Patterns__obtain_filename(wv->pattern, TL_IS_400); if (wv->pattern->hierarchical) Patterns__copy_up_file_into_weave(wv->weave_web, C); else Patterns__copy_file_into_weave(wv->weave_web, C); crumbs_dropped = TRUE; } HTML_OPEN_WITH("ul", "class=\"crumbs\""); HTMLFormat__drop_initial_breadcrumbs(OUT, wv->breadcrumbs, wv->docs_mode); text_stream *bct = Bibliographic__get_datum(wv->weave_web->md, TL_IS_401); if (Str__len(Bibliographic__get_datum(wv->weave_web->md, TL_IS_402)) > 0) { bct = Bibliographic__get_datum(wv->weave_web->md, TL_IS_403); } HTMLFormat__breadcrumb(OUT, bct, TL_IS_404); if (wv->weave_web->md->chaptered) { TEMPORARY_TEXT(chapter_link); WRITE_TO(chapter_link, "index.html#%s%S", (wv->weave_web->as_ebook)?"C":"", S->owning_chapter->md->ch_range); HTMLFormat__breadcrumb(OUT, S->owning_chapter->md->ch_title, chapter_link); DISCARD_TEXT(chapter_link); } HTMLFormat__breadcrumb(OUT, heading_text, NULL); HTML_CLOSE("ul"); } else { HTML_OPEN_WITH("ul", "class=\"crumbs\""); HTMLFormat__breadcrumb(OUT, heading_text, NULL); HTML_CLOSE("ul"); } } } void HTMLFormat__drop_initial_breadcrumbs(OUTPUT_STREAM, linked_list *crumbs, int docs_mode) { if (LinkedLists__len(crumbs) > 0) { breadcrumb_request *BR; LOOP_OVER_LINKED_LIST(BR, breadcrumb_request, crumbs) { HTMLFormat__breadcrumb(OUT, BR->breadcrumb_text, BR->breadcrumb_link); } } else if (docs_mode) HTMLFormat__breadcrumb(OUT, TL_IS_405, TL_IS_406); } #line 282 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) { if (starts) { if (Str__len(prefatory) > 0) { HTML_OPEN_WITH("span", "class=\"definitionkeyword\""); WRITE("%S", prefatory); HTML_CLOSE("span"); WRITE(" "); if (Str__eq(prefatory, TL_IS_407)) { match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, matter, L"(%c*) from (%C+) *")) { HTMLFormat__source_code(self, OUT, wv, 0, NULL, mr.exp[0], colouring, concluding_comment, starts, FALSE, code_mode); HTML_OPEN_WITH("span", "class=\"definitionkeyword\""); WRITE(" from "); HTML_CLOSE("span"); HTMLFormat__source_code(self, OUT, wv, 0, NULL, mr.exp[1], colouring, concluding_comment, FALSE, finishes, code_mode); Regexp__dispose_of(&mr); return; } Regexp__dispose_of(&mr); } } else for (int i=0; i= 0) HTML_CLOSE("span"); Formats__change_colour(OUT, wv, colour_wanted, TRUE); current_colour = colour_wanted; } } #line 313 "inweb/Chapter 5/HTML Formats.w" ; if (Str__get_at(matter, i) == '<') WRITE("<"); else if (Str__get_at(matter, i) == '>') WRITE(">"); else if (Str__get_at(matter, i) == '&') WRITE("&"); else WRITE("%c", Str__get_at(matter, i)); } if (current_colour >= 0) HTML_CLOSE("span"); current_colour = -1; if (finishes) { if (Str__len(concluding_comment) > 0) { if (!starts) WRITE(" "); HTML_OPEN_WITH("span", "class=\"comment\""); Formats__text(OUT, wv, concluding_comment); HTML_CLOSE("span"); } WRITE("\n"); } } #line 340 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) { if (enter) { if (html_in_para == HTML_OUT) HTMLFormat__p(OUT, "inwebparagraph"); HTML_OPEN_WITH("code", "class=\"display\""); } else { HTML_CLOSE("code"); } } #line 351 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *from) { HTMLFormat__exit_current_paragraph(OUT); HTML_OPEN("blockquote"); WRITE("\n"); INDENT; HTMLFormat__p(OUT, NULL); WRITE("%S", from); HTMLFormat__cp(OUT); OUTDENT; HTML_CLOSE("blockquote"); WRITE("\n"); } #line 362 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) { HTMLFormat__go_to_depth(OUT, depth); if (Str__len(label) > 0) WRITE("(%S) ", label); else WRITE(" "); } #line 371 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__bar(weave_format *self, text_stream *OUT, weave_target *wv) { HTMLFormat__exit_current_paragraph(OUT); HTML__hr(OUT, NULL); } #line 383 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__figure(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) { HTMLFormat__exit_current_paragraph(OUT); filename *F = Filenames__in_folder( Pathnames__subfolder(wv->weave_web->md->path_to_web, TL_IS_408), figname); filename *RF = Filenames__from_text(figname); TEMPORARY_TEXT(ext); Filenames__write_extension(ext, RF); if (Str__eq_insensitive(ext, TL_IS_409)) { if (pl == NULL) HTMLFormat__pre(OUT, NULL); else HTMLFormat__pre(OUT, NULL); if (pl) Painter__reset_syntax_colouring(pl); HTML_figure_state hfs; hfs.OUT = OUT; hfs.colour_as = pl; hfs.wv = wv; hfs.keywords = (pl)?(&(pl->built_in_keywords)):NULL; TextFiles__read(F, FALSE, "unable to read file of textual figure", TRUE, &HTMLFormat__text_file_helper, NULL, &hfs); if (pl == NULL) HTMLFormat__cpre(OUT); else HTMLFormat__cpre(OUT); } else { HTML_OPEN("center"); HTML__image(OUT, RF); Patterns__copy_file_into_weave(wv->weave_web, F); HTML_CLOSE("center"); } DISCARD_TEXT(ext); WRITE("\n"); } void HTMLFormat__text_file_helper(text_stream *text, text_file_position *tfp, void *state) { HTML_figure_state *hfs = (HTML_figure_state *) state; TEMPORARY_TEXT(colouring); LOOP_THROUGH_TEXT(pos, text) PUT_TO(colouring, PLAIN_COLOUR); if (hfs->colour_as) { Painter__syntax_colour(hfs->colour_as, hfs->OUT, hfs->keywords, text, colouring, TRUE); Formats__source_code(hfs->OUT, hfs->wv, 1, TL_IS_410, text, colouring, TL_IS_411, TRUE, TRUE, TRUE); } else { WRITE_TO(hfs->OUT, "%S\n", text); } DISCARD_TEXT(colouring); } #line 430 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) { paragraph *P = pmac->defining_paragraph; WRITE("<"); HTML_OPEN_WITH("span", "class=\"%s\"", (defn)?"cwebmacrodefn":"cwebmacro"); WRITE("%S", pmac->macro_name); HTML_CLOSE("span"); WRITE(" "); HTML_OPEN_WITH("span", "class=\"cwebmacronumber\""); WRITE("%S", P->paragraph_number); HTML_CLOSE("span"); WRITE(">%s", (defn)?" =":""); } #line 445 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) { HTMLFormat__exit_current_paragraph(OUT); } #line 450 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) { if (html_in_para == HTML_IN_PRE) { WRITE("\n"); } else { int old_state = html_in_para, old_depth = item_depth; HTMLFormat__exit_current_paragraph(OUT); if ((old_state == HTML_IN_P) || ((old_state == HTML_IN_LI) && (old_depth > 1))) HTMLFormat__p(OUT,"inwebparagraph"); } } #line 463 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__change_material(weave_format *self, text_stream *OUT, weave_target *wv, int old_material, int new_material, int content) { if (old_material != new_material) { if (old_material == MACRO_MATERIAL) HTML_CLOSE("code"); if ((content) || (new_material != MACRO_MATERIAL)) HTMLFormat__exit_current_paragraph(OUT); switch (old_material) { case CODE_MATERIAL: case REGULAR_MATERIAL: switch (new_material) { case CODE_MATERIAL: WRITE("\n"); HTMLFormat__pre(OUT, "display"); break; case DEFINITION_MATERIAL: WRITE("\n"); HTMLFormat__pre(OUT, "definitions"); break; case MACRO_MATERIAL: if (content) { WRITE("\n"); HTMLFormat__p(OUT,"macrodefinition"); } HTML_OPEN_WITH("code", "class=\"display\""); WRITE("\n"); break; case REGULAR_MATERIAL: if (content) { WRITE("\n"); HTMLFormat__p(OUT,"inwebparagraph"); } break; } break; case MACRO_MATERIAL: switch (new_material) { case CODE_MATERIAL: WRITE("\n"); HTMLFormat__pre(OUT, "displaydefn"); break; case DEFINITION_MATERIAL: WRITE("\n"); HTMLFormat__pre(OUT, "definitions"); break; } break; case DEFINITION_MATERIAL: switch (new_material) { case CODE_MATERIAL: WRITE("\n"); HTMLFormat__pre(OUT, "display"); break; case MACRO_MATERIAL: WRITE("\n"); HTMLFormat__p(OUT, "macrodefinition"); HTML_OPEN_WITH("code", "class=\"display\""); WRITE("\n"); break; } break; default: HTMLFormat__cpre(OUT); break; } } } #line 531 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__change_colour(weave_format *self, text_stream *OUT, weave_target *wv, int col, int in_code) { char *cl = "plain"; switch (col) { case DEFINITION_COLOUR: cl = "cwebmacrotext"; break; case FUNCTION_COLOUR: cl = "functiontext"; break; case IDENTIFIER_COLOUR: cl = "identifier"; break; case ELEMENT_COLOUR: cl = "element"; break; case RESERVED_COLOUR: cl = "reserved"; break; case STRING_COLOUR: cl = "string"; break; case CHAR_LITERAL_COLOUR: cl = "character"; break; case CONSTANT_COLOUR: cl = "constant"; break; case PLAIN_COLOUR: cl = "plain"; break; case EXTRACT_COLOUR: cl = "extract"; break; case COMMENT_COLOUR: cl = "comment"; break; default: PRINT("col: %d\n", col); internal_error("bad colour"); break; } HTML_OPEN_WITH("span", "class=\"%s\"", cl); } #line 552 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) { if (end == 1) { HTMLFormat__exit_current_paragraph(OUT); HTMLFormat__p(OUT, "endnote"); } else { HTMLFormat__cp(OUT); } } #line 562 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) { for (int i=0; i < Str__len(id); i++) { if (html_in_para == HTML_OUT) HTMLFormat__p(OUT, "inwebparagraph"); if (Str__get_at(id, i) == '&') WRITE("&"); else if (Str__get_at(id, i) == '<') WRITE("<"); else if (Str__get_at(id, i) == '>') WRITE(">"); else if ((i == 0) && (Str__get_at(id, i) == '-') && (Str__get_at(id, i+1) == '-') && ((Str__get_at(id, i+2) == ' ') || (Str__get_at(id, i+2) == 0))) { WRITE("—"); i++; } else if ((Str__get_at(id, i) == ' ') && (Str__get_at(id, i+1) == '-') && (Str__get_at(id, i+2) == '-') && ((Str__get_at(id, i+3) == ' ') || (Str__get_at(id, i+3) == '\n') || (Str__get_at(id, i+3) == 0))) { WRITE(" —"); i+=2; } else PUT(Str__get_at(id, i)); } } #line 583 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) { TEMPORARY_TEXT(TEMP) HTMLFormat__xref(TEMP, wv, par1, page_section, TRUE); HTML__begin_link(OUT, TEMP); DISCARD_TEXT(TEMP) WRITE("%s%S", (Str__get_first_char(par1->ornament) == 'S')?"§":"¶", par1->paragraph_number); if (par2) WRITE("-%S", par2->paragraph_number); HTML__end_link(OUT); } #line 597 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__xref(OUTPUT_STREAM, weave_target *wv, paragraph *P, section *from, int a_link) { TEMPORARY_TEXT(linkto); if ((from) && (P->under_section != from)) { Str__copy(linkto, P->under_section->sect_range); LOOP_THROUGH_TEXT(pos, linkto) if ((Str__get(pos) == '/') || (Str__get(pos) == ' ')) Str__put(pos, '-'); WRITE_TO(linkto, ".html"); } WRITE("%S%s%S", linkto, (a_link)?"#":"", P->ornament); DISCARD_TEXT(linkto); WRITE("P"); text_stream *N = P->paragraph_number; LOOP_THROUGH_TEXT(pos, N) if (Str__get(pos) == '.') WRITE("_"); else PUT(Str__get(pos)); } #line 618 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *this_S) { HTMLFormat__exit_current_paragraph(OUT); if (wv->docs_mode) { chapter *C = this_S->owning_chapter; section *S, *last_S = NULL, *prev_S = NULL, *next_S = NULL; LOOP_OVER_LINKED_LIST(S, section, C->sections) { if (S == this_S) prev_S = last_S; if (last_S == this_S) next_S = S; last_S = S; } if ((prev_S) || (next_S)) { HTML__hr(OUT, "tocbar"); HTML_OPEN_WITH("ul", "class=\"toc\""); HTML_OPEN("li"); if (prev_S == NULL) WRITE("(This section begins %S.)", C->md->ch_title); else { TEMPORARY_TEXT(TEMP); HTMLFormat__sref(TEMP, wv, prev_S); HTML__begin_link(OUT, TEMP); WRITE("Back to '%S'", prev_S->md->sect_title); HTML__end_link(OUT); DISCARD_TEXT(TEMP); } HTML_CLOSE("li"); HTML_OPEN("li"); if (next_S == NULL) WRITE("(This section ends %S.)", C->md->ch_title); else { TEMPORARY_TEXT(TEMP); HTMLFormat__sref(TEMP, wv, next_S); HTML__begin_link(OUT, TEMP); WRITE("Continue with '%S'", next_S->md->sect_title); HTML__end_link(OUT); DISCARD_TEXT(TEMP); } HTML_CLOSE("li"); HTML_CLOSE("ul"); } HTML__hr(OUT, "tocbar"); } HTML__comment(OUT, comment); HTML__completed(OUT); Bibliographic__set_datum(wv->weave_web->md, TL_IS_412, wv->booklet_title); Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_413, wv, WEAVE_SECOND_HALF); } #line 665 "inweb/Chapter 5/HTML Formats.w" void HTMLFormat__sref(OUTPUT_STREAM, weave_target *wv, section *S) { if (S == NULL) internal_error("unwoven section"); LOOP_THROUGH_TEXT(pos, S->sect_range) if (Str__get(pos) == '/') PUT('-'); else PUT(Str__get(pos)); WRITE(".html"); } #line 678 "inweb/Chapter 5/HTML Formats.w" int HTMLFormat__begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) { TEMPORARY_TEXT(T) WRITE_TO(T, "%S", Bibliographic__get_datum(W->md, TL_IS_414)); W->as_ebook = Epub__new(T, "P"); filename *CSS = Patterns__obtain_filename(pattern, TL_IS_415); Epub__use_CSS_throughout(W->as_ebook, CSS); Epub__attach_metadata(W->as_ebook, L"identifier", T); DISCARD_TEXT(T) pathname *P = Reader__woven_folder(W); W->redirect_weaves_to = Epub__begin_construction(W->as_ebook, P, NULL); Shell__copy(CSS, W->redirect_weaves_to, ""); return SWARM_SECTIONS_SWM; } void HTMLFormat__end_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) { Epub__end_construction(W->as_ebook); } #line 22 "inweb/Chapter 5/Running Through TeX.w" void RunningTeX__post_process_weave(weave_target *wv, int open_afterwards, int to_DVI) { filename *console_filename = Filenames__set_extension(wv->weave_to, "console"); filename *log_filename = Filenames__set_extension(wv->weave_to, "log"); filename *pdf_filename = Filenames__set_extension(wv->weave_to, "pdf"); tex_results *res = CREATE(tex_results); { #line 52 "inweb/Chapter 5/Running Through TeX.w" res->overfull_hbox_count = 0; res->tex_error_count = 0; res->page_count = 0; res->pdf_size = 0; res->PDF_filename = pdf_filename; } #line 28 "inweb/Chapter 5/Running Through TeX.w" ; wv->post_processing_results = (void *) res; { #line 59 "inweb/Chapter 5/Running Through TeX.w" TEMPORARY_TEXT(TEMP) filename *tex_rel = Filenames__without_path(wv->weave_to); filename *console_rel = Filenames__without_path(console_filename); Shell__plain(TEMP, "cd "); Shell__quote_path(TEMP, Filenames__get_path_to(wv->weave_to)); Shell__plain(TEMP, "; "); text_stream *tool = wv->pattern->pdftex_command; if (to_DVI) tool = wv->pattern->tex_command; WRITE_TO(TEMP, "%S", tool); Shell__plain(TEMP, " -interaction=scrollmode "); Shell__quote_file(TEMP, tex_rel); Shell__plain(TEMP, ">"); Shell__quote_file(TEMP, console_rel); Shell__run(TEMP); DISCARD_TEXT(TEMP) } #line 31 "inweb/Chapter 5/Running Through TeX.w" ; { #line 82 "inweb/Chapter 5/Running Through TeX.w" TextFiles__read(console_filename, FALSE, "can't open console file", TRUE, RunningTeX__scan_console_line, NULL, (void *) res); } #line 32 "inweb/Chapter 5/Running Through TeX.w" ; { #line 94 "inweb/Chapter 5/Running Through TeX.w" if (res->tex_error_count == 0) { Shell__rm(console_filename); Shell__rm(log_filename); Shell__rm(wv->weave_to); } } #line 33 "inweb/Chapter 5/Running Through TeX.w" ; if (open_afterwards) { #line 103 "inweb/Chapter 5/Running Through TeX.w" if (Str__len(wv->pattern->open_command) == 0) Errors__fatal("no way to open PDF (see pattern.txt file)"); else Shell__apply_S(wv->pattern->open_command, pdf_filename); } #line 35 "inweb/Chapter 5/Running Through TeX.w" ; } #line 50 "inweb/Chapter 5/Running Through TeX.w" #line 109 "inweb/Chapter 5/Running Through TeX.w" void RunningTeX__scan_console_line(text_stream *line, text_file_position *tfp, void *res_V) { tex_results *res = (tex_results *) res_V; match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, line, L"Output written %c*? %((%d+) page%c*?(%d+) bytes%).")) { res->page_count = Str__atoi(mr.exp[0], 0); res->pdf_size = Str__atoi(mr.exp[1], 0); } if (Regexp__match(&mr, line, L"%c+verfull \\hbox%c+")) res->overfull_hbox_count++; else if (Str__get_first_char(line) == '!') { res->tex_error_count++; } Regexp__dispose_of(&mr); } #line 129 "inweb/Chapter 5/Running Through TeX.w" void RunningTeX__report_on_post_processing(weave_target *wv) { tex_results *res = wv->post_processing_results; if (res) { PRINT(": %dpp %dK", res->page_count, res->pdf_size/1024); if (res->overfull_hbox_count > 0) PRINT(", %d overfull hbox(es)", res->overfull_hbox_count); if (res->tex_error_count > 0) PRINT(", %d error(s)", res->tex_error_count); } } #line 143 "inweb/Chapter 5/Running Through TeX.w" int RunningTeX__substitute_post_processing_data(text_stream *to, weave_target *wv, text_stream *detail) { if (wv) { tex_results *res = wv->post_processing_results; if (res) { if (Str__eq_wide_string(detail, L"PDF Size")) { WRITE_TO(to, "%dKB", res->pdf_size/1024); } else if (Str__eq_wide_string(detail, L"Extent")) { WRITE_TO(to, "%dpp", res->page_count); } else if (Str__eq_wide_string(detail, L"Leafname")) { Str__copy(to, Filenames__get_leafname(res->PDF_filename)); } else if (Str__eq_wide_string(detail, L"Errors")) { Str__clear(to); if ((res->overfull_hbox_count > 0) || (res->tex_error_count > 0)) WRITE_TO(to, ": "); if (res->overfull_hbox_count > 0) WRITE_TO(to, "%d overfull line%s", res->overfull_hbox_count, (res->overfull_hbox_count>1)?"s":""); if ((res->overfull_hbox_count > 0) && (res->tex_error_count > 0)) WRITE_TO(to, ", "); if (res->tex_error_count > 0) WRITE_TO(to, "%d TeX error%s", res->tex_error_count, (res->tex_error_count>1)?"s":""); } else return FALSE; return TRUE; } } return FALSE; } #line 23 "inweb/Chapter 6/Makefiles.w" void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I) { makefile_state MS; MS.for_web = W; MS.last_line_was_blank = TRUE; MS.repeat_block = Str__new(); MS.inside_block = FALSE; MS.allow_commands = TRUE; MS.tools_dictionary = Dictionaries__new(16, FALSE); MS.webs_dictionary = Dictionaries__new(16, FALSE); MS.modules_dictionary = Dictionaries__new(16, FALSE); MS.search_path = I; MS.repeat_scope = -1; MS.repeat_tag = NULL; text_stream *OUT = &(MS.to_makefile); if (STREAM_OPEN_TO_FILE(OUT, F, ISO_ENC) == FALSE) Errors__fatal_with_file("unable to write tangled file", F); WRITE("# This makefile was automatically written by inweb -makefile\n"); WRITE("# and is not intended for human editing\n\n"); TextFiles__read(prototype, FALSE, "can't open prototype file", TRUE, Makefiles__scan_makefile_line, NULL, &MS); STREAM_CLOSE(OUT); WRITE_TO(STDOUT, "Wrote makefile '%f' from script '%f'\n", F, prototype); } #line 49 "inweb/Chapter 6/Makefiles.w" void Makefiles__scan_makefile_line(text_stream *line, text_file_position *tfp, void *X) { makefile_state *MS = (makefile_state *) X; text_stream *OUT = &(MS->to_makefile); match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, line, L" *#%c*")) { Regexp__dispose_of(&mr); return; } // Skip comment lines if (MS->allow_commands) { if (Regexp__match(&mr, line, L" *{repeat-tools-block:(%C*)} *")) { #line 93 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_TOOL_MOM; { #line 105 "inweb/Chapter 6/Makefiles.w" if (MS->inside_block) Errors__in_text_file("nested repeat blocks are not allowed", tfp); MS->inside_block = TRUE; MS->repeat_scope = marker; MS->repeat_tag = Str__duplicate(mr.exp[0]); Str__clear(MS->repeat_block); Regexp__dispose_of(&mr); return; } #line 94 "inweb/Chapter 6/Makefiles.w" ; } #line 57 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{repeat-webs-block:(%C*)} *")) { #line 97 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_WEB_MOM; { #line 105 "inweb/Chapter 6/Makefiles.w" if (MS->inside_block) Errors__in_text_file("nested repeat blocks are not allowed", tfp); MS->inside_block = TRUE; MS->repeat_scope = marker; MS->repeat_tag = Str__duplicate(mr.exp[0]); Str__clear(MS->repeat_block); Regexp__dispose_of(&mr); return; } #line 98 "inweb/Chapter 6/Makefiles.w" ; } #line 59 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{repeat-modules-block:(%C*)} *")) { #line 101 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_MODULE_MOM; { #line 105 "inweb/Chapter 6/Makefiles.w" if (MS->inside_block) Errors__in_text_file("nested repeat blocks are not allowed", tfp); MS->inside_block = TRUE; MS->repeat_scope = marker; MS->repeat_tag = Str__duplicate(mr.exp[0]); Str__clear(MS->repeat_block); Regexp__dispose_of(&mr); return; } #line 102 "inweb/Chapter 6/Makefiles.w" ; } #line 61 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{end-block} *")) { #line 118 "inweb/Chapter 6/Makefiles.w" if (MS->inside_block == FALSE) Errors__in_text_file("{endblock} without {repeatblock}", tfp); MS->inside_block = FALSE; Makefiles__repeat(OUT, NULL, TRUE, MS->repeat_block, TRUE, NULL, tfp, MS, MS->repeat_scope, MS->repeat_tag); Str__clear(MS->repeat_block); Regexp__dispose_of(&mr); return; } #line 62 "inweb/Chapter 6/Makefiles.w" ; if (MS->inside_block) { #line 114 "inweb/Chapter 6/Makefiles.w" WRITE_TO(MS->repeat_block, "%S\n", line); return; } #line 63 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L"(%c*){repeat-tools-span}(%c*?){end-span}(%c*)")) { #line 127 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_TOOL_MOM; { #line 139 "inweb/Chapter 6/Makefiles.w" WRITE("%S", mr.exp[0]); Makefiles__repeat(OUT, TL_IS_416, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_417); WRITE("%S\n", mr.exp[2]); MS->last_line_was_blank = FALSE; Regexp__dispose_of(&mr); return; } #line 128 "inweb/Chapter 6/Makefiles.w" ; } #line 66 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L"(%c*){repeat-webs-span}(%c*?){end-span}(%c*)")) { #line 131 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_WEB_MOM; { #line 139 "inweb/Chapter 6/Makefiles.w" WRITE("%S", mr.exp[0]); Makefiles__repeat(OUT, TL_IS_416, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_417); WRITE("%S\n", mr.exp[2]); MS->last_line_was_blank = FALSE; Regexp__dispose_of(&mr); return; } #line 132 "inweb/Chapter 6/Makefiles.w" ; } #line 68 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L"(%c*){repeat-modules-span}(%c*?){end-span}(%c*)")) { #line 135 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_MODULE_MOM; { #line 139 "inweb/Chapter 6/Makefiles.w" WRITE("%S", mr.exp[0]); Makefiles__repeat(OUT, TL_IS_416, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_417); WRITE("%S\n", mr.exp[2]); MS->last_line_was_blank = FALSE; Regexp__dispose_of(&mr); return; } #line 136 "inweb/Chapter 6/Makefiles.w" ; } #line 70 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{identity-settings} *")) { #line 156 "inweb/Chapter 6/Makefiles.w" WRITE("INWEB = "); Makefiles__pathname_slashed(OUT, path_to_inweb); WRITE("/Tangled/inweb\n"); pathname *path_to_intest = Pathnames__subfolder(Pathnames__up(path_to_inweb), TL_IS_419); WRITE("INTEST = "); Makefiles__pathname_slashed(OUT, path_to_intest); WRITE("/Tangled/intest\n"); if (MS->for_web) { WRITE("MYNAME = %S\n", Pathnames__directory_name(MS->for_web->md->path_to_web)); WRITE("ME = "); Makefiles__pathname_slashed(OUT, MS->for_web->md->path_to_web); WRITE("\n"); MS->last_line_was_blank = FALSE; } Regexp__dispose_of(&mr); return; } #line 72 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{platform-settings} *")) { #line 147 "inweb/Chapter 6/Makefiles.w" filename *prototype = Filenames__in_folder(path_to_inweb, TL_IS_418); MS->allow_commands = FALSE; TextFiles__read(prototype, FALSE, "can't open make settings file", TRUE, Makefiles__scan_makefile_line, NULL, MS); Regexp__dispose_of(&mr); MS->allow_commands = TRUE; return; } #line 73 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{tool} *(%C+) (%C+) (%c+) (%C+) *")) { #line 169 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_TOOL_MOM; { #line 181 "inweb/Chapter 6/Makefiles.w" WRITE("%SLEAF = %S\n", mr.exp[0], mr.exp[1]); WRITE("%SWEB = %S\n", mr.exp[0], mr.exp[2]); WRITE("%SMAKER = $(%SWEB)/%S.mk\n", mr.exp[0], mr.exp[0], mr.exp[1]); WRITE("%SX = $(%SWEB)/Tangled/%S\n", mr.exp[0], mr.exp[0], mr.exp[1]); MS->last_line_was_blank = FALSE; web_md *Wm = Reader__load_web_md(Pathnames__from_text(mr.exp[2]), NULL, MS->search_path, FALSE, TRUE); Wm->as_module->module_name = Str__duplicate(mr.exp[0]); Wm->as_module->module_tag = Str__duplicate(mr.exp[3]); Wm->as_module->origin_marker = marker; Dictionaries__create(MS->tools_dictionary, mr.exp[0]); Dictionaries__write_value(MS->tools_dictionary, mr.exp[0], Wm); Regexp__dispose_of(&mr); return; } #line 170 "inweb/Chapter 6/Makefiles.w" ; } #line 75 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{web} *(%C+) (%C+) (%c+) (%C+) *")) { #line 173 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_WEB_MOM; { #line 181 "inweb/Chapter 6/Makefiles.w" WRITE("%SLEAF = %S\n", mr.exp[0], mr.exp[1]); WRITE("%SWEB = %S\n", mr.exp[0], mr.exp[2]); WRITE("%SMAKER = $(%SWEB)/%S.mk\n", mr.exp[0], mr.exp[0], mr.exp[1]); WRITE("%SX = $(%SWEB)/Tangled/%S\n", mr.exp[0], mr.exp[0], mr.exp[1]); MS->last_line_was_blank = FALSE; web_md *Wm = Reader__load_web_md(Pathnames__from_text(mr.exp[2]), NULL, MS->search_path, FALSE, TRUE); Wm->as_module->module_name = Str__duplicate(mr.exp[0]); Wm->as_module->module_tag = Str__duplicate(mr.exp[3]); Wm->as_module->origin_marker = marker; Dictionaries__create(MS->tools_dictionary, mr.exp[0]); Dictionaries__write_value(MS->tools_dictionary, mr.exp[0], Wm); Regexp__dispose_of(&mr); return; } #line 174 "inweb/Chapter 6/Makefiles.w" ; } #line 76 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L" *{module} *(%C+) (%C+) (%c+) (%C+) *")) { #line 177 "inweb/Chapter 6/Makefiles.w" int marker = MAKEFILE_MODULE_MOM; { #line 181 "inweb/Chapter 6/Makefiles.w" WRITE("%SLEAF = %S\n", mr.exp[0], mr.exp[1]); WRITE("%SWEB = %S\n", mr.exp[0], mr.exp[2]); WRITE("%SMAKER = $(%SWEB)/%S.mk\n", mr.exp[0], mr.exp[0], mr.exp[1]); WRITE("%SX = $(%SWEB)/Tangled/%S\n", mr.exp[0], mr.exp[0], mr.exp[1]); MS->last_line_was_blank = FALSE; web_md *Wm = Reader__load_web_md(Pathnames__from_text(mr.exp[2]), NULL, MS->search_path, FALSE, TRUE); Wm->as_module->module_name = Str__duplicate(mr.exp[0]); Wm->as_module->module_tag = Str__duplicate(mr.exp[3]); Wm->as_module->origin_marker = marker; Dictionaries__create(MS->tools_dictionary, mr.exp[0]); Dictionaries__write_value(MS->tools_dictionary, mr.exp[0], Wm); Regexp__dispose_of(&mr); return; } #line 178 "inweb/Chapter 6/Makefiles.w" ; } #line 77 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files} *")) { #line 196 "inweb/Chapter 6/Makefiles.w" WRITE("%S", mr.exp[0]); Makefiles__pattern(OUT, MS->for_web->md->sections_md, MS->for_web->md->contents_filename); WRITE("\n"); MS->last_line_was_blank = FALSE; Regexp__dispose_of(&mr); return; } #line 79 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files-for-tool-alone} *(%C+)")) { #line 221 "inweb/Chapter 6/Makefiles.w" WRITE("%S", mr.exp[0]); if (Dictionaries__find(MS->tools_dictionary, mr.exp[1])) { web_md *Wm = Dictionaries__read_value(MS->tools_dictionary, mr.exp[1]); Makefiles__pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename); } else if (Dictionaries__find(MS->webs_dictionary, mr.exp[1])) { web_md *Wm = Dictionaries__read_value(MS->webs_dictionary, mr.exp[1]); Makefiles__pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename); } else { PRINT("Tool %S\n", mr.exp[0]); Errors__in_text_file("unknown tool to find dependencies for", tfp); } WRITE("\n"); MS->last_line_was_blank = FALSE; Regexp__dispose_of(&mr); return; } #line 81 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files-for-tool-and-modules} *(%C+)")) { #line 204 "inweb/Chapter 6/Makefiles.w" WRITE("%S", mr.exp[0]); if (Dictionaries__find(MS->tools_dictionary, mr.exp[1])) { web_md *Wm = Dictionaries__read_value(MS->tools_dictionary, mr.exp[1]); Makefiles__pattern(OUT, Wm->sections_md, Wm->contents_filename); } else if (Dictionaries__find(MS->webs_dictionary, mr.exp[1])) { web_md *Wm = Dictionaries__read_value(MS->webs_dictionary, mr.exp[1]); Makefiles__pattern(OUT, Wm->sections_md, Wm->contents_filename); } else { PRINT("Tool %S\n", mr.exp[0]); Errors__in_text_file("unknown tool to find dependencies for", tfp); } WRITE("\n"); MS->last_line_was_blank = FALSE; Regexp__dispose_of(&mr); return; } #line 83 "inweb/Chapter 6/Makefiles.w" ; if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files-for-module} *(%C+)")) { #line 238 "inweb/Chapter 6/Makefiles.w" WRITE("%S", mr.exp[0]); if (Dictionaries__find(MS->modules_dictionary, mr.exp[1])) { web_md *Wm = Dictionaries__read_value(MS->modules_dictionary, mr.exp[1]); Makefiles__pattern(OUT, Wm->sections_md, Wm->contents_filename); } else { Errors__in_text_file("unknown module to find dependencies for", tfp); } WRITE("\n"); MS->last_line_was_blank = FALSE; Regexp__dispose_of(&mr); return; } #line 85 "inweb/Chapter 6/Makefiles.w" ; } Regexp__dispose_of(&mr); { #line 251 "inweb/Chapter 6/Makefiles.w" if (Str__len(line) == 0) { if (MS->last_line_was_blank == FALSE) WRITE("\n"); MS->last_line_was_blank = TRUE; } else { MS->last_line_was_blank = FALSE; WRITE("%S\n", line); } } #line 89 "inweb/Chapter 6/Makefiles.w" ; } #line 260 "inweb/Chapter 6/Makefiles.w" void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) { TEMPORARY_TEXT(PT) WRITE_TO(PT, "%p", P); LOOP_THROUGH_TEXT(pos, PT) { wchar_t c = Str__get(pos); if (c == ' ') WRITE("\\ "); else PUT(c); } DISCARD_TEXT(PT) } void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) { dictionary *patterns_done = Dictionaries__new(16, TRUE); if (F) { #line 282 "inweb/Chapter 6/Makefiles.w" pathname *P = Filenames__get_path_to(F); TEMPORARY_TEXT(leaf_pattern); WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P)); match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, leaf_pattern, L"Chapter %d*")) { Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Chapter*"); } else if (Regexp__match(&mr, leaf_pattern, L"Appendix %C")) { Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Appendix*"); } Regexp__dispose_of(&mr); TEMPORARY_TEXT(tester); WRITE_TO(tester, "%p/%S/*", Pathnames__up(P), leaf_pattern); DISCARD_TEXT(leaf_pattern); Filenames__write_extension(tester, F); if (Dictionaries__find(patterns_done, tester) == NULL) { WRITE_TO(Dictionaries__create_text(patterns_done, tester), "got this"); WRITE(" "); LOOP_THROUGH_TEXT(pos, tester) { wchar_t c = Str__get(pos); if (c == ' ') PUT('\\'); PUT(c); } } DISCARD_TEXT(tester); } #line 273 "inweb/Chapter 6/Makefiles.w" ; section_md *Sm; LOOP_OVER_LINKED_LIST(Sm, section_md, L) { filename *F = Sm->source_file_for_section; { #line 282 "inweb/Chapter 6/Makefiles.w" pathname *P = Filenames__get_path_to(F); TEMPORARY_TEXT(leaf_pattern); WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P)); match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, leaf_pattern, L"Chapter %d*")) { Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Chapter*"); } else if (Regexp__match(&mr, leaf_pattern, L"Appendix %C")) { Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Appendix*"); } Regexp__dispose_of(&mr); TEMPORARY_TEXT(tester); WRITE_TO(tester, "%p/%S/*", Pathnames__up(P), leaf_pattern); DISCARD_TEXT(leaf_pattern); Filenames__write_extension(tester, F); if (Dictionaries__find(patterns_done, tester) == NULL) { WRITE_TO(Dictionaries__create_text(patterns_done, tester), "got this"); WRITE(" "); LOOP_THROUGH_TEXT(pos, tester) { wchar_t c = Str__get(pos); if (c == ' ') PUT('\\'); PUT(c); } } DISCARD_TEXT(tester); } #line 277 "inweb/Chapter 6/Makefiles.w" ; } } #line 310 "inweb/Chapter 6/Makefiles.w" void Makefiles__repeat(OUTPUT_STREAM, text_stream *prefix, int every_time, text_stream *matter, int as_lines, text_stream *suffix, text_file_position *tfp, makefile_state *MS, int over, text_stream *tag) { module *M; int c = 0; LOOP_OVER(M, module) { if ((M->origin_marker == over) && ((Str__eq(tag, TL_IS_420)) || (Str__eq(tag, M->module_tag)))) { if ((prefix) && ((c++ > 0) || (every_time))) WRITE("%S", prefix); if (matter) { TEMPORARY_TEXT(line); LOOP_THROUGH_TEXT(pos, matter) { if (Str__get(pos) == '\n') { if (as_lines) { Makefiles__scan_makefile_line(line, tfp, (void *) MS); Str__clear(line); } } else { if (Str__get(pos) == '@') { WRITE_TO(line, "%S", M->module_name); } else { PUT_TO(line, Str__get(pos)); } } } if (!as_lines) WRITE("%S", line); DISCARD_TEXT(line); } if (suffix) WRITE("%S", suffix); } } } #line 14 "inweb/Chapter 6/Git Support.w" void Git__write_gitignore(web *W, filename *prototype, filename *F) { gitignore_state MS; MS.for_web = W; MS.last_line_was_blank = TRUE; text_stream *OUT = &(MS.to_gitignore); if (STREAM_OPEN_TO_FILE(OUT, F, ISO_ENC) == FALSE) Errors__fatal_with_file("unable to write tangled file", F); WRITE("# This gitignore was automatically written by inweb -gitignore\n"); WRITE("# and is not intended for human editing\n\n"); TextFiles__read(prototype, FALSE, "can't open prototype file", TRUE, Git__copy_gitignore_line, NULL, &MS); STREAM_CLOSE(OUT); WRITE_TO(STDOUT, "Wrote gitignore file '%f' from script '%f'\n", F, prototype); } #line 31 "inweb/Chapter 6/Git Support.w" void Git__copy_gitignore_line(text_stream *line, text_file_position *tfp, void *X) { gitignore_state *MS = (gitignore_state *) X; text_stream *OUT = &(MS->to_gitignore); match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, line, L" *#%c*")) { Regexp__dispose_of(&mr); return; } if (Regexp__match(&mr, line, L" *{basics} *")) { #line 44 "inweb/Chapter 6/Git Support.w" filename *prototype = Filenames__in_folder(path_to_inweb_materials, TL_IS_421); TextFiles__read(prototype, FALSE, "can't open make settings file", TRUE, Git__copy_gitignore_line, NULL, MS); Regexp__dispose_of(&mr); return; } #line 37 "inweb/Chapter 6/Git Support.w" ; Regexp__dispose_of(&mr); { #line 52 "inweb/Chapter 6/Git Support.w" if (Str__len(line) == 0) { if (MS->last_line_was_blank == FALSE) WRITE("\n"); MS->last_line_was_blank = TRUE; } else { MS->last_line_was_blank = FALSE; WRITE("%S\n", line); } } #line 40 "inweb/Chapter 6/Git Support.w" ; } #line 18 "inweb/Chapter 6/Readme Writeme.w" void Readme__write(filename *from, filename *to) { WRITE_TO(STDOUT, "write-me: %f --> %f\n", from, to); write_state ws; ws.current_definition = NULL; ws.known_macros = NEW_LINKED_LIST(macro); macro *V = Readme__new_macro(TL_IS_422, NULL, NULL); ADD_TO_LINKED_LIST(V, macro, ws.known_macros); macro *P = Readme__new_macro(TL_IS_423, NULL, NULL); ADD_TO_LINKED_LIST(P, macro, ws.known_macros); macro *A = Readme__new_macro(TL_IS_424, NULL, NULL); ADD_TO_LINKED_LIST(A, macro, ws.known_macros); ws.stack_frame = NULL; text_stream file_to; if (Streams__open_to_file(&file_to, to, UTF8_ENC) == FALSE) Errors__fatal_with_file("can't write readme file", to); ws.OUT = &file_to; TextFiles__read(from, FALSE, "unable to read template file", TRUE, &Readme__write_helper, NULL, (void *) &ws); Streams__close(&file_to); } #line 44 "inweb/Chapter 6/Readme Writeme.w" void Readme__write_helper(text_stream *text, text_file_position *tfp, void *state) { write_state *ws = (write_state *) state; text_stream *OUT = ws->OUT; match_results mr = Regexp__create_mr(); if (Regexp__match(&mr, text, L" *@end *")) { if (ws->current_definition == NULL) Errors__in_text_file("@end without @define", tfp); else ws->current_definition = NULL; } else if (ws->current_definition) { if (Str__len(ws->current_definition->content) > 0) WRITE_TO(ws->current_definition->content, "\n"); WRITE_TO(ws->current_definition->content, "%S", text); } else if (Regexp__match(&mr, text, L" *@define (%i+)(%c*)")) { if (ws->current_definition) Errors__in_text_file("@define without @end", tfp); else { macro *M = Readme__new_macro(mr.exp[0], mr.exp[1], tfp); ws->current_definition = M; ADD_TO_LINKED_LIST(M, macro, ws->known_macros); } } else { Readme__expand_material(ws, OUT, text, tfp); Readme__expand_material(ws, OUT, TL_IS_425, tfp); } Regexp__dispose_of(&mr); } #line 82 "inweb/Chapter 6/Readme Writeme.w" macro *Readme__new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) { macro *M = CREATE(macro); M->name = Str__duplicate(name); M->tokens = Readme__parse_token_list(tokens, tfp); M->content = Str__new(); return M; } #line 98 "inweb/Chapter 6/Readme Writeme.w" #line 100 "inweb/Chapter 6/Readme Writeme.w" macro_tokens Readme__parse_token_list(text_stream *chunk, text_file_position *tfp) { macro_tokens mt; mt.no_pars = 0; mt.down = NULL; mt.bound_to = NULL; if (Str__get_first_char(chunk) == '(') { int x = 1, bl = 1, from = 1, quoted = FALSE; while ((bl > 0) && (Str__get_at(chunk, x) != 0)) { wchar_t c = Str__get_at(chunk, x); if (c == '\'') { quoted = quoted?FALSE:TRUE; } else if (quoted == FALSE) { if (c == '(') bl++; else if (c == ')') { bl--; if (bl == 0) { #line 129 "inweb/Chapter 6/Readme Writeme.w" int n = mt.no_pars; if (n >= 8) Errors__in_text_file("too many parameters", tfp); else { mt.pars[n] = Str__new(); for (int j=from; j= 8) Errors__in_text_file("too many parameters", tfp); else { mt.pars[n] = Str__new(); for (int j=from; jstack_frame; ws->stack_frame = &mt; Readme__expand_at(ws, OUT, mr.exp[1], tfp); ws->stack_frame = mt.down; Readme__expand_material(ws, OUT, mr.exp[2], tfp); } else { WRITE("%S", text); } Regexp__dispose_of(&mr); } #line 172 "inweb/Chapter 6/Readme Writeme.w" void Readme__expand_at(write_state *ws, text_stream *OUT, text_stream *macro_name, text_file_position *tfp) { macro_tokens *stack = ws->stack_frame; while (stack) { macro *in = stack->bound_to; if (in) for (int n = 0; n < in->tokens.no_pars; n++) if (Str__eq(in->tokens.pars[n], macro_name)) { if (n < stack->no_pars) { Readme__expand_material(ws, OUT, stack->pars[n], tfp); return; } } stack = stack->down; } macro *M; LOOP_OVER_LINKED_LIST(M, macro, ws->known_macros) if (Str__eq(M->name, macro_name)) { ws->stack_frame->bound_to = M; Readme__expand_macro(ws, OUT, M, tfp); return; } Errors__in_text_file("no such @-command", tfp); WRITE_TO(STDERR, "(command is '%S')\n", macro_name); } #line 204 "inweb/Chapter 6/Readme Writeme.w" void Readme__expand_macro(write_state *ws, text_stream *OUT, macro *M, text_file_position *tfp) { if (Str__eq(M->name, TL_IS_426)) { #line 215 "inweb/Chapter 6/Readme Writeme.w" if (ws->stack_frame->no_pars != 1) Errors__in_text_file("@version takes 1 parameter", tfp); else { TEMPORARY_TEXT(program); Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp); Readme__write_var(OUT, program, TL_IS_429); DISCARD_TEXT(program); } } #line 205 "inweb/Chapter 6/Readme Writeme.w" else if (Str__eq(M->name, TL_IS_427)) { #line 225 "inweb/Chapter 6/Readme Writeme.w" if (ws->stack_frame->no_pars != 1) Errors__in_text_file("@purpose takes 1 parameter", tfp); else { TEMPORARY_TEXT(program); Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp); Readme__write_var(OUT, program, TL_IS_430); DISCARD_TEXT(program); } } #line 206 "inweb/Chapter 6/Readme Writeme.w" else if (Str__eq(M->name, TL_IS_428)) { #line 235 "inweb/Chapter 6/Readme Writeme.w" if (ws->stack_frame->no_pars != 2) Errors__in_text_file("@var takes 2 parameters", tfp); else { TEMPORARY_TEXT(program); TEMPORARY_TEXT(bibv); Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp); Readme__expand_material(ws, bibv, ws->stack_frame->pars[1], tfp); Readme__write_var(OUT, program, bibv); DISCARD_TEXT(program); DISCARD_TEXT(bibv); } } #line 207 "inweb/Chapter 6/Readme Writeme.w" else { ws->stack_frame->bound_to = M; Readme__expand_material(ws, OUT, M->content, tfp); } } #line 262 "inweb/Chapter 6/Readme Writeme.w" void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) { writeme_asset *A = Readme__find_asset(program); if (A->if_web) WRITE("%S", Bibliographic__get_datum(A->if_web, datum)); else if (Str__eq(datum, TL_IS_431)) WRITE("%S", A->date); else if (Str__eq(datum, TL_IS_432)) WRITE("%S", A->version); } #line 273 "inweb/Chapter 6/Readme Writeme.w" writeme_asset *Readme__find_asset(text_stream *program) { writeme_asset *A; LOOP_OVER(A, writeme_asset) if (Str__eq(program, A->name)) return A; A = CREATE(writeme_asset); A->name = Str__duplicate(program); A->if_web = NULL; A->date = Str__new(); A->version = Str__new(); A->next_is_version = FALSE; { #line 287 "inweb/Chapter 6/Readme Writeme.w" if (Str__ends_with_wide_string(program, L".i7x")) { { #line 306 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(Filenames__from_text(program), FALSE, "unable to read extension", TRUE, &Readme__extension_harvester, NULL, A); } #line 288 "inweb/Chapter 6/Readme Writeme.w" ; } else { if (WebMetadata__directory_looks_like_a_web(Pathnames__from_text(program))) { A->if_web = WebMetadata__get_without_modules(Pathnames__from_text(program), NULL); } else { filename *I6_vn = Filenames__in_folder( Pathnames__subfolder(Pathnames__from_text(program), TL_IS_433), TL_IS_434); if (TextFiles__exists(I6_vn)) { #line 310 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(I6_vn, FALSE, "unable to read header file from I6 source", TRUE, &Readme__header_harvester, NULL, A); } #line 295 "inweb/Chapter 6/Readme Writeme.w" ; filename *template_vn = Filenames__in_folder(Pathnames__from_text(program), TL_IS_435); if (TextFiles__exists(template_vn)) { #line 314 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(template_vn, FALSE, "unable to read manifest file from website template", TRUE, &Readme__template_harvester, NULL, A); } #line 297 "inweb/Chapter 6/Readme Writeme.w" ; filename *rmt_vn = Filenames__in_folder(Pathnames__from_text(program), TL_IS_436); if (TextFiles__exists(rmt_vn)) { #line 318 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE, &Readme__readme_harvester, NULL, A); } #line 299 "inweb/Chapter 6/Readme Writeme.w" ; rmt_vn = Filenames__in_folder(Pathnames__from_text(program), TL_IS_437); if (TextFiles__exists(rmt_vn)) { #line 318 "inweb/Chapter 6/Readme Writeme.w" TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE, &Readme__readme_harvester, NULL, A); } #line 301 "inweb/Chapter 6/Readme Writeme.w" ; } } } #line 282 "inweb/Chapter 6/Readme Writeme.w" ; return A; } #line 324 "inweb/Chapter 6/Readme Writeme.w" void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); if (Str__len(text) == 0) return; if (Regexp__match(&mr, text, L" *Version (%c*?) of %c*begins here. *")) A->version = Str__duplicate(mr.exp[0]); Regexp__dispose_of(&mr); } #line 336 "inweb/Chapter 6/Readme Writeme.w" void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); if (Str__len(text) == 0) return; if (Regexp__match(&mr, text, L"#define RELEASE_NUMBER (%c*?) *")) A->version = Str__duplicate(mr.exp[0]); if (Regexp__match(&mr, text, L"#define RELEASE_DATE \"(%c*?)\" *")) A->date = Str__duplicate(mr.exp[0]); Regexp__dispose_of(&mr); } #line 350 "inweb/Chapter 6/Readme Writeme.w" void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); if (Str__len(text) == 0) return; if (Regexp__match(&mr, text, L"%[INTERPRETERVERSION%]")) { A->next_is_version = TRUE; } else if (A->next_is_version) { A->version = Str__duplicate(text); A->next_is_version = FALSE; } Regexp__dispose_of(&mr); } #line 366 "inweb/Chapter 6/Readme Writeme.w" void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) { writeme_asset *A = (writeme_asset *) state; match_results mr = Regexp__create_mr(); if (Str__len(text) == 0) return; if ((Regexp__match(&mr, text, L"CheapGlk Library: version (%c*?) *")) || (Regexp__match(&mr, text, L"- Version (%c*?) *"))) A->version = Str__duplicate(mr.exp[0]); Regexp__dispose_of(&mr); } void register_tangled_nonterminals(void) { } void register_tangled_text_literals(void) { TL_IS_0 = Str__literal(L"strings"); TL_IS_1 = Str__literal(L"Hello"); TL_IS_2 = Str__literal(L"debug-log.txt"); TL_IS_3 = Str__literal(L"Tangled"); TL_IS_4 = Str__literal(L"wayzgoose"); TL_IS_5 = Str__literal(L"snow goose"); TL_IS_6 = Str__literal(L"fish"); TL_IS_7 = Str__literal(L"ePub"); TL_IS_8 = Str__literal(L"OEBPS"); TL_IS_9 = Str__literal(L"mimetype"); TL_IS_10 = Str__literal(L"META-INF"); TL_IS_11 = Str__literal(L"container.xml"); TL_IS_12 = Str__literal(L"cover.html"); TL_IS_13 = Str__literal(L"Cover"); TL_IS_14 = Str__literal(L"cover"); TL_IS_15 = Str__literal(L"content.opf"); TL_IS_16 = Str__literal(L"toc.ncx"); TL_IS_17 = Str__literal(L".."); TL_IS_18 = Str__literal(L"A"); TL_IS_19 = Str__literal(L"Web Syntax Version: 1"); TL_IS_20 = Str__literal(L"Web Syntax Version: 2"); TL_IS_21 = Str__literal(L"S"); TL_IS_22 = Str__literal(L"Sections"); TL_IS_23 = Str__literal(L"All"); TL_IS_24 = Str__literal(L"Headers"); TL_IS_25 = Str__literal(L"Language"); TL_IS_26 = Str__literal(L"Language"); TL_IS_27 = Str__literal(L"Contents.w"); TL_IS_28 = Str__literal(L"Author"); TL_IS_29 = Str__literal(L"Language"); TL_IS_30 = Str__literal(L"Purpose"); TL_IS_31 = Str__literal(L"Title"); TL_IS_32 = Str__literal(L"License"); TL_IS_33 = Str__literal(L"Licence"); TL_IS_34 = Str__literal(L"Short Title"); TL_IS_35 = Str__literal(L"Capitalized Title"); TL_IS_36 = Str__literal(L"Build Date"); TL_IS_37 = Str__literal(L"Build Number"); TL_IS_38 = Str__literal(L"Prerelease"); TL_IS_39 = Str__literal(L"Semantic Version Number"); TL_IS_40 = Str__literal(L"Version Number"); TL_IS_41 = Str__literal(L"1"); TL_IS_42 = Str__literal(L"Version Name"); TL_IS_43 = Str__literal(L"Index Template"); TL_IS_44 = Str__literal(L"Preform Language"); TL_IS_45 = Str__literal(L"Declare Section Usage"); TL_IS_46 = Str__literal(L"Off"); TL_IS_47 = Str__literal(L"Namespaces"); TL_IS_48 = Str__literal(L"Off"); TL_IS_49 = Str__literal(L"Strict Usage Rules"); TL_IS_50 = Str__literal(L"Off"); TL_IS_51 = Str__literal(L"Web Syntax Version"); TL_IS_52 = Str__literal(L"Capitalized Title"); TL_IS_53 = Str__literal(L"miscellaneous"); TL_IS_54 = Str__literal(L"(main)"); TL_IS_55 = Str__literal(L"build.txt"); TL_IS_56 = Str__literal(L"build.txt"); TL_IS_57 = Str__literal(L"Prerelease"); TL_IS_58 = Str__literal(L"Build Number"); TL_IS_59 = Str__literal(L"Build Date"); TL_IS_60 = Str__literal(L"Semantic Version Number"); TL_IS_61 = Str__literal(L"Version Number"); TL_IS_62 = Str__literal(L"Prerelease"); TL_IS_63 = Str__literal(L"Build Number"); TL_IS_64 = Str__literal(L"Semantic Version Number"); TL_IS_65 = Str__literal(L"The compiler is not feeling well today."); TL_IS_66 = Str__literal(L"inweb"); TL_IS_67 = Str__literal(L"Patterns"); TL_IS_68 = Str__literal(L"Materials"); TL_IS_69 = Str__literal(L"makescript.txt"); TL_IS_70 = Str__literal(L"gitignorescript.txt"); TL_IS_71 = Str__literal(L"READMEscript.txt"); TL_IS_72 = Str__literal(L"Short Title"); TL_IS_73 = Str__literal(L"Short Title"); TL_IS_74 = Str__literal(L"Title"); TL_IS_75 = Str__literal(L"docs"); TL_IS_76 = Str__literal(L"Short Title"); TL_IS_77 = Str__literal(L"Short Title"); TL_IS_78 = Str__literal(L"Title"); TL_IS_79 = Str__literal(L"GitHubPages"); TL_IS_80 = Str__literal(L"0"); TL_IS_81 = Str__literal(L"for locating programming language definitions"); TL_IS_82 = Str__literal(L"for analysing a web"); TL_IS_83 = Str__literal(L"for weaving a web"); TL_IS_84 = Str__literal(L"for tangling a web"); TL_IS_85 = Str__literal(L".inweb"); TL_IS_86 = Str__literal(L"0"); TL_IS_87 = Str__literal(L"0"); TL_IS_88 = Str__literal(L"tex"); TL_IS_89 = Str__literal(L"pdftex"); TL_IS_90 = Str__literal(L"open"); TL_IS_91 = Str__literal(L"Patterns"); TL_IS_92 = Str__literal(L"pattern.txt"); TL_IS_93 = Str__literal(L"pattern.txt"); TL_IS_94 = Str__literal(L"format"); TL_IS_95 = Str__literal(L"abbrevs"); TL_IS_96 = Str__literal(L"numbered"); TL_IS_97 = Str__literal(L"default-range"); TL_IS_98 = Str__literal(L"tex-command"); TL_IS_99 = Str__literal(L"pdftex-command"); TL_IS_100 = Str__literal(L"open-command"); TL_IS_101 = Str__literal(L"Booklet Title"); TL_IS_102 = Str__literal(L"yes"); TL_IS_103 = Str__literal(L"no"); TL_IS_104 = Str__literal(L"../"); TL_IS_105 = Str__literal(L"Inweb Version"); TL_IS_106 = Str__literal(L"Language"); TL_IS_107 = Str__literal(L"Woven"); TL_IS_108 = Str__literal(L"Tangled"); TL_IS_109 = Str__literal(L"Title"); TL_IS_110 = Str__literal(L""); TL_IS_111 = Str__literal(L"="); TL_IS_112 = Str__literal(L"@"); TL_IS_113 = Str__literal(L"Figures"); TL_IS_114 = Str__literal(L"Figures"); TL_IS_115 = Str__literal(L"unknown [[command]]"); TL_IS_116 = Str__literal(L"<...> definition begins outside of a paragraph"); TL_IS_117 = Str__literal(L"(very early code)"); TL_IS_118 = Str__literal(L"(early code)"); TL_IS_119 = Str__literal(L"(not code)"); TL_IS_120 = Str__literal(L"unknown bracketed annotation"); TL_IS_121 = Str__literal(L"unknown material after '='"); TL_IS_122 = Str__literal(L"don't understand @command"); TL_IS_123 = Str__literal(L"Purpose used after bar"); TL_IS_124 = Str__literal(L"Interface used after bar"); TL_IS_125 = Str__literal(L"Definitions used after bar"); TL_IS_126 = Str__literal(L"second bar in the same section"); TL_IS_127 = Str__literal(L"enumeration constants can't supply a value"); TL_IS_128 = Str__literal(L"P"); TL_IS_129 = Str__literal(L"S"); TL_IS_130 = Str__literal(L"ifdef-"); TL_IS_131 = Str__literal(L"ifndef-"); TL_IS_132 = Str__literal(L"."); TL_IS_133 = Str__literal(L"This paragraph is used only if "); TL_IS_134 = Str__literal(L" and if "); TL_IS_135 = Str__literal(L" and "); TL_IS_136 = Str__literal(L" is"); TL_IS_137 = Str__literal(L" are"); TL_IS_138 = Str__literal(L" defined"); TL_IS_139 = Str__literal(L" undefined"); TL_IS_140 = Str__literal(L"enumeration constants must belong to a _FAMILY"); TL_IS_141 = Str__literal(L"this enumeration _FAMILY is unknown"); TL_IS_142 = Str__literal(L"this enumeration _FAMILY already exists"); TL_IS_143 = Str__literal(L"unrecognised interface line"); TL_IS_144 = Str__literal(L"makescript.txt"); TL_IS_145 = Str__literal(L"makescript.txt"); TL_IS_146 = Str__literal(L"gitignorescript.txt"); TL_IS_147 = Str__literal(L"gitignorescript.txt"); TL_IS_148 = Str__literal(L"cover-sheet"); TL_IS_149 = Str__literal(L"Version Number"); TL_IS_150 = Str__literal(L"Version Number"); TL_IS_151 = Str__literal(L" "); TL_IS_152 = Str__literal(L"chaptered-index.html"); TL_IS_153 = Str__literal(L"unchaptered-index.html"); TL_IS_154 = Str__literal(L"index.html"); TL_IS_155 = Str__literal(L"index.html"); TL_IS_156 = Str__literal(L"cover-sheet"); TL_IS_157 = Str__literal(L"nav.html"); TL_IS_158 = Str__literal(L"nav.html"); TL_IS_159 = Str__literal(L"Index"); TL_IS_160 = Str__literal(L"index"); TL_IS_161 = Str__literal(L"Purpose"); TL_IS_162 = Str__literal(L"Booklet Title"); TL_IS_163 = Str__literal(L"Booklet Title"); TL_IS_164 = Str__literal(L"Booklet Title"); TL_IS_165 = Str__literal(L"Booklet Title"); TL_IS_166 = Str__literal(L"Definitions"); TL_IS_167 = Str__literal(L""); TL_IS_168 = Str__literal(L""); TL_IS_169 = Str__literal(L""); TL_IS_170 = Str__literal(L""); TL_IS_171 = Str__literal(L"define"); TL_IS_172 = Str__literal(L"enum"); TL_IS_173 = Str__literal(L"weavesection"); TL_IS_174 = Str__literal(L"weavesections"); TL_IS_175 = Str__literal(L"weavesectionss"); TL_IS_176 = Str__literal(L"weavesectionsss"); TL_IS_177 = Str__literal(L"nsweavesection"); TL_IS_178 = Str__literal(L"nsweavesections"); TL_IS_179 = Str__literal(L"tweavesection"); TL_IS_180 = Str__literal(L"tweavesections"); TL_IS_181 = Str__literal(L"tweavesectionss"); TL_IS_182 = Str__literal(L"tweavesectionsss"); TL_IS_183 = Str__literal(L"Title"); TL_IS_184 = Str__literal(L"This code is "); TL_IS_185 = Str__literal(L"never used"); TL_IS_186 = Str__literal(L", "); TL_IS_187 = Str__literal(L" and "); TL_IS_188 = Str__literal(L"used in "); TL_IS_189 = Str__literal(L" (twice)"); TL_IS_190 = Str__literal(L" (three times)"); TL_IS_191 = Str__literal(L" (four times)"); TL_IS_192 = Str__literal(L" (five times)"); TL_IS_193 = Str__literal(L"."); TL_IS_194 = Str__literal(L"The function "); TL_IS_195 = Str__literal(L" appears nowhere else"); TL_IS_196 = Str__literal(L")"); TL_IS_197 = Str__literal(L"."); TL_IS_198 = Str__literal(L" is used in "); TL_IS_199 = Str__literal(L"), "); TL_IS_200 = Str__literal(L", "); TL_IS_201 = Str__literal(L" ("); TL_IS_202 = Str__literal(L", "); TL_IS_203 = Str__literal(L"The structure "); TL_IS_204 = Str__literal(L" is private to this section"); TL_IS_205 = Str__literal(L" is accessed in "); TL_IS_206 = Str__literal(L", "); TL_IS_207 = Str__literal(L" and here"); TL_IS_208 = Str__literal(L"."); TL_IS_209 = Str__literal(L""); TL_IS_210 = Str__literal(L""); TL_IS_211 = Str__literal(L""); TL_IS_212 = Str__literal(L""); TL_IS_213 = Str__literal(L""); TL_IS_214 = Str__literal(L"misplaced definition"); TL_IS_215 = Str__literal(L"unknown macro"); TL_IS_216 = Str__literal(L"C"); TL_IS_217 = Str__literal(L"Languages"); TL_IS_218 = Str__literal(L"InC"); TL_IS_219 = Str__literal(L"Name"); TL_IS_220 = Str__literal(L"Details"); TL_IS_221 = Str__literal(L"Extension"); TL_IS_222 = Str__literal(L"Line Comment"); TL_IS_223 = Str__literal(L"Whole Line Comment"); TL_IS_224 = Str__literal(L"Multiline Comment Open"); TL_IS_225 = Str__literal(L"Multiline Comment Close"); TL_IS_226 = Str__literal(L"String Literal"); TL_IS_227 = Str__literal(L"String Literal Escape"); TL_IS_228 = Str__literal(L"Character Literal"); TL_IS_229 = Str__literal(L"Character Literal Escape"); TL_IS_230 = Str__literal(L"Binary Literal Prefix"); TL_IS_231 = Str__literal(L"Octal Literal Prefix"); TL_IS_232 = Str__literal(L"Hexadecimal Literal Prefix"); TL_IS_233 = Str__literal(L"Negative Literal Prefix"); TL_IS_234 = Str__literal(L"Shebang"); TL_IS_235 = Str__literal(L"Line Marker"); TL_IS_236 = Str__literal(L"Before Named Paragraph Expansion"); TL_IS_237 = Str__literal(L"After Named Paragraph Expansion"); TL_IS_238 = Str__literal(L"Start Definition"); TL_IS_239 = Str__literal(L"Prolong Definition"); TL_IS_240 = Str__literal(L"End Definition"); TL_IS_241 = Str__literal(L"Start Ifdef"); TL_IS_242 = Str__literal(L"Start Ifndef"); TL_IS_243 = Str__literal(L"End Ifdef"); TL_IS_244 = Str__literal(L"End Ifndef"); TL_IS_245 = Str__literal(L"C-Like"); TL_IS_246 = Str__literal(L"Suppress Disclaimer"); TL_IS_247 = Str__literal(L"Supports Namespaces"); TL_IS_248 = Str__literal(L"}"); TL_IS_249 = Str__literal(L"unquoted"); TL_IS_250 = Str__literal(L"{"); TL_IS_251 = Str__literal(L"debug"); TL_IS_252 = Str__literal(L"!string"); TL_IS_253 = Str__literal(L"!function"); TL_IS_254 = Str__literal(L"!definition"); TL_IS_255 = Str__literal(L"!reserved"); TL_IS_256 = Str__literal(L"!element"); TL_IS_257 = Str__literal(L"!identifier"); TL_IS_258 = Str__literal(L"!character"); TL_IS_259 = Str__literal(L"!constant"); TL_IS_260 = Str__literal(L"!plain"); TL_IS_261 = Str__literal(L"!extract"); TL_IS_262 = Str__literal(L"!comment"); TL_IS_263 = Str__literal(L"true"); TL_IS_264 = Str__literal(L"false"); TL_IS_265 = Str__literal(L"Tangled output generated by inweb: do not edit"); TL_IS_266 = Str__literal(L"this programming language does not support @d"); TL_IS_267 = Str__literal(L"this programming language does not support multiline @d"); TL_IS_268 = Str__literal(L"program ended with conditional compilation open"); TL_IS_269 = Str__literal(L"conditional compilation too deeply nested"); TL_IS_270 = Str__literal(L"found #endif without #ifdef or #ifndef"); TL_IS_271 = Str__literal(L"Structures"); TL_IS_272 = Str__literal(L"Main::"); TL_IS_273 = Str__literal(L"Namespaces"); TL_IS_274 = Str__literal(L"Being internally called, this function mustn't belong to a :: namespace"); TL_IS_275 = Str__literal(L"Being externally called, this function must belong to a :: namespace"); TL_IS_276 = Str__literal(L"quartz"); TL_IS_277 = Str__literal(L"quartz"); TL_IS_278 = Str__literal(L"quartz"); TL_IS_279 = Str__literal(L"like this"); TL_IS_280 = Str__literal(L"most_recent_result"); TL_IS_281 = Str__literal(L"most_recent_result_p"); TL_IS_282 = Str__literal(L"Syntax.preform"); TL_IS_283 = Str__literal(L"Preform Language"); TL_IS_284 = Str__literal(L"Preform Language"); TL_IS_285 = Str__literal(L""); TL_IS_286 = Str__literal(L""); TL_IS_287 = Str__literal(L"plain"); TL_IS_288 = Str__literal(L".txt"); TL_IS_289 = Str__literal(L"TeX"); TL_IS_290 = Str__literal(L".tex"); TL_IS_291 = Str__literal(L"DVI"); TL_IS_292 = Str__literal(L".tex"); TL_IS_293 = Str__literal(L"PDF"); TL_IS_294 = Str__literal(L".tex"); TL_IS_295 = Str__literal(L"inweb-macros.tex"); TL_IS_296 = Str__literal(L"not"); TL_IS_297 = Str__literal(L"leq"); TL_IS_298 = Str__literal(L"geq"); TL_IS_299 = Str__literal(L"sim"); TL_IS_300 = Str__literal(L"hbox"); TL_IS_301 = Str__literal(L"left"); TL_IS_302 = Str__literal(L"right"); TL_IS_303 = Str__literal(L"Rightarrow"); TL_IS_304 = Str__literal(L"Leftrightarrow"); TL_IS_305 = Str__literal(L"to"); TL_IS_306 = Str__literal(L"rightarrow"); TL_IS_307 = Str__literal(L"longrightarrow"); TL_IS_308 = Str__literal(L"leftarrow"); TL_IS_309 = Str__literal(L"longleftarrow"); TL_IS_310 = Str__literal(L"lbrace"); TL_IS_311 = Str__literal(L"mid"); TL_IS_312 = Str__literal(L"rbrace"); TL_IS_313 = Str__literal(L"cdot"); TL_IS_314 = Str__literal(L"cdots"); TL_IS_315 = Str__literal(L"dots"); TL_IS_316 = Str__literal(L"times"); TL_IS_317 = Str__literal(L"quad"); TL_IS_318 = Str__literal(L"qquad"); TL_IS_319 = Str__literal(L"TeX"); TL_IS_320 = Str__literal(L"neq"); TL_IS_321 = Str__literal(L"noteq"); TL_IS_322 = Str__literal(L"ell"); TL_IS_323 = Str__literal(L"log"); TL_IS_324 = Str__literal(L"exp"); TL_IS_325 = Str__literal(L"sin"); TL_IS_326 = Str__literal(L"cos"); TL_IS_327 = Str__literal(L"tan"); TL_IS_328 = Str__literal(L"top"); TL_IS_329 = Str__literal(L"Alpha"); TL_IS_330 = Str__literal(L"Beta"); TL_IS_331 = Str__literal(L"Gamma"); TL_IS_332 = Str__literal(L"Delta"); TL_IS_333 = Str__literal(L"Epsilon"); TL_IS_334 = Str__literal(L"Zeta"); TL_IS_335 = Str__literal(L"Eta"); TL_IS_336 = Str__literal(L"Theta"); TL_IS_337 = Str__literal(L"Iota"); TL_IS_338 = Str__literal(L"Kappa"); TL_IS_339 = Str__literal(L"Lambda"); TL_IS_340 = Str__literal(L"Mu"); TL_IS_341 = Str__literal(L"Nu"); TL_IS_342 = Str__literal(L"Xi"); TL_IS_343 = Str__literal(L"Omicron"); TL_IS_344 = Str__literal(L"Pi"); TL_IS_345 = Str__literal(L"Rho"); TL_IS_346 = Str__literal(L"Varsigma"); TL_IS_347 = Str__literal(L"Sigma"); TL_IS_348 = Str__literal(L"Tau"); TL_IS_349 = Str__literal(L"Upsilon"); TL_IS_350 = Str__literal(L"Phi"); TL_IS_351 = Str__literal(L"Chi"); TL_IS_352 = Str__literal(L"Psi"); TL_IS_353 = Str__literal(L"Omega"); TL_IS_354 = Str__literal(L"alpha"); TL_IS_355 = Str__literal(L"beta"); TL_IS_356 = Str__literal(L"gamma"); TL_IS_357 = Str__literal(L"delta"); TL_IS_358 = Str__literal(L"epsilon"); TL_IS_359 = Str__literal(L"zeta"); TL_IS_360 = Str__literal(L"eta"); TL_IS_361 = Str__literal(L"theta"); TL_IS_362 = Str__literal(L"iota"); TL_IS_363 = Str__literal(L"kappa"); TL_IS_364 = Str__literal(L"lambda"); TL_IS_365 = Str__literal(L"mu"); TL_IS_366 = Str__literal(L"nu"); TL_IS_367 = Str__literal(L"xi"); TL_IS_368 = Str__literal(L"omicron"); TL_IS_369 = Str__literal(L"pi"); TL_IS_370 = Str__literal(L"rho"); TL_IS_371 = Str__literal(L"varsigma"); TL_IS_372 = Str__literal(L"sigma"); TL_IS_373 = Str__literal(L"tau"); TL_IS_374 = Str__literal(L"upsilon"); TL_IS_375 = Str__literal(L"phi"); TL_IS_376 = Str__literal(L"chi"); TL_IS_377 = Str__literal(L"psi"); TL_IS_378 = Str__literal(L"omega"); TL_IS_379 = Str__literal(L"exists"); TL_IS_380 = Str__literal(L"in"); TL_IS_381 = Str__literal(L"forall"); TL_IS_382 = Str__literal(L"cap"); TL_IS_383 = Str__literal(L"emptyset"); TL_IS_384 = Str__literal(L"subseteq"); TL_IS_385 = Str__literal(L"land"); TL_IS_386 = Str__literal(L"lor"); TL_IS_387 = Str__literal(L"lnot"); TL_IS_388 = Str__literal(L"sum"); TL_IS_389 = Str__literal(L"prod"); TL_IS_390 = Str__literal(L"exists"); TL_IS_391 = Str__literal(L"forall"); TL_IS_392 = Str__literal(L"HTML"); TL_IS_393 = Str__literal(L".html"); TL_IS_394 = Str__literal(L"ePub"); TL_IS_395 = Str__literal(L".html"); TL_IS_396 = Str__literal(L"template"); TL_IS_397 = Str__literal(L"inweb.css"); TL_IS_398 = Str__literal(L""); TL_IS_399 = Str__literal(L"template"); TL_IS_400 = Str__literal(L"crumbs.gif"); TL_IS_401 = Str__literal(L"Title"); TL_IS_402 = Str__literal(L"Short Title"); TL_IS_403 = Str__literal(L"Short Title"); TL_IS_404 = Str__literal(L"index.html"); TL_IS_405 = Str__literal(L"★"); TL_IS_406 = Str__literal(L"../webs.html"); TL_IS_407 = Str__literal(L"enum"); TL_IS_408 = Str__literal(L"Figures"); TL_IS_409 = Str__literal(L".txt"); TL_IS_410 = Str__literal(L""); TL_IS_411 = Str__literal(L""); TL_IS_412 = Str__literal(L"Booklet Title"); TL_IS_413 = Str__literal(L"template"); TL_IS_414 = Str__literal(L"Title"); TL_IS_415 = Str__literal(L"inweb.css"); TL_IS_416 = Str__literal(L" "); TL_IS_417 = Str__literal(L"all"); TL_IS_418 = Str__literal(L"platform-settings.mk"); TL_IS_419 = Str__literal(L"intest"); TL_IS_420 = Str__literal(L"all"); TL_IS_421 = Str__literal(L"gitignorescript.txt"); TL_IS_422 = Str__literal(L"version"); TL_IS_423 = Str__literal(L"purpose"); TL_IS_424 = Str__literal(L"var"); TL_IS_425 = Str__literal(L"\n"); TL_IS_426 = Str__literal(L"version"); TL_IS_427 = Str__literal(L"purpose"); TL_IS_428 = Str__literal(L"var"); TL_IS_429 = Str__literal(L"Version Number"); TL_IS_430 = Str__literal(L"Purpose"); TL_IS_431 = Str__literal(L"Build Date"); TL_IS_432 = Str__literal(L"Version Number"); TL_IS_433 = Str__literal(L"inform6"); TL_IS_434 = Str__literal(L"header.h"); TL_IS_435 = Str__literal(L"(manifest).txt"); TL_IS_436 = Str__literal(L"README.txt"); TL_IS_437 = Str__literal(L"README.md"); }