inweb-bootstrap/Tangled/inweb.c
2020-04-13 17:06:45 +01:00

26343 lines
908 KiB
C

#ifndef PLATFORM_WINDOWS
#define PLATFORM_POSIX
#endif
/* Tangled output generated by inweb: do not edit */
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#ifdef PLATFORM_POSIX
#include <errno.h>
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#include <limits.h>
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_WINDOWS
#include <errno.h>
#endif /* PLATFORM_WINDOWS */
#line 47 "inweb/foundation-module/Chapter 1/Foundation Module.w"
#include <wchar.h>
#ifdef PLATFORM_POSIX
#line 25 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <sys/stat.h>
#include <sys/types.h>
#line 28 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <dirent.h>
#include <pthread.h>
#line 31 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <unistd.h>
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_UNIX
#ifdef PLATFORM_POSIX
#line 49 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <strings.h>
#endif /* PLATFORM_UNIX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_LINUX
#ifdef PLATFORM_POSIX
#line 61 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <strings.h>
#endif /* PLATFORM_LINUX */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_ANDROID
#ifdef PLATFORM_POSIX
#line 71 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#include <strings.h>
#endif /* PLATFORM_ANDROID */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#line 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 <sys/stat.h>
#include <dirent.h>
#line 23 "inweb/foundation-module/Chapter 1/Windows Platform.w"
#include <io.h>
#include <windows.h>
#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 chapter_MT 33
#define colony_MT 34
#define colony_member_MT 35
#define colouring_language_block_MT 36
#define colouring_rule_MT 37
#define enumeration_set_MT 38
#define hash_table_entry_MT 39
#define hash_table_entry_usage_MT 40
#define language_function_MT 41
#define language_type_MT 42
#define macro_MT 43
#define macro_tokens_MT 44
#define macro_usage_MT 45
#define nonterminal_variable_MT 46
#define para_macro_MT 47
#define paragraph_MT 48
#define paragraph_tagging_MT 49
#define preform_nonterminal_MT 50
#define programming_language_MT 51
#define reserved_word_MT 52
#define section_MT 53
#define source_line_array_MT 54
#define structure_element_MT 55
#define tangle_target_MT 56
#define tex_results_MT 57
#define text_literal_MT 58
#define theme_tag_MT 59
#define weave_format_MT 60
#define weave_pattern_MT 61
#define weave_plugin_MT 62
#define weave_target_MT 63
#define web_MT 64
#define writeme_asset_MT 65
#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 TEST_LANGUAGE_CLSW 11
#define TEST_LANGUAGE_ON_CLSW 12
#define ANALYSIS_CLSG 3
#define CATALOGUE_CLSW 13
#define FUNCTIONS_CLSW 14
#define STRUCTURES_CLSW 15
#define ADVANCE_CLSW 16
#define GITIGNORE_CLSW 17
#define MAKEFILE_CLSW 18
#define WRITEME_CLSW 19
#define ADVANCE_FILE_CLSW 20
#define PROTOTYPE_CLSW 21
#define SCAN_CLSW 22
#define WEAVING_CLSG 4
#define WEAVE_CLSW 23
#define WEAVE_INTO_CLSW 24
#define WEAVE_TO_CLSW 25
#define OPEN_CLSW 26
#define WEAVE_AS_CLSW 27
#define WEAVE_TAG_CLSW 28
#define BREADCRUMB_CLSW 29
#define NAVIGATION_CLSW 30
#define TANGLING_CLSG 5
#define TANGLE_CLSW 31
#define TANGLE_TO_CLSW 32
#define COLONIAL_CLSG 6
#define COLONY_CLSW 33
#define MEMBER_CLSW 34
#define LOOP_WITHIN_TANGLE(C, S, T)\
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)\
LOOP_OVER_LINKED_LIST(S, section, C->sections)\
if (S->sect_target == T)\
for (source_line *L = S->first_line; L; L = L->next_line)
#define NO_LCAT 0
#define BAR_LCAT 1
#define BEGIN_CODE_LCAT 2
#define BEGIN_DEFINITION_LCAT 3
#define C_LIBRARY_INCLUDE_LCAT 4
#define CHAPTER_HEADING_LCAT 5
#define CODE_BODY_LCAT 6
#define COMMAND_LCAT 7
#define COMMENT_BODY_LCAT 8
#define CONT_DEFINITION_LCAT 9
#define DEFINITIONS_LCAT 10
#define END_EXTRACT_LCAT 11
#define HEADING_START_LCAT 12
#define INTERFACE_BODY_LCAT 13
#define INTERFACE_LCAT 14
#define MACRO_DEFINITION_LCAT 15
#define PARAGRAPH_START_LCAT 16
#define PREFORM_GRAMMAR_LCAT 17
#define PREFORM_LCAT 18
#define PURPOSE_BODY_LCAT 19
#define PURPOSE_LCAT 20
#define SECTION_HEADING_LCAT 21
#define SOURCE_DISPLAY_LCAT 22
#define TEXT_EXTRACT_LCAT 23
#define TYPEDEF_LCAT 24
#define NO_CMD 0
#define PAGEBREAK_CMD 1
#define GRAMMAR_INDEX_CMD 2
#define FIGURE_CMD 3
#define EMBED_CMD 4
#define TAG_CMD 5
#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 8192 /* 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 CHARACTERS_IN_CRULE_RUN -3 /* This block applies to each character from a set in turn */
#define INSTANCES_CRULE_RUN -4 /* This block applies to each instance in turn */
#define MATCHES_CRULE_RUN -5 /* This block applies to each match against a regexp in turn */
#define BRACKETS_CRULE_RUN -6 /* This block applies to bracketed subexpressions in a regexp */
#define NOT_A_RULE_PREFIX 1 /* this isn't a prefix rule */
#define UNSPACED_RULE_PREFIX 2 /* for |prefix P| */
#define SPACED_RULE_PREFIX 3 /* for |spaced prefix P| */
#define OPTIONALLY_SPACED_RULE_PREFIX 4 /* for |optionally spaced prefix P| */
#define UNSPACED_RULE_SUFFIX 5 /* for |suffix P| */
#define SPACED_RULE_SUFFIX 6 /* for |spaced suffix P| */
#define OPTIONALLY_SPACED_RULE_SUFFIX 7 /* for |optionally spaced suffix P| */
#define MAX_ILDF_REGEXP_LENGTH 64
#define DEFINITION_COLOUR 'd'
#define FUNCTION_COLOUR 'f'
#define RESERVED_COLOUR 'r'
#define ELEMENT_COLOUR 'e'
#define IDENTIFIER_COLOUR 'i'
#define CHAR_LITERAL_COLOUR 'c'
#define CONSTANT_COLOUR 'n'
#define STRING_COLOUR 's'
#define PLAIN_COLOUR 'p'
#define EXTRACT_COLOUR 'x'
#define COMMENT_COLOUR '!'
#define NEWLINE_COLOUR '\n'
#define NOT_A_COLOUR ' '
#define UNQUOTED_COLOUR '_'
#define PARSE_TYPES_PAR_MTID 2
#define PARSE_FUNCTIONS_PAR_MTID 3
#define FURTHER_PARSING_PAR_MTID 4
#define SUBCATEGORISE_LINE_PAR_MTID 5
#define PARSE_COMMENT_TAN_MTID 6
#define SHEBANG_TAN_MTID 7
#define SUPPRESS_DISCLAIMER_TAN_MTID 8
#define ADDITIONAL_EARLY_MATTER_TAN_MTID 9
#define START_DEFN_TAN_MTID 10
#define PROLONG_DEFN_TAN_MTID 11
#define END_DEFN_TAN_MTID 12
#define ADDITIONAL_PREDECLARATIONS_TAN_MTID 13
#define SUPPRESS_EXPANSION_TAN_MTID 14
#define TANGLE_COMMAND_TAN_MTID 15
#define WILL_TANGLE_EXTRA_LINE_TAN_MTID 16
#define TANGLE_EXTRA_LINE_TAN_MTID 17
#define INSERT_LINE_MARKER_TAN_MTID 18
#define BEFORE_MACRO_EXPANSION_TAN_MTID 19
#define AFTER_MACRO_EXPANSION_TAN_MTID 20
#define OPEN_IFDEF_TAN_MTID 21
#define CLOSE_IFDEF_TAN_MTID 22
#define COMMENT_TAN_MTID 23
#define TANGLE_CODE_UNUSUALLY_TAN_MTID 24
#define GNABEHS_TAN_MTID 25
#define ADDITIONAL_TANGLING_TAN_MTID 26
#define BEGIN_WEAVE_WEA_MTID 27
#define SKIP_IN_WEAVING_WEA_MTID 28
#define RESET_SYNTAX_COLOURING_WEA_MTID 29
#define SYNTAX_COLOUR_WEA_MTID 30
#define WEAVE_CODE_LINE_WEA_MTID 31
#define NOTIFY_NEW_TAG_WEA_MTID 32
#define EARLY_PREWEAVE_ANALYSIS_ANA_MTID 33
#define LATE_PREWEAVE_ANALYSIS_ANA_MTID 34
#define SHARE_ELEMENT_ANA_MTID 35
#define UNSPACED_RULE_PREFIX 2 /* for |prefix P| */
#define SPACED_RULE_PREFIX 3 /* for |spaced prefix P| */
#define OPTIONALLY_SPACED_RULE_PREFIX 4 /* for |optionally spaced prefix P| */
#define UNSPACED_RULE_SUFFIX 5 /* for |suffix P| */
#define SPACED_RULE_SUFFIX 6 /* for |spaced suffix P| */
#define OPTIONALLY_SPACED_RULE_SUFFIX 7 /* for |optionally spaced suffix P| */
#define MAX_CONDITIONAL_COMPILATION_STACK 8
#define MAX_ARG_LINES 32 /* maximum number of lines over which a function's header can extend */
#define NOT_A_NONTERMINAL -4
#define A_FLEXIBLE_NONTERMINAL -3
#define A_VORACIOUS_NONTERMINAL -2
#define A_GRAMMAR_NONTERMINAL -1
#define INFINITE_WORD_COUNT 1000000000
#define BEGIN_WEAVING_FOR_MTID 36
#define END_WEAVING_FOR_MTID 37
#define TOP_FOR_MTID 38
#define TOC_FOR_MTID 39
#define CHAPTER_TP_FOR_MTID 40
#define SUBHEADING_FOR_MTID 41
#define PARAGRAPH_HEADING_FOR_MTID 42
#define SOURCE_CODE_FOR_MTID 43
#define INLINE_CODE_FOR_MTID 44
#define URL_FOR_MTID 45
#define FOOTNOTE_CUE_FOR_MTID 46
#define BEGIN_FOOTNOTE_TEXT_FOR_MTID 47
#define END_FOOTNOTE_TEXT_FOR_MTID 48
#define DISPLAY_LINE_FOR_MTID 49
#define ITEM_FOR_MTID 50
#define BAR_FOR_MTID 51
#define FIGURE_FOR_MTID 52
#define EMBED_FOR_MTID 53
#define PARA_MACRO_FOR_MTID 54
#define PAGEBREAK_FOR_MTID 55
#define BLANK_LINE_FOR_MTID 56
#define AFTER_DEFINITIONS_FOR_MTID 57
#define CHANGE_MATERIAL_FOR_MTID 58
#define CHANGE_COLOUR_FOR_MTID 59
#define COMMENTARY_TEXT_FOR_MTID 60
#define PRESERVE_MATH_MODE_FOR_MTID 61
#define PREFORM_DOCUMENT_FOR_MTID 62
#define ENDNOTE_FOR_MTID 63
#define LOCALE_FOR_MTID 64
#define TAIL_FOR_MTID 65
#define POST_PROCESS_POS_MTID 66
#define POST_PROCESS_REPORT_POS_MTID 67
#define INDEX_PDFS_POS_MTID 68
#define POST_PROCESS_SUBSTITUTE_POS_MTID 69
#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 35
#define NO_DEFINED_DA_VALUES 4
#define NO_DEFINED_MT_VALUES 66
#define NO_DEFINED_MREASON_VALUES 5
#define NO_DEFINED_MTID_VALUES 69
#define NO_DEFINED_CLSF_VALUES 5
#define NO_DEFINED_CLSG_VALUES 7
#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 25
#define NO_DEFINED_CMD_VALUES 6
#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];
int exp_at[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 *ch_basic_title; /* e.g., "Chapter 3" */
struct text_stream *ch_decorated_title; /* e.g., "Fresh Water Fish" */
struct text_stream *rubric; /* optional; without double-quotation marks */
struct text_stream *ch_language_name; /* in which most of the sections are written */
int imported; /* from a different web? */
struct linked_list *sections_md; /* of |section_md| */
MEMORY_MANAGEMENT
} chapter_md;
#line 68 "inweb/foundation-module/Chapter 8/Web Structure.w"
typedef struct section_md {
struct text_stream *sect_title; /* e.g., "Program Control" */
struct text_stream *sect_range; /* e.g., "2/ct" */
int using_syntax; /* which syntax the web is written in */
int is_a_singleton; /* is this the only section in its entire web? */
struct filename *source_file_for_section;
struct text_stream *tag_name;
struct text_stream *sect_independent_language;
struct text_stream *sect_language_name;
struct text_stream *titling_line_to_insert;
MEMORY_MANAGEMENT
} section_md;
#line 244 "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 *chapters_md; /* of |chapter_md|: just the ones in this module */
struct linked_list *sections_md; /* of |section_md|: just the ones in this module */
MEMORY_MANAGEMENT
} module;
#line 73 "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_pattern; /* |-weave-as X|: for example, |-weave-to HTML| */
int show_languages_switch; /* |-show-languages|: print list of available PLs */
int catalogue_switch; /* |-catalogue|: print catalogue of sections */
int functions_switch; /* |-functions|: print catalogue of functions within sections */
int structures_switch; /* |-structures|: print catalogue of structures within sections */
int advance_switch; /* |-advance-build|: advance build file for web */
int 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 filename *colony_setting; /* |-colony X|: the filename X, if supplied */
struct text_stream *member_setting; /* |-member X|: sets web to member X of colony */
struct linked_list *breadcrumb_setting; /* of |breadcrumb_request| */
int verbose_switch; /* |-verbose|: print names of files read to stdout */
int targets; /* used only for parsing */
struct programming_language *test_language_setting; /* |-test-language X| */
struct filename *test_language_on_setting; /* |-test-language-on X| */
struct pathname *import_setting; /* |-import X|: where to find imported webs */
} inweb_instructions;
#line 11 "inweb/Chapter 1/Patterns.w"
typedef struct weave_pattern {
struct text_stream *pattern_name; /* such as |HTML| */
struct pathname *pattern_location; /* the directory */
struct weave_pattern *based_on; /* inherit from which other pattern? */
struct weave_format *pattern_format; /* such as |DVI|: the desired final format */
struct linked_list *plugins; /* of |weave_plugin|: any extras needed */
struct linked_list *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 web_extent; /* total lines in literate source, excluding contents */
int no_paragraphs; /* this will be at least 1 */
struct programming_language *main_language; /* in which most of the sections are written */
struct linked_list *tangle_targets; /* of |tangle_target| */
struct linked_list *headers; /* of |filename|: additional header files */
int analysed; /* has this been scanned for function usage and such? */
struct linked_list *language_types; /* of |language_type|: used only for C-like languages */
struct ebook *as_ebook; /* when being woven to an ebook */
struct pathname *redirect_weaves_to; /* ditto */
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" */
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 248 "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 377 "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 */
int plainer; /* used only for |BEGIN_CODE_LCAT| lines: suppresses box */
int enable_hyperlinks; /* used only for |CODE_BODY_LCAT| lines: link URLs in weave */
struct programming_language *colour_as; /* used only for |TEXT_EXTRACT_LCAT| lines */
int is_commentary; /* flag */
struct language_function *function_defined; /* if any C-like function is defined on this line */
struct preform_nonterminal *preform_nonterminal_defined; /* similarly */
int suppress_tangling; /* if e.g., lines are tangled out of order */
int interface_line_identified; /* only relevant during parsing of Interface lines */
struct 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 634 "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 |language_type|: 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 256 "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| */
struct source_line *definition_line; /* or null, if it's not a constant, function or type name */
struct language_function *as_function; /* for function names only */
MEMORY_MANAGEMENT
} hash_table_entry;
#line 354 "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 */
struct linked_list *breadcrumbs; /* non-standard breadcrumb trail, if any */
struct filename *navigation; /* navigation links, or |NULL| if not supplied */
struct linked_list *plugins; /* of |weave_plugin|: these are for HTML extensions */
/* used for workspace during an actual weave: */
struct source_line *current_weave_line;
struct linked_list *footnotes_cued; /* of |text_stream| */
struct linked_list *footnotes_written; /* of |text_stream| */
struct text_stream *current_footnote;
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 175 "inweb/Chapter 3/The Indexer.w"
typedef struct contents_processor {
text_stream *leafname;
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 inside_navigation_submenu;
} contents_processor;
#line 87 "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 102 "inweb/Chapter 4/Programming Languages.w"
typedef struct programming_language {
text_stream *language_name; /* identifies it: see above */
/* then a great many fields set directly in the definition file: */
text_stream *file_extension; /* by default output to a file whose name has this extension */
text_stream *language_details; /* brief explanation of what language is */
int supports_namespaces;
text_stream *line_comment;
text_stream *whole_line_comment;
text_stream *multiline_comment_open;
text_stream *multiline_comment_close;
text_stream *string_literal;
text_stream *string_literal_escape;
text_stream *character_literal;
text_stream *character_literal_escape;
text_stream *binary_literal_prefix;
text_stream *octal_literal_prefix;
text_stream *hexadecimal_literal_prefix;
text_stream *negative_literal_prefix;
text_stream *shebang;
text_stream *line_marker;
text_stream *before_macro_expansion;
text_stream *after_macro_expansion;
text_stream *start_definition;
text_stream *prolong_definition;
text_stream *end_definition;
text_stream *start_ifdef;
text_stream *end_ifdef;
text_stream *start_ifndef;
text_stream *end_ifndef;
wchar_t type_notation[MAX_ILDF_REGEXP_LENGTH];
wchar_t function_notation[MAX_ILDF_REGEXP_LENGTH];
int suppress_disclaimer;
int C_like; /* languages with this set have access to extra features */
struct linked_list *reserved_words; /* of |reserved_word| */
struct hash_table built_in_keywords;
struct colouring_language_block *program; /* algorithm for syntax colouring */
METHOD_CALLS
MEMORY_MANAGEMENT
} programming_language;
#line 152 "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 390 "inweb/Chapter 4/Programming Languages.w"
typedef struct colouring_language_block {
struct linked_list *rules; /* of |colouring_rule| */
struct colouring_language_block *parent; /* or |NULL| for the topmost one */
int run; /* one of the |*_CRULE_RUN| values, or else a colour */
struct text_stream *run_instance; /* used only for |INSTANCES_CRULE_RUN| */
struct text_stream *char_set; /* used only for |CHARACTERS_IN_CRULE_RUN| */
wchar_t match_regexp_text[MAX_ILDF_REGEXP_LENGTH]; /* used for |MATCHES_CRULE_RUN|, |BRACKETS_CRULE_RUN| */
/* workspace during painting */
struct match_results mr; /* of a regular expression */
MEMORY_MANAGEMENT
} colouring_language_block;
#line 434 "inweb/Chapter 4/Programming Languages.w"
typedef struct colouring_rule {
/* the premiss: */
int sense; /* |FALSE| to negate the condition */
int match_colour; /* for |coloured 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 */
wchar_t match_regexp_text[MAX_ILDF_REGEXP_LENGTH];
int number; /* for |number N| rules; 0 for others */
int number_of; /* for |number N of M| rules; 0 for others */
/* the conclusion: */
struct colouring_language_block *execute_block; /* or |NULL|, in which case... */
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 */
struct match_results mr; /* of a regular expression */
MEMORY_MANAGEMENT
} colouring_rule;
#line 556 "inweb/Chapter 4/Programming Languages.w"
typedef struct reserved_word {
struct text_stream *word;
int colour;
MEMORY_MANAGEMENT
} reserved_word;
#line 8 "inweb/Chapter 4/Types and Functions.w"
typedef struct language_type {
struct text_stream *structure_name;
int tangled; /* whether the structure definition has been tangled out */
struct source_line *structure_header_at; /* opening line of |typedef| */
struct source_line *typedef_ends; /* closing line, where |}| appears */
struct linked_list *incorporates; /* of |language_type| */
struct linked_list *elements; /* of |structure_element| */
struct language_type *next_cst_alphabetically;
MEMORY_MANAGEMENT
} language_type;
#line 78 "inweb/Chapter 4/Types and Functions.w"
typedef struct structure_element {
struct text_stream *element_name;
struct source_line *element_created_at;
int allow_sharing;
MEMORY_MANAGEMENT
} structure_element;
#line 112 "inweb/Chapter 4/Types and Functions.w"
typedef struct language_function {
struct text_stream *function_name; /* e.g., |"cultivate"| */
struct text_stream *function_type; /* e.g., |"tree *"| */
struct text_stream *function_arguments; /* e.g., |"int rainfall)"|: note |)| */
struct source_line *function_header_at; /* where the first line of the header begins */
int within_namespace; /* written using InC namespace dividers */
int called_from_other_sections;
int call_freely;
int usage_described;
int no_conditionals;
struct source_line *within_conditionals[MAX_CONDITIONAL_COMPILATION_STACK];
MEMORY_MANAGEMENT
} language_function;
#line 104 "inweb/Chapter 4/InC Support.w"
typedef struct preform_nonterminal {
struct text_stream *nt_name; /* e.g., |<action-clause>| */
struct text_stream *unangled_name; /* e.g., |action-clause| */
struct text_stream *as_C_identifier; /* e.g., |action_clause_NTM| */
int as_function; /* defined internally, that is, parsed by a C language_function */
int voracious; /* a voracious nonterminal: see "The English Syntax of Inform" */
int min_word_count; /* for internals only */
int max_word_count;
int takes_pointer_result; /* right-hand formula defines |*XP|, not |*X| */
struct source_line *where_defined;
struct preform_nonterminal *next_pnt_alphabetically;
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/Format Methods.w"
typedef struct weave_format {
struct text_stream *format_name;
struct text_stream *woven_extension;
METHOD_CALLS
MEMORY_MANAGEMENT
} weave_format;
#line 13 "inweb/Chapter 5/Weave Plugins.w"
typedef struct weave_plugin {
struct text_stream *plugin_name;
MEMORY_MANAGEMENT
} weave_plugin;
#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;
#line 21 "inweb/Chapter 6/Colonies.w"
typedef struct colony {
struct linked_list *members; /* of |colony_member| */
MEMORY_MANAGEMENT
} colony;
#line 36 "inweb/Chapter 6/Colonies.w"
typedef struct colony_member {
int web_rather_than_module; /* |TRUE| for a web, |FALSE| for a module */
struct text_stream *name; /* the |N| in |N at P in W| */
struct text_stream *path; /* the |P| in |N at P in W| */
struct pathname *weave_path; /* the |W| in |N at P in W| */
struct text_stream *home_leaf; /* usually |index.html|, but not for single-file webs */
struct text_stream *default_weave_pattern; /* for use when weaving */
struct web_md *loaded; /* metadata on its sections, lazily evaluated */
struct filename *navigation; /* navigation sidebar HTML */
struct linked_list *breadcrumb_tail; /* of |breadcrumb_request| */
MEMORY_MANAGEMENT
} colony_member;
#line 56 "inweb/Chapter 6/Colonies.w"
typedef struct colony_reader_state {
struct colony *province;
struct filename *nav;
struct linked_list *crumbs; /* of |breadcrumb_request| */
struct text_stream *pattern;
} colony_reader_state;
#line 148 "inweb/Chapter 6/Colonies.w"
typedef struct breadcrumb_request {
struct text_stream *breadcrumb_text;
struct text_stream *breadcrumb_link;
MEMORY_MANAGEMENT
} breadcrumb_request;
typedef long int pointer_sized_int;
typedef void (*writer_function)(text_stream *, char *, void *);
typedef void (*writer_function_I)(text_stream *, char *, int);
typedef void (*log_function)(text_stream *, void *);
typedef void (*log_function_I)(text_stream *, int);
typedef char string[MAX_STRING_LENGTH+1];
#line 88 "inweb/foundation-module/Chapter 1/Foundation Module.w"
void Foundation__start(void) ;
#line 167 "inweb/foundation-module/Chapter 1/Foundation Module.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 205 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__relative_URL(OUTPUT_STREAM, pathname *from, pathname *to) ;
#line 241 "inweb/foundation-module/Chapter 3/Pathnames.w"
int Pathnames__create_in_file_system(pathname *P) ;
#line 259 "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 211 "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 231 "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 571 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__includes_at(text_stream *line, int i, text_stream *pattern) ;
#line 594 "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 144 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
match_results Regexp__create_mr(void) ;
#line 154 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
void Regexp__dispose_of(match_results *mr) ;
#line 168 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match(match_results *mr, text_stream *text, wchar_t *pattern) ;
#line 175 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match_from(match_results *mr, text_stream *text, wchar_t *pattern, int x, int allow_partial) ;
#line 191 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
void Regexp__prepare(match_results *mr) ;
#line 207 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match_r(match_results *mr, text_stream *text, wchar_t *pattern, match_position *scan_from, int allow_partial) ;
#line 337 "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 367 "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 414 "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 90 "inweb/foundation-module/Chapter 8/Web Structure.w"
web_md * WebMetadata__get_without_modules(pathname *P, filename *alt_F) ;
#line 94 "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 265 "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 320 "inweb/foundation-module/Chapter 8/Web Structure.w"
void WebMetadata__read_contents_line(text_stream *line, text_file_position *tfp, void *X) ;
#line 657 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__directory_looks_like_a_web(pathname *P) ;
#line 661 "inweb/foundation-module/Chapter 8/Web Structure.w"
filename * WebMetadata__contents_filename(pathname *P) ;
#line 668 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__chapter_count(web_md *Wm) ;
#line 674 "inweb/foundation-module/Chapter 8/Web Structure.w"
int WebMetadata__section_count(web_md *Wm) ;
#line 29 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
int Bibliographic__datum_can_be_declared(web_md *Wm, text_stream *key) ;
#line 35 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
int Bibliographic__datum_on_or_off(web_md *Wm, text_stream *key) ;
#line 45 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
void Bibliographic__initialise_data(web_md *Wm) ;
#line 86 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
void Bibliographic__check_required_data(web_md *Wm) ;
#line 99 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
text_stream * Bibliographic__get_datum(web_md *Wm, text_stream *key) ;
#line 105 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
int Bibliographic__data_exists(web_md *Wm, text_stream *key) ;
#line 111 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
web_bibliographic_datum * Bibliographic__look_up_datum(web_md *Wm, text_stream *key) ;
#line 126 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
web_bibliographic_datum * Bibliographic__set_datum(web_md *Wm, text_stream *key, text_stream *val) ;
#line 31 "inweb/foundation-module/Chapter 8/Web Modules.w"
module * WebModules__new(text_stream *name, pathname *at, int m) ;
#line 52 "inweb/foundation-module/Chapter 8/Web Modules.w"
module * WebModules__create_main_module(web_md *WS) ;
#line 63 "inweb/foundation-module/Chapter 8/Web Modules.w"
void WebModules__dependency(module *A, module *B) ;
#line 79 "inweb/foundation-module/Chapter 8/Web Modules.w"
module_search * WebModules__make_search_path(pathname *ext_path) ;
#line 89 "inweb/foundation-module/Chapter 8/Web Modules.w"
module * WebModules__find(web_md *WS, module_search *ms, text_stream *name, pathname *X) ;
#line 118 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__exists(pathname *P) ;
#line 141 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__named_reference(module **return_M, section_md **return_Sm, int *named_as_module, text_stream *title, module *from_M, text_stream *text, int list) ;
#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 275 "inweb/Chapter 1/Program Control.w"
void Main__error_in_web(text_stream *message, source_line *sl) ;
#line 57 "inweb/Chapter 1/Configuration.w"
inweb_instructions Configuration__read(int argc, char **argv) ;
#line 258 "inweb/Chapter 1/Configuration.w"
void Configuration__switch(int id, int val, text_stream *arg, void *state) ;
#line 388 "inweb/Chapter 1/Configuration.w"
void Configuration__bareword(int id, text_stream *opt, void *state) ;
#line 403 "inweb/Chapter 1/Configuration.w"
void Configuration__set_range(inweb_instructions *args, text_stream *opt) ;
#line 435 "inweb/Chapter 1/Configuration.w"
void Configuration__set_fundamental_mode(inweb_instructions *args, int new_material) ;
#line 38 "inweb/Chapter 1/Patterns.w"
weave_pattern * Patterns__find(web *W, text_stream *name) ;
#line 89 "inweb/Chapter 1/Patterns.w"
void Patterns__scan_pattern_line(text_stream *line, text_file_position *tfp, void *X) ;
#line 169 "inweb/Chapter 1/Patterns.w"
int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) ;
#line 187 "inweb/Chapter 1/Patterns.w"
filename * Patterns__obtain_filename(weave_pattern *pattern, text_stream *leafname) ;
#line 203 "inweb/Chapter 1/Patterns.w"
void Patterns__copy_payloads_into_weave(web *W, weave_pattern *pattern) ;
#line 224 "inweb/Chapter 1/Patterns.w"
void Patterns__copy_file_into_weave(web *W, filename *F) ;
#line 229 "inweb/Chapter 1/Patterns.w"
void Patterns__copy_up_file_into_weave(web *W, filename *F) ;
#line 97 "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 103 "inweb/Chapter 2/The Reader.w"
web * Reader__load_web(pathname *P, filename *alt_F, module_search *I, int verbosely, int including_modules) ;
#line 205 "inweb/Chapter 2/The Reader.w"
void Reader__read_web(web *W, int verbosely) ;
#line 219 "inweb/Chapter 2/The Reader.w"
void Reader__read_file(web *W, chapter *C, filename *F, text_stream *titling_line, section *S, int verbosely, int disregard_top) ;
#line 262 "inweb/Chapter 2/The Reader.w"
void Reader__scan_source_line(text_stream *line, text_file_position *tfp, void *state) ;
#line 289 "inweb/Chapter 2/The Reader.w"
pathname * Reader__woven_folder(web *W) ;
#line 295 "inweb/Chapter 2/The Reader.w"
pathname * Reader__tangled_folder(web *W) ;
#line 310 "inweb/Chapter 2/The Reader.w"
chapter * Reader__get_chapter_for_range(web *W, text_stream *range) ;
#line 319 "inweb/Chapter 2/The Reader.w"
section * Reader__get_section_for_range(web *W, text_stream *range) ;
#line 333 "inweb/Chapter 2/The Reader.w"
section * Reader__section_by_filename(web *W, text_stream *filename) ;
#line 355 "inweb/Chapter 2/The Reader.w"
int Reader__range_within(text_stream *range1, text_stream *range2) ;
#line 384 "inweb/Chapter 2/The Reader.w"
tangle_target * Reader__add_tangle_target(web *W, programming_language *language) ;
#line 408 "inweb/Chapter 2/The Reader.w"
void Reader__add_imported_header(web *W, filename *HF) ;
#line 415 "inweb/Chapter 2/The Reader.w"
int Reader__web_has_one_section(web *W) ;
#line 423 "inweb/Chapter 2/The Reader.w"
void Reader__print_web_statistics(web *W) ;
#line 45 "inweb/Chapter 2/Line Categories.w"
source_line * Lines__new_source_line_in(text_stream *line, text_file_position *tfp, section *S) ;
#line 113 "inweb/Chapter 2/Line Categories.w"
char * Lines__category_name(int cat) ;
#line 17 "inweb/Chapter 2/The Parser.w"
void Parser__parse_web(web *W, int inweb_mode) ;
#line 723 "inweb/Chapter 2/The Parser.w"
text_stream * Parser__extract_purpose(text_stream *prologue, source_line *XL, section *S, source_line **adjust) ;
#line 744 "inweb/Chapter 2/The Parser.w"
void Parser__wrong_version(int using, source_line *L, char *feature, int need) ;
#line 755 "inweb/Chapter 2/The Parser.w"
int Parser__detect_footnote(web *W, text_stream *matter, text_stream *before, text_stream *cue, text_stream *after) ;
#line 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 106 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_code(web *W) ;
#line 183 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_as_code(web *W, source_line *L, text_stream *text, int mask, int transf) ;
#line 225 "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"
hash_table_entry * Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) ;
#line 312 "inweb/Chapter 3/The Analyser.w"
void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) ;
#line 316 "inweb/Chapter 3/The Analyser.w"
hash_table_entry * Analyser__mark_reserved_word_at_line(source_line *L, text_stream *p, int e) ;
#line 324 "inweb/Chapter 3/The Analyser.w"
int Analyser__is_reserved_word(hash_table *HT, text_stream *p, int e) ;
#line 330 "inweb/Chapter 3/The Analyser.w"
int Analyser__is_reserved_word_for_section(section *S, text_stream *p, int e) ;
#line 334 "inweb/Chapter 3/The Analyser.w"
source_line * Analyser__get_defn_line(section *S, text_stream *p, int e) ;
#line 340 "inweb/Chapter 3/The Analyser.w"
language_function * Analyser__get_function(section *S, text_stream *p, int e) ;
#line 363 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_find(web *W, source_line *L, text_stream *identifier, int u) ;
#line 385 "inweb/Chapter 3/The Analyser.w"
void Analyser__write_makefile(web *W, filename *F, module_search *I) ;
#line 392 "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, 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, linked_list *breadcrumbs, filename *navigation) ;
#line 195 "inweb/Chapter 3/The Swarm.w"
void Swarm__ensure_plugin(weave_target *wt, text_stream *name) ;
#line 209 "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) ;
#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 137 "inweb/Chapter 3/The Indexer.w"
void Indexer__nav_column(OUTPUT_STREAM, pathname *P, web *W, text_stream *range, weave_pattern *pattern, filename *nav, text_stream *leafname) ;
#line 156 "inweb/Chapter 3/The Indexer.w"
void Indexer__nav_run(web *W, text_stream *range, filename *F, text_stream *leafname, text_stream *OUT, weave_pattern *pattern, pathname *P) ;
#line 193 "inweb/Chapter 3/The Indexer.w"
contents_processor Indexer__new_processor(text_stream *range) ;
#line 208 "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 unlink_selflinks) ;
#line 284 "inweb/Chapter 3/The Indexer.w"
void Indexer__save_template_line(text_stream *line, text_file_position *tfp, void *void_cp) ;
#line 441 "inweb/Chapter 3/The Indexer.w"
linked_list_item * Indexer__heading_topmost_on_stack(contents_processor *cp, int level) ;
#line 452 "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 462 "inweb/Chapter 3/The Indexer.w"
void Indexer__end_CI_loop(contents_processor *cp) ;
#line 704 "inweb/Chapter 3/The Indexer.w"
void Indexer__list_module(OUTPUT_STREAM, module *M, int list_this) ;
#line 721 "inweb/Chapter 3/The Indexer.w"
void Indexer__transcribe_CSS(OUTPUT_STREAM, filename *CSS_file) ;
#line 728 "inweb/Chapter 3/The Indexer.w"
void Indexer__copy_CSS(text_stream *line, text_file_position *tfp, void *X) ;
#line 737 "inweb/Chapter 3/The Indexer.w"
filename * Indexer__current_file(void) ;
#line 740 "inweb/Chapter 3/The Indexer.w"
void Indexer__set_current_file(filename *F) ;
#line 16 "inweb/Chapter 3/The Weaver.w"
int Weaver__weave_source(web *W, weave_target *wv) ;
#line 741 "inweb/Chapter 3/The Weaver.w"
void Weaver__show_endnotes_on_previous_paragraph(OUTPUT_STREAM, weave_target *wv, paragraph *P) ;
#line 841 "inweb/Chapter 3/The Weaver.w"
void Weaver__show_function_usage(OUTPUT_STREAM, weave_target *wv, paragraph *P, language_function *fn, int as_list) ;
#line 906 "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, web *W) ;
#line 50 "inweb/Chapter 4/Programming Languages.w"
programming_language * Languages__default(web *W) ;
#line 54 "inweb/Chapter 4/Programming Languages.w"
void Languages__show(OUTPUT_STREAM) ;
#line 71 "inweb/Chapter 4/Programming Languages.w"
int Languages__compare_names(const void *ent1, const void *ent2) ;
#line 80 "inweb/Chapter 4/Programming Languages.w"
void Languages__read_definitions(pathname *P) ;
#line 94 "inweb/Chapter 4/Programming Languages.w"
pathname * Languages__default_directory(void) ;
#line 157 "inweb/Chapter 4/Programming Languages.w"
programming_language * Languages__read_definition(filename *F) ;
#line 222 "inweb/Chapter 4/Programming Languages.w"
void Languages__read_definition_line(text_stream *line, text_file_position *tfp, void *v_state) ;
#line 404 "inweb/Chapter 4/Programming Languages.w"
colouring_language_block * Languages__new_block(colouring_language_block *within, int r) ;
#line 458 "inweb/Chapter 4/Programming Languages.w"
colouring_rule * Languages__new_rule(colouring_language_block *within) ;
#line 482 "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 562 "inweb/Chapter 4/Programming Languages.w"
reserved_word * Languages__reserved(programming_language *pl, text_stream *W, int C, text_file_position *tfp) ;
#line 599 "inweb/Chapter 4/Programming Languages.w"
int Languages__colour(text_stream *T, text_file_position *tfp) ;
#line 624 "inweb/Chapter 4/Programming Languages.w"
int Languages__boolean(text_stream *T, text_file_position *tfp) ;
#line 638 "inweb/Chapter 4/Programming Languages.w"
text_stream * Languages__text(text_stream *T, text_file_position *tfp, int allow) ;
#line 725 "inweb/Chapter 4/Programming Languages.w"
void Languages__regexp(wchar_t *write_to, text_stream *T, text_file_position *tfp) ;
#line 775 "inweb/Chapter 4/Programming Languages.w"
int Languages__add_to_regexp(wchar_t *write_to, int i, wchar_t c) ;
#line 780 "inweb/Chapter 4/Programming Languages.w"
int Languages__add_escape_to_regexp(wchar_t *write_to, int i, wchar_t c) ;
#line 22 "inweb/Chapter 4/Types and Functions.w"
language_type * Functions__new_struct(web *W, text_stream *name, source_line *L) ;
#line 86 "inweb/Chapter 4/Types and Functions.w"
structure_element * Functions__new_element(language_type *str, text_stream *elname, source_line *L) ;
#line 100 "inweb/Chapter 4/Types and Functions.w"
language_type * Functions__find_structure(web *W, text_stream *name) ;
#line 127 "inweb/Chapter 4/Types and Functions.w"
language_function * Functions__new_function(text_stream *fname, source_line *L) ;
#line 193 "inweb/Chapter 4/Types and Functions.w"
void Functions__catalogue(section *S, int functions_too) ;
#line 37 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__parse_types(web *W, programming_language *pl) ;
#line 47 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__parse_functions(web *W, programming_language *pl) ;
#line 59 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__further_parsing(web *W, programming_language *pl) ;
#line 72 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__subcategorise_line(programming_language *pl, source_line *L) ;
#line 86 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__parse_comment(programming_language *pl, text_stream *line, text_stream *before, text_stream *within) ;
#line 105 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__shebang(OUTPUT_STREAM, programming_language *pl, web *W, tangle_target *target) ;
#line 116 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__disclaimer(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ;
#line 130 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__additional_early_matter(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ;
#line 149 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__start_definition(OUTPUT_STREAM, programming_language *pl, text_stream *term, text_stream *start, section *S, source_line *L) ;
#line 157 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__prolong_definition(OUTPUT_STREAM, programming_language *pl, text_stream *more, section *S, source_line *L) ;
#line 165 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__end_definition(OUTPUT_STREAM, programming_language *pl, section *S, source_line *L) ;
#line 178 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__additional_predeclarations(OUTPUT_STREAM, programming_language *pl, web *W) ;
#line 191 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__allow_expansion(programming_language *pl, text_stream *material) ;
#line 206 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__special_tangle_command(OUTPUT_STREAM, programming_language *pl, text_stream *data) ;
#line 223 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__will_insert_in_tangle(programming_language *pl, source_line *L) ;
#line 228 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__insert_in_tangle(OUTPUT_STREAM, programming_language *pl, source_line *L) ;
#line 241 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__insert_line_marker(OUTPUT_STREAM, programming_language *pl, source_line *L) ;
#line 255 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__before_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ;
#line 258 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__after_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ;
#line 272 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__open_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ;
#line 275 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__close_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ;
#line 285 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__comment(OUTPUT_STREAM, programming_language *pl, text_stream *comm) ;
#line 297 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__tangle_code(OUTPUT_STREAM, programming_language *pl, text_stream *original) ;
#line 309 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__gnabehs(OUTPUT_STREAM, programming_language *pl, web *W) ;
#line 321 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__additional_tangling(programming_language *pl, web *W, tangle_target *target) ;
#line 333 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__begin_weave(section *S, weave_target *wv) ;
#line 343 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__skip_in_weaving(programming_language *pl, weave_target *wv, source_line *L) ;
#line 358 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__reset_syntax_colouring(programming_language *pl) ;
#line 371 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__syntax_colour(OUTPUT_STREAM, programming_language *pl, weave_target *wv, source_line *L, text_stream *matter, text_stream *colouring) ;
#line 392 "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 405 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__new_tag_declared(theme_tag *tag) ;
#line 428 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__early_preweave_analysis(programming_language *pl, web *W) ;
#line 431 "inweb/Chapter 4/Language Methods.w"
void LanguageMethods__late_preweave_analysis(programming_language *pl, web *W) ;
#line 442 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__share_element(programming_language *pl, text_stream *element_name) ;
#line 451 "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 58 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__expand(OUTPUT_STREAM, text_stream *prototype, text_stream *S, int N, filename *F) ;
#line 82 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__shebang(programming_language *pl, text_stream *OUT, web *W, tangle_target *target) ;
#line 87 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__before_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ;
#line 92 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__after_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ;
#line 97 "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 106 "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 115 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__end_definition(programming_language *pl, text_stream *OUT, section *S, source_line *L) ;
#line 123 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__I6_open_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ;
#line 129 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__I6_close_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ;
#line 135 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__insert_line_marker(programming_language *pl, text_stream *OUT, source_line *L) ;
#line 141 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__comment(programming_language *pl, text_stream *OUT, text_stream *comm) ;
#line 157 "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 219 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_types(programming_language *self, web *W) ;
#line 238 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_functions(programming_language *self, web *W) ;
#line 259 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__suppress_disclaimer(programming_language *pl) ;
#line 266 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__begin_weave(programming_language *pl, section *S, weave_target *wv) ;
#line 275 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__reset_syntax_colouring(programming_language *pl) ;
#line 279 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__syntax_colour(programming_language *pl, text_stream *OUT, weave_target *wv, source_line *L, text_stream *matter, text_stream *colouring) ;
#line 17 "inweb/Chapter 4/The Painter.w"
void Painter__reset_syntax_colouring(programming_language *pl) ;
#line 38 "inweb/Chapter 4/The Painter.w"
int Painter__syntax_colour(programming_language *pl, hash_table *HT, text_stream *matter, text_stream *colouring, int with_comments) ;
#line 58 "inweb/Chapter 4/The Painter.w"
void Painter__syntax_colour_inner(programming_language *pl, hash_table *HT, text_stream *matter, text_stream *colouring, int from, int to) ;
#line 170 "inweb/Chapter 4/The Painter.w"
int Painter__identifier_at(programming_language *pl, text_stream *matter, text_stream *colouring, int i) ;
#line 203 "inweb/Chapter 4/The Painter.w"
void Painter__execute(hash_table *HT, colouring_language_block *block, text_stream *matter, text_stream *colouring, int from, int to, int N) ;
#line 284 "inweb/Chapter 4/The Painter.w"
void Painter__execute_rule(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to, int N) ;
#line 300 "inweb/Chapter 4/The Painter.w"
int Painter__satisfies(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to, int N) ;
#line 364 "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 391 "inweb/Chapter 4/The Painter.w"
linked_list * Painter__lines(filename *F) ;
#line 413 "inweb/Chapter 4/The Painter.w"
void Painter__text_file_helper(text_stream *text, text_file_position *tfp, void *state) ;
#line 418 "inweb/Chapter 4/The Painter.w"
void Painter__colour_file(programming_language *pl, filename *F, text_stream *to, text_stream *coloured) ;
#line 9 "inweb/Chapter 4/C-Like Languages.w"
void CLike__make_c_like(programming_language *pl) ;
#line 27 "inweb/Chapter 4/C-Like Languages.w"
void CLike__parse_types(programming_language *self, web *W) ;
#line 188 "inweb/Chapter 4/C-Like Languages.w"
void CLike__parse_functions(programming_language *self, web *W) ;
#line 317 "inweb/Chapter 4/C-Like Languages.w"
void CLike__subcategorise_code(programming_language *self, source_line *L) ;
#line 346 "inweb/Chapter 4/C-Like Languages.w"
void CLike__additional_early_matter(programming_language *self, text_stream *OUT, web *W, tangle_target *target) ;
#line 365 "inweb/Chapter 4/C-Like Languages.w"
void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) ;
#line 403 "inweb/Chapter 4/C-Like Languages.w"
void CLike__tangle_structure(OUTPUT_STREAM, programming_language *self, language_type *str) ;
#line 470 "inweb/Chapter 4/C-Like Languages.w"
void CLike__analyse_code(programming_language *self, web *W) ;
#line 492 "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 750 "inweb/Chapter 4/InC Support.w"
preform_nonterminal * InCSupport__nonterminal_by_name(text_stream *name) ;
#line 764 "inweb/Chapter 4/InC Support.w"
text_stream * InCSupport__nonterminal_variable_identifier(text_stream *name) ;
#line 785 "inweb/Chapter 4/InC Support.w"
void InCSupport__additional_tangling(programming_language *self, web *W, tangle_target *target) ;
#line 847 "inweb/Chapter 4/InC Support.w"
void InCSupport__weave_grammar_index(OUTPUT_STREAM) ;
#line 925 "inweb/Chapter 4/InC Support.w"
int InCSupport__skip_in_weaving(programming_language *self, weave_target *wv, source_line *L) ;
#line 940 "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 954 "inweb/Chapter 4/InC Support.w"
void InCSupport__new_tag_declared(programming_language *self, theme_tag *tag) ;
#line 961 "inweb/Chapter 4/InC Support.w"
void InCSupport__analyse_code(programming_language *self, web *W) ;
#line 968 "inweb/Chapter 4/InC Support.w"
int InCSupport__share_element(programming_language *self, text_stream *elname) ;
#line 18 "inweb/Chapter 5/Format Methods.w"
weave_format * Formats__create_weave_format(text_stream *name, text_stream *ext) ;
#line 26 "inweb/Chapter 5/Format Methods.w"
weave_format * Formats__find_by_name(text_stream *name) ;
#line 40 "inweb/Chapter 5/Format Methods.w"
text_stream * Formats__file_extension(weave_format *wf) ;
#line 48 "inweb/Chapter 5/Format Methods.w"
void Formats__create_weave_formats(void) ;
#line 71 "inweb/Chapter 5/Format Methods.w"
int Formats__begin_weaving(web *W, weave_pattern *pattern) ;
#line 77 "inweb/Chapter 5/Format Methods.w"
void Formats__end_weaving(web *W, weave_pattern *pattern) ;
#line 92 "inweb/Chapter 5/Format Methods.w"
void Formats__top(OUTPUT_STREAM, weave_target *wv, text_stream *comment) ;
#line 110 "inweb/Chapter 5/Format Methods.w"
void Formats__toc(OUTPUT_STREAM, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ;
#line 124 "inweb/Chapter 5/Format Methods.w"
void Formats__chapter_title_page(OUTPUT_STREAM, weave_target *wv, chapter *C) ;
#line 145 "inweb/Chapter 5/Format Methods.w"
void Formats__subheading(OUTPUT_STREAM, weave_target *wv, int level, text_stream *heading, text_stream *addendum) ;
#line 170 "inweb/Chapter 5/Format Methods.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 191 "inweb/Chapter 5/Format Methods.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, int linked) ;
#line 207 "inweb/Chapter 5/Format Methods.w"
void Formats__source_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) ;
#line 224 "inweb/Chapter 5/Format Methods.w"
void Formats__url(OUTPUT_STREAM, weave_target *wv, text_stream *url, text_stream *content, int external) ;
#line 241 "inweb/Chapter 5/Format Methods.w"
void Formats__footnote_cue(OUTPUT_STREAM, weave_target *wv, text_stream *cue) ;
#line 257 "inweb/Chapter 5/Format Methods.w"
void Formats__begin_footnote_text(OUTPUT_STREAM, weave_target *wv, text_stream *cue) ;
#line 274 "inweb/Chapter 5/Format Methods.w"
void Formats__end_footnote_text(OUTPUT_STREAM, weave_target *wv, text_stream *cue) ;
#line 291 "inweb/Chapter 5/Format Methods.w"
void Formats__display_line(OUTPUT_STREAM, weave_target *wv, text_stream *from) ;
#line 313 "inweb/Chapter 5/Format Methods.w"
void Formats__item(OUTPUT_STREAM, weave_target *wv, int depth, text_stream *label) ;
#line 325 "inweb/Chapter 5/Format Methods.w"
void Formats__bar(OUTPUT_STREAM, weave_target *wv) ;
#line 339 "inweb/Chapter 5/Format Methods.w"
void Formats__figure(OUTPUT_STREAM, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) ;
#line 354 "inweb/Chapter 5/Format Methods.w"
void Formats__embed(OUTPUT_STREAM, weave_target *wv, text_stream *service, text_stream *ID) ;
#line 369 "inweb/Chapter 5/Format Methods.w"
void Formats__para_macro(OUTPUT_STREAM, weave_target *wv, para_macro *pmac, int defn) ;
#line 382 "inweb/Chapter 5/Format Methods.w"
void Formats__pagebreak(OUTPUT_STREAM, weave_target *wv) ;
#line 397 "inweb/Chapter 5/Format Methods.w"
void Formats__blank_line(OUTPUT_STREAM, weave_target *wv, int in_comment) ;
#line 411 "inweb/Chapter 5/Format Methods.w"
void Formats__after_definitions(OUTPUT_STREAM, weave_target *wv) ;
#line 427 "inweb/Chapter 5/Format Methods.w"
void Formats__change_material(OUTPUT_STREAM, weave_target *wv, int old_material, int new_material, int content, int plainly) ;
#line 444 "inweb/Chapter 5/Format Methods.w"
void Formats__change_colour(OUTPUT_STREAM, weave_target *wv, int col, int in_code) ;
#line 455 "inweb/Chapter 5/Format Methods.w"
void Formats__text(OUTPUT_STREAM, weave_target *wv, text_stream *id) ;
#line 458 "inweb/Chapter 5/Format Methods.w"
void Formats__text_comment(OUTPUT_STREAM, weave_target *wv, text_stream *id) ;
#line 462 "inweb/Chapter 5/Format Methods.w"
void Formats__text_r(OUTPUT_STREAM, weave_target *wv, text_stream *id, int within, int comments) ;
#line 591 "inweb/Chapter 5/Format Methods.w"
void Formats__text_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) ;
#line 616 "inweb/Chapter 5/Format Methods.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 634 "inweb/Chapter 5/Format Methods.w"
void Formats__endnote(OUTPUT_STREAM, weave_target *wv, int end) ;
#line 649 "inweb/Chapter 5/Format Methods.w"
void Formats__locale(OUTPUT_STREAM, weave_target *wv, paragraph *par1, paragraph *par2) ;
#line 662 "inweb/Chapter 5/Format Methods.w"
void Formats__tail(OUTPUT_STREAM, weave_target *wv, text_stream *comment, section *S) ;
#line 678 "inweb/Chapter 5/Format Methods.w"
void Formats__post_process_weave(weave_target *wv, int open_afterwards) ;
#line 689 "inweb/Chapter 5/Format Methods.w"
void Formats__report_on_post_processing(weave_target *wv) ;
#line 701 "inweb/Chapter 5/Format Methods.w"
int Formats__index_pdfs(text_stream *format) ;
#line 717 "inweb/Chapter 5/Format Methods.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, int linked) ;
#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__preserve_math_mode(weave_format *self, weave_target *wv, text_stream *matter, text_stream *id) ;
#line 72 "inweb/Chapter 5/TeX Format.w"
int TeX__yes(weave_format *self, weave_target *wv) ;
#line 77 "inweb/Chapter 5/TeX Format.w"
void TeX__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ;
#line 101 "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 117 "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 139 "inweb/Chapter 5/TeX Format.w"
void TeX__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv, chapter *C) ;
#line 153 "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 185 "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, int linked) ;
#line 227 "inweb/Chapter 5/TeX Format.w"
void TeX__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) ;
#line 233 "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 250 "inweb/Chapter 5/TeX Format.w"
void TeX__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *text) ;
#line 256 "inweb/Chapter 5/TeX Format.w"
void TeX__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ;
#line 268 "inweb/Chapter 5/TeX Format.w"
void TeX__bar(weave_format *self, text_stream *OUT, weave_target *wv) ;
#line 280 "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 302 "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 311 "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 320 "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 329 "inweb/Chapter 5/TeX Format.w"
void TeX__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) ;
#line 334 "inweb/Chapter 5/TeX Format.w"
void TeX__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ;
#line 341 "inweb/Chapter 5/TeX Format.w"
void TeX__after_definitions(weave_format *self, text_stream *OUT, weave_target *wv) ;
#line 346 "inweb/Chapter 5/TeX Format.w"
void TeX__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ;
#line 356 "inweb/Chapter 5/TeX Format.w"
void TeX__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ;
#line 379 "inweb/Chapter 5/TeX Format.w"
void TeX__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ;
#line 386 "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, int change_material) ;
#line 412 "inweb/Chapter 5/TeX Format.w"
void TeX__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) ;
#line 422 "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 502 "inweb/Chapter 5/TeX Format.w"
void TeX__post_process_PDF(weave_format *self, weave_target *wv, int open) ;
#line 505 "inweb/Chapter 5/TeX Format.w"
void TeX__post_process_DVI(weave_format *self, weave_target *wv, int open) ;
#line 510 "inweb/Chapter 5/TeX Format.w"
void TeX__post_process_report(weave_format *self, weave_target *wv) ;
#line 515 "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 528 "inweb/Chapter 5/TeX Format.w"
void TeX__remove_math_mode(OUTPUT_STREAM, text_stream *text) ;
#line 535 "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 64 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__p(OUTPUT_STREAM, char *class) ;
#line 70 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__cp(OUTPUT_STREAM) ;
#line 75 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__pre(OUTPUT_STREAM, char *class) ;
#line 82 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__cpre(OUTPUT_STREAM) ;
#line 91 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__go_to_depth(OUTPUT_STREAM, int depth) ;
#line 116 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__exit_current_paragraph(OUTPUT_STREAM) ;
#line 128 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__breadcrumb(OUTPUT_STREAM, text_stream *text, text_stream *link) ;
#line 148 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ;
#line 162 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__preserve_math_mode(weave_format *self, weave_target *wv, text_stream *matter, text_stream *text) ;
#line 188 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__top_EPUB(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ;
#line 197 "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 214 "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 249 "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 307 "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, int linked) ;
#line 458 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) ;
#line 469 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__url(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *url, text_stream *content, int external) ;
#line 477 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__footnote_cue(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *cue) ;
#line 488 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__begin_footnote_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *cue) ;
#line 498 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__end_footnote_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *cue) ;
#line 508 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *from) ;
#line 519 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ;
#line 528 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__bar(weave_format *self, text_stream *OUT, weave_target *wv) ;
#line 534 "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 549 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__embed(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *service, text_stream *ID) ;
#line 588 "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 603 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) ;
#line 608 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ;
#line 621 "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, int plainly) ;
#line 690 "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 711 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ;
#line 721 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ;
#line 742 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ;
#line 756 "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 803 "inweb/Chapter 5/HTML Formats.w"
int HTMLFormat__begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ;
#line 818 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__end_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ;
#line 19 "inweb/Chapter 5/Weave Plugins.w"
weave_plugin * WeavePlugins__new(text_stream *name) ;
#line 33 "inweb/Chapter 5/Weave Plugins.w"
void WeavePlugins__include(OUTPUT_STREAM, web *W, weave_plugin *wp, 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) ;
#line 63 "inweb/Chapter 6/Colonies.w"
void Colonies__load(filename *F) ;
#line 78 "inweb/Chapter 6/Colonies.w"
void Colonies__read_line(text_stream *line, text_file_position *tfp, void *v_crs) ;
#line 136 "inweb/Chapter 6/Colonies.w"
void Colonies__add_crumb(linked_list *L, text_stream *spec, text_file_position *tfp) ;
#line 154 "inweb/Chapter 6/Colonies.w"
breadcrumb_request * Colonies__request_breadcrumb(text_stream *arg) ;
#line 169 "inweb/Chapter 6/Colonies.w"
void Colonies__drop_initial_breadcrumbs(OUTPUT_STREAM, filename *F, linked_list *crumbs) ;
#line 184 "inweb/Chapter 6/Colonies.w"
colony_member * Colonies__find(text_stream *T) ;
#line 202 "inweb/Chapter 6/Colonies.w"
module * Colonies__as_module(colony_member *CM, source_line *L, web_md *Wm) ;
#line 255 "inweb/Chapter 6/Colonies.w"
int Colonies__resolve_reference_in_weave(text_stream *url, text_stream *title, filename *for_HTML_file, text_stream *text, web_md *Wm, source_line *L) ;
#line 367 "inweb/Chapter 6/Colonies.w"
void Colonies__link_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) ;
#line 376 "inweb/Chapter 6/Colonies.w"
void Colonies__reference_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) ;
#line 387 "inweb/Chapter 6/Colonies.w"
void Colonies__section_URL(OUTPUT_STREAM, section_md *Sm) ;
#line 397 "inweb/Chapter 6/Colonies.w"
void Colonies__paragraph_URL(OUTPUT_STREAM, paragraph *P, section *from, int a_link) ;
void register_tangled_nonterminals(void);
text_stream *TL_IS_0 = NULL;
text_stream *TL_IS_1 = NULL;
text_stream *TL_IS_2 = NULL;
text_stream *TL_IS_3 = NULL;
text_stream *TL_IS_4 = NULL;
text_stream *TL_IS_5 = NULL;
text_stream *TL_IS_6 = NULL;
text_stream *TL_IS_7 = NULL;
text_stream *TL_IS_8 = NULL;
text_stream *TL_IS_9 = NULL;
text_stream *TL_IS_10 = NULL;
text_stream *TL_IS_11 = NULL;
text_stream *TL_IS_12 = NULL;
text_stream *TL_IS_13 = NULL;
text_stream *TL_IS_14 = NULL;
text_stream *TL_IS_15 = NULL;
text_stream *TL_IS_16 = NULL;
text_stream *TL_IS_17 = NULL;
text_stream *TL_IS_18 = NULL;
text_stream *TL_IS_19 = NULL;
text_stream *TL_IS_20 = NULL;
text_stream *TL_IS_21 = NULL;
text_stream *TL_IS_22 = NULL;
text_stream *TL_IS_23 = NULL;
text_stream *TL_IS_24 = NULL;
text_stream *TL_IS_25 = NULL;
text_stream *TL_IS_26 = NULL;
text_stream *TL_IS_27 = NULL;
text_stream *TL_IS_28 = NULL;
text_stream *TL_IS_29 = NULL;
text_stream *TL_IS_30 = NULL;
text_stream *TL_IS_31 = NULL;
text_stream *TL_IS_32 = NULL;
text_stream *TL_IS_33 = NULL;
text_stream *TL_IS_34 = NULL;
text_stream *TL_IS_35 = NULL;
text_stream *TL_IS_36 = NULL;
text_stream *TL_IS_37 = NULL;
text_stream *TL_IS_38 = NULL;
text_stream *TL_IS_39 = NULL;
text_stream *TL_IS_40 = NULL;
text_stream *TL_IS_41 = NULL;
text_stream *TL_IS_42 = NULL;
text_stream *TL_IS_43 = NULL;
text_stream *TL_IS_44 = NULL;
text_stream *TL_IS_45 = NULL;
text_stream *TL_IS_46 = NULL;
text_stream *TL_IS_47 = NULL;
text_stream *TL_IS_48 = NULL;
text_stream *TL_IS_49 = NULL;
text_stream *TL_IS_50 = NULL;
text_stream *TL_IS_51 = NULL;
text_stream *TL_IS_52 = NULL;
text_stream *TL_IS_53 = NULL;
text_stream *TL_IS_54 = NULL;
text_stream *TL_IS_55 = NULL;
text_stream *TL_IS_56 = NULL;
text_stream *TL_IS_57 = NULL;
text_stream *TL_IS_58 = NULL;
text_stream *TL_IS_59 = NULL;
text_stream *TL_IS_60 = NULL;
text_stream *TL_IS_61 = NULL;
text_stream *TL_IS_62 = NULL;
text_stream *TL_IS_63 = NULL;
text_stream *TL_IS_64 = NULL;
text_stream *TL_IS_65 = NULL;
text_stream *TL_IS_66 = NULL;
text_stream *TL_IS_67 = NULL;
text_stream *TL_IS_68 = NULL;
text_stream *TL_IS_69 = NULL;
text_stream *TL_IS_70 = NULL;
text_stream *TL_IS_71 = NULL;
text_stream *TL_IS_72 = NULL;
text_stream *TL_IS_73 = NULL;
text_stream *TL_IS_74 = NULL;
text_stream *TL_IS_75 = NULL;
text_stream *TL_IS_76 = NULL;
text_stream *TL_IS_77 = NULL;
text_stream *TL_IS_78 = NULL;
text_stream *TL_IS_79 = NULL;
text_stream *TL_IS_80 = NULL;
text_stream *TL_IS_81 = NULL;
text_stream *TL_IS_82 = NULL;
text_stream *TL_IS_83 = NULL;
text_stream *TL_IS_84 = NULL;
text_stream *TL_IS_85 = NULL;
text_stream *TL_IS_86 = NULL;
text_stream *TL_IS_87 = NULL;
text_stream *TL_IS_88 = NULL;
text_stream *TL_IS_89 = NULL;
text_stream *TL_IS_90 = NULL;
text_stream *TL_IS_91 = NULL;
text_stream *TL_IS_92 = NULL;
text_stream *TL_IS_93 = NULL;
text_stream *TL_IS_94 = NULL;
text_stream *TL_IS_95 = NULL;
text_stream *TL_IS_96 = NULL;
text_stream *TL_IS_97 = NULL;
text_stream *TL_IS_98 = NULL;
text_stream *TL_IS_99 = NULL;
text_stream *TL_IS_100 = NULL;
text_stream *TL_IS_101 = NULL;
text_stream *TL_IS_102 = NULL;
text_stream *TL_IS_103 = NULL;
text_stream *TL_IS_104 = NULL;
text_stream *TL_IS_105 = NULL;
text_stream *TL_IS_106 = NULL;
text_stream *TL_IS_107 = NULL;
text_stream *TL_IS_108 = NULL;
text_stream *TL_IS_109 = NULL;
text_stream *TL_IS_110 = NULL;
text_stream *TL_IS_111 = NULL;
text_stream *TL_IS_112 = NULL;
text_stream *TL_IS_113 = NULL;
text_stream *TL_IS_114 = NULL;
text_stream *TL_IS_115 = NULL;
text_stream *TL_IS_116 = NULL;
text_stream *TL_IS_117 = NULL;
text_stream *TL_IS_118 = NULL;
text_stream *TL_IS_119 = NULL;
text_stream *TL_IS_120 = NULL;
text_stream *TL_IS_121 = NULL;
text_stream *TL_IS_122 = NULL;
text_stream *TL_IS_123 = NULL;
text_stream *TL_IS_124 = NULL;
text_stream *TL_IS_125 = NULL;
text_stream *TL_IS_126 = NULL;
text_stream *TL_IS_127 = NULL;
text_stream *TL_IS_128 = NULL;
text_stream *TL_IS_129 = NULL;
text_stream *TL_IS_130 = NULL;
text_stream *TL_IS_131 = NULL;
text_stream *TL_IS_132 = NULL;
text_stream *TL_IS_133 = NULL;
text_stream *TL_IS_134 = NULL;
text_stream *TL_IS_135 = NULL;
text_stream *TL_IS_136 = NULL;
text_stream *TL_IS_137 = NULL;
text_stream *TL_IS_138 = NULL;
text_stream *TL_IS_139 = NULL;
text_stream *TL_IS_140 = NULL;
text_stream *TL_IS_141 = NULL;
text_stream *TL_IS_142 = NULL;
text_stream *TL_IS_143 = NULL;
text_stream *TL_IS_144 = NULL;
text_stream *TL_IS_145 = NULL;
text_stream *TL_IS_146 = NULL;
text_stream *TL_IS_147 = NULL;
text_stream *TL_IS_148 = NULL;
text_stream *TL_IS_149 = NULL;
text_stream *TL_IS_150 = NULL;
text_stream *TL_IS_151 = NULL;
text_stream *TL_IS_152 = NULL;
text_stream *TL_IS_153 = NULL;
text_stream *TL_IS_154 = NULL;
text_stream *TL_IS_155 = NULL;
text_stream *TL_IS_156 = NULL;
text_stream *TL_IS_157 = NULL;
text_stream *TL_IS_158 = NULL;
text_stream *TL_IS_159 = NULL;
text_stream *TL_IS_160 = NULL;
text_stream *TL_IS_161 = NULL;
text_stream *TL_IS_162 = NULL;
text_stream *TL_IS_163 = NULL;
text_stream *TL_IS_164 = NULL;
text_stream *TL_IS_165 = NULL;
text_stream *TL_IS_166 = NULL;
text_stream *TL_IS_167 = NULL;
text_stream *TL_IS_168 = NULL;
text_stream *TL_IS_169 = NULL;
text_stream *TL_IS_170 = NULL;
text_stream *TL_IS_171 = NULL;
text_stream *TL_IS_172 = NULL;
text_stream *TL_IS_173 = NULL;
text_stream *TL_IS_174 = NULL;
text_stream *TL_IS_175 = NULL;
text_stream *TL_IS_176 = NULL;
text_stream *TL_IS_177 = NULL;
text_stream *TL_IS_178 = NULL;
text_stream *TL_IS_179 = NULL;
text_stream *TL_IS_180 = NULL;
text_stream *TL_IS_181 = NULL;
text_stream *TL_IS_182 = NULL;
text_stream *TL_IS_183 = NULL;
text_stream *TL_IS_184 = NULL;
text_stream *TL_IS_185 = NULL;
text_stream *TL_IS_186 = NULL;
text_stream *TL_IS_187 = NULL;
text_stream *TL_IS_188 = NULL;
text_stream *TL_IS_189 = NULL;
text_stream *TL_IS_190 = NULL;
text_stream *TL_IS_191 = NULL;
text_stream *TL_IS_192 = NULL;
text_stream *TL_IS_193 = NULL;
text_stream *TL_IS_194 = NULL;
text_stream *TL_IS_195 = NULL;
text_stream *TL_IS_196 = NULL;
text_stream *TL_IS_197 = NULL;
text_stream *TL_IS_198 = NULL;
text_stream *TL_IS_199 = NULL;
text_stream *TL_IS_200 = NULL;
text_stream *TL_IS_201 = NULL;
text_stream *TL_IS_202 = NULL;
text_stream *TL_IS_203 = NULL;
text_stream *TL_IS_204 = NULL;
text_stream *TL_IS_205 = NULL;
text_stream *TL_IS_206 = NULL;
text_stream *TL_IS_207 = NULL;
text_stream *TL_IS_208 = NULL;
text_stream *TL_IS_209 = NULL;
text_stream *TL_IS_210 = NULL;
text_stream *TL_IS_211 = NULL;
text_stream *TL_IS_212 = NULL;
text_stream *TL_IS_213 = NULL;
text_stream *TL_IS_214 = NULL;
text_stream *TL_IS_215 = NULL;
text_stream *TL_IS_216 = NULL;
text_stream *TL_IS_217 = NULL;
text_stream *TL_IS_218 = NULL;
text_stream *TL_IS_219 = NULL;
text_stream *TL_IS_220 = NULL;
text_stream *TL_IS_221 = NULL;
text_stream *TL_IS_222 = NULL;
text_stream *TL_IS_223 = NULL;
text_stream *TL_IS_224 = NULL;
text_stream *TL_IS_225 = NULL;
text_stream *TL_IS_226 = NULL;
text_stream *TL_IS_227 = NULL;
text_stream *TL_IS_228 = NULL;
text_stream *TL_IS_229 = NULL;
text_stream *TL_IS_230 = NULL;
text_stream *TL_IS_231 = NULL;
text_stream *TL_IS_232 = NULL;
text_stream *TL_IS_233 = NULL;
text_stream *TL_IS_234 = NULL;
text_stream *TL_IS_235 = NULL;
text_stream *TL_IS_236 = NULL;
text_stream *TL_IS_237 = NULL;
text_stream *TL_IS_238 = NULL;
text_stream *TL_IS_239 = NULL;
text_stream *TL_IS_240 = NULL;
text_stream *TL_IS_241 = NULL;
text_stream *TL_IS_242 = NULL;
text_stream *TL_IS_243 = NULL;
text_stream *TL_IS_244 = NULL;
text_stream *TL_IS_245 = NULL;
text_stream *TL_IS_246 = NULL;
text_stream *TL_IS_247 = NULL;
text_stream *TL_IS_248 = NULL;
text_stream *TL_IS_249 = NULL;
text_stream *TL_IS_250 = NULL;
text_stream *TL_IS_251 = NULL;
text_stream *TL_IS_252 = NULL;
text_stream *TL_IS_253 = NULL;
text_stream *TL_IS_254 = NULL;
text_stream *TL_IS_255 = NULL;
text_stream *TL_IS_256 = NULL;
text_stream *TL_IS_257 = NULL;
text_stream *TL_IS_258 = NULL;
text_stream *TL_IS_259 = NULL;
text_stream *TL_IS_260 = NULL;
text_stream *TL_IS_261 = NULL;
text_stream *TL_IS_262 = NULL;
text_stream *TL_IS_263 = NULL;
text_stream *TL_IS_264 = NULL;
text_stream *TL_IS_265 = NULL;
text_stream *TL_IS_266 = NULL;
text_stream *TL_IS_267 = NULL;
text_stream *TL_IS_268 = NULL;
text_stream *TL_IS_269 = NULL;
text_stream *TL_IS_270 = NULL;
text_stream *TL_IS_271 = NULL;
text_stream *TL_IS_272 = NULL;
text_stream *TL_IS_273 = NULL;
text_stream *TL_IS_274 = NULL;
text_stream *TL_IS_275 = NULL;
text_stream *TL_IS_276 = NULL;
text_stream *TL_IS_277 = NULL;
text_stream *TL_IS_278 = NULL;
text_stream *TL_IS_279 = NULL;
text_stream *TL_IS_280 = NULL;
text_stream *TL_IS_281 = NULL;
text_stream *TL_IS_282 = NULL;
text_stream *TL_IS_283 = NULL;
text_stream *TL_IS_284 = NULL;
text_stream *TL_IS_285 = NULL;
text_stream *TL_IS_286 = NULL;
text_stream *TL_IS_287 = NULL;
text_stream *TL_IS_288 = NULL;
text_stream *TL_IS_289 = NULL;
text_stream *TL_IS_290 = NULL;
text_stream *TL_IS_291 = NULL;
text_stream *TL_IS_292 = NULL;
text_stream *TL_IS_293 = NULL;
text_stream *TL_IS_294 = NULL;
text_stream *TL_IS_295 = NULL;
text_stream *TL_IS_296 = NULL;
text_stream *TL_IS_297 = NULL;
text_stream *TL_IS_298 = NULL;
text_stream *TL_IS_299 = NULL;
text_stream *TL_IS_300 = NULL;
text_stream *TL_IS_301 = NULL;
text_stream *TL_IS_302 = NULL;
text_stream *TL_IS_303 = NULL;
text_stream *TL_IS_304 = NULL;
text_stream *TL_IS_305 = NULL;
text_stream *TL_IS_306 = NULL;
text_stream *TL_IS_307 = NULL;
text_stream *TL_IS_308 = NULL;
text_stream *TL_IS_309 = NULL;
text_stream *TL_IS_310 = NULL;
text_stream *TL_IS_311 = NULL;
text_stream *TL_IS_312 = NULL;
text_stream *TL_IS_313 = NULL;
text_stream *TL_IS_314 = NULL;
text_stream *TL_IS_315 = NULL;
text_stream *TL_IS_316 = NULL;
text_stream *TL_IS_317 = NULL;
text_stream *TL_IS_318 = NULL;
text_stream *TL_IS_319 = NULL;
text_stream *TL_IS_320 = NULL;
text_stream *TL_IS_321 = NULL;
text_stream *TL_IS_322 = NULL;
text_stream *TL_IS_323 = NULL;
text_stream *TL_IS_324 = NULL;
text_stream *TL_IS_325 = NULL;
text_stream *TL_IS_326 = NULL;
text_stream *TL_IS_327 = NULL;
text_stream *TL_IS_328 = NULL;
text_stream *TL_IS_329 = NULL;
text_stream *TL_IS_330 = NULL;
text_stream *TL_IS_331 = NULL;
text_stream *TL_IS_332 = NULL;
text_stream *TL_IS_333 = NULL;
text_stream *TL_IS_334 = NULL;
text_stream *TL_IS_335 = NULL;
text_stream *TL_IS_336 = NULL;
text_stream *TL_IS_337 = NULL;
text_stream *TL_IS_338 = NULL;
text_stream *TL_IS_339 = NULL;
text_stream *TL_IS_340 = NULL;
text_stream *TL_IS_341 = NULL;
text_stream *TL_IS_342 = NULL;
text_stream *TL_IS_343 = NULL;
text_stream *TL_IS_344 = NULL;
text_stream *TL_IS_345 = NULL;
text_stream *TL_IS_346 = NULL;
text_stream *TL_IS_347 = NULL;
text_stream *TL_IS_348 = NULL;
text_stream *TL_IS_349 = NULL;
text_stream *TL_IS_350 = NULL;
text_stream *TL_IS_351 = NULL;
text_stream *TL_IS_352 = NULL;
text_stream *TL_IS_353 = NULL;
text_stream *TL_IS_354 = NULL;
text_stream *TL_IS_355 = NULL;
text_stream *TL_IS_356 = NULL;
text_stream *TL_IS_357 = NULL;
text_stream *TL_IS_358 = NULL;
text_stream *TL_IS_359 = NULL;
text_stream *TL_IS_360 = NULL;
text_stream *TL_IS_361 = NULL;
text_stream *TL_IS_362 = NULL;
text_stream *TL_IS_363 = NULL;
text_stream *TL_IS_364 = NULL;
text_stream *TL_IS_365 = NULL;
text_stream *TL_IS_366 = NULL;
text_stream *TL_IS_367 = NULL;
text_stream *TL_IS_368 = NULL;
text_stream *TL_IS_369 = NULL;
text_stream *TL_IS_370 = NULL;
text_stream *TL_IS_371 = NULL;
text_stream *TL_IS_372 = NULL;
text_stream *TL_IS_373 = NULL;
text_stream *TL_IS_374 = NULL;
text_stream *TL_IS_375 = NULL;
text_stream *TL_IS_376 = NULL;
text_stream *TL_IS_377 = NULL;
text_stream *TL_IS_378 = NULL;
text_stream *TL_IS_379 = NULL;
text_stream *TL_IS_380 = NULL;
text_stream *TL_IS_381 = NULL;
text_stream *TL_IS_382 = NULL;
text_stream *TL_IS_383 = NULL;
text_stream *TL_IS_384 = NULL;
text_stream *TL_IS_385 = NULL;
text_stream *TL_IS_386 = NULL;
text_stream *TL_IS_387 = NULL;
text_stream *TL_IS_388 = NULL;
text_stream *TL_IS_389 = NULL;
text_stream *TL_IS_390 = NULL;
text_stream *TL_IS_391 = NULL;
text_stream *TL_IS_392 = NULL;
text_stream *TL_IS_393 = NULL;
text_stream *TL_IS_394 = NULL;
text_stream *TL_IS_395 = NULL;
text_stream *TL_IS_396 = NULL;
text_stream *TL_IS_397 = NULL;
text_stream *TL_IS_398 = NULL;
text_stream *TL_IS_399 = NULL;
text_stream *TL_IS_400 = NULL;
text_stream *TL_IS_401 = NULL;
text_stream *TL_IS_402 = NULL;
text_stream *TL_IS_403 = NULL;
text_stream *TL_IS_404 = NULL;
text_stream *TL_IS_405 = NULL;
text_stream *TL_IS_406 = NULL;
text_stream *TL_IS_407 = NULL;
text_stream *TL_IS_408 = NULL;
text_stream *TL_IS_409 = NULL;
text_stream *TL_IS_410 = NULL;
text_stream *TL_IS_411 = NULL;
text_stream *TL_IS_412 = NULL;
text_stream *TL_IS_413 = NULL;
text_stream *TL_IS_414 = NULL;
text_stream *TL_IS_415 = NULL;
text_stream *TL_IS_416 = NULL;
text_stream *TL_IS_417 = NULL;
text_stream *TL_IS_418 = NULL;
text_stream *TL_IS_419 = NULL;
text_stream *TL_IS_420 = NULL;
text_stream *TL_IS_421 = NULL;
text_stream *TL_IS_422 = NULL;
text_stream *TL_IS_423 = NULL;
text_stream *TL_IS_424 = NULL;
text_stream *TL_IS_425 = NULL;
text_stream *TL_IS_426 = NULL;
text_stream *TL_IS_427 = NULL;
text_stream *TL_IS_428 = NULL;
text_stream *TL_IS_429 = NULL;
text_stream *TL_IS_430 = NULL;
text_stream *TL_IS_431 = NULL;
text_stream *TL_IS_432 = NULL;
text_stream *TL_IS_433 = NULL;
text_stream *TL_IS_434 = NULL;
text_stream *TL_IS_435 = NULL;
text_stream *TL_IS_436 = NULL;
text_stream *TL_IS_437 = NULL;
text_stream *TL_IS_438 = NULL;
text_stream *TL_IS_439 = NULL;
text_stream *TL_IS_440 = NULL;
text_stream *TL_IS_441 = NULL;
text_stream *TL_IS_442 = NULL;
text_stream *TL_IS_443 = NULL;
text_stream *TL_IS_444 = NULL;
text_stream *TL_IS_445 = NULL;
text_stream *TL_IS_446 = NULL;
text_stream *TL_IS_447 = NULL;
text_stream *TL_IS_448 = NULL;
text_stream *TL_IS_449 = NULL;
text_stream *TL_IS_450 = NULL;
text_stream *TL_IS_451 = NULL;
text_stream *TL_IS_452 = NULL;
text_stream *TL_IS_453 = NULL;
text_stream *TL_IS_454 = NULL;
text_stream *TL_IS_455 = NULL;
text_stream *TL_IS_456 = NULL;
text_stream *TL_IS_457 = NULL;
text_stream *TL_IS_458 = NULL;
text_stream *TL_IS_459 = NULL;
text_stream *TL_IS_460 = NULL;
text_stream *TL_IS_461 = NULL;
text_stream *TL_IS_462 = NULL;
text_stream *TL_IS_463 = NULL;
text_stream *TL_IS_464 = NULL;
text_stream *TL_IS_465 = NULL;
text_stream *TL_IS_466 = NULL;
text_stream *TL_IS_467 = NULL;
text_stream *TL_IS_468 = NULL;
text_stream *TL_IS_469 = NULL;
text_stream *TL_IS_470 = NULL;
text_stream *TL_IS_471 = NULL;
text_stream *TL_IS_472 = NULL;
text_stream *TL_IS_473 = NULL;
text_stream *TL_IS_474 = NULL;
text_stream *TL_IS_475 = NULL;
text_stream *TL_IS_476 = NULL;
text_stream *TL_IS_477 = NULL;
text_stream *TL_IS_478 = NULL;
text_stream *TL_IS_479 = NULL;
text_stream *TL_IS_480 = NULL;
text_stream *TL_IS_481 = NULL;
text_stream *TL_IS_482 = NULL;
text_stream *TL_IS_483 = NULL;
text_stream *TL_IS_484 = NULL;
text_stream *TL_IS_485 = NULL;
text_stream *TL_IS_486 = NULL;
text_stream *TL_IS_487 = NULL;
text_stream *TL_IS_488 = NULL;
text_stream *TL_IS_489 = NULL;
text_stream *TL_IS_490 = NULL;
text_stream *TL_IS_491 = NULL;
text_stream *TL_IS_492 = NULL;
text_stream *TL_IS_493 = NULL;
text_stream *TL_IS_494 = NULL;
text_stream *TL_IS_495 = NULL;
text_stream *TL_IS_496 = NULL;
text_stream *TL_IS_497 = NULL;
text_stream *TL_IS_498 = NULL;
text_stream *TL_IS_499 = NULL;
text_stream *TL_IS_500 = NULL;
text_stream *TL_IS_501 = NULL;
text_stream *TL_IS_502 = NULL;
text_stream *TL_IS_503 = NULL;
text_stream *TL_IS_504 = NULL;
text_stream *TL_IS_505 = NULL;
text_stream *TL_IS_506 = NULL;
text_stream *TL_IS_507 = NULL;
text_stream *TL_IS_508 = NULL;
text_stream *TL_IS_509 = NULL;
text_stream *TL_IS_510 = NULL;
text_stream *TL_IS_511 = NULL;
text_stream *TL_IS_512 = NULL;
text_stream *TL_IS_513 = NULL;
text_stream *TL_IS_514 = NULL;
text_stream *TL_IS_515 = NULL;
text_stream *TL_IS_516 = NULL;
text_stream *TL_IS_517 = NULL;
text_stream *TL_IS_518 = NULL;
text_stream *TL_IS_519 = NULL;
text_stream *TL_IS_520 = NULL;
text_stream *TL_IS_521 = NULL;
text_stream *TL_IS_522 = NULL;
text_stream *TL_IS_523 = NULL;
text_stream *TL_IS_524 = NULL;
text_stream *TL_IS_525 = NULL;
text_stream *TL_IS_526 = NULL;
text_stream *TL_IS_527 = NULL;
text_stream *TL_IS_528 = NULL;
text_stream *TL_IS_529 = NULL;
text_stream *TL_IS_530 = NULL;
text_stream *TL_IS_531 = NULL;
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 Module.w"
text_stream *DL = NULL; /* Current destination of debugging text: kept |NULL| until opened */
#line 79 "inweb/foundation-module/Chapter 1/Foundation Module.w"
#line 88 "inweb/foundation-module/Chapter 1/Foundation Module.w"
void Foundation__start(void) {
Memory__start();
{
#line 105 "inweb/foundation-module/Chapter 1/Foundation Module.w"
Writers__register_writer('f', &Filenames__writer);
Writers__register_writer('p', &Pathnames__writer);
Writers__register_writer('v', &VersionNumbers__writer);
Writers__register_writer('S', &Streams__writer);
}
#line 90 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
register_tangled_text_literals();
;
Time__begin();
Pathnames__start();
{
#line 116 "inweb/foundation-module/Chapter 1/Foundation Module.w"
Log__declare_aspect(DEBUGGING_LOG_INCLUSIONS_DA, L"debugging log inclusions", FALSE, FALSE);
Log__declare_aspect(SHELL_USAGE_DA, L"shell usage", FALSE, FALSE);
Log__declare_aspect(MEMORY_USAGE_DA, L"memory usage", FALSE, FALSE);
Log__declare_aspect(TEXT_FILES_DA, L"text files", FALSE, FALSE);
}
#line 94 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
{
#line 127 "inweb/foundation-module/Chapter 1/Foundation Module.w"
Writers__register_logger('a', &Tries__log_avinue);
Writers__register_logger('S', &Streams__log);
}
#line 95 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
{
#line 146 "inweb/foundation-module/Chapter 1/Foundation Module.w"
CommandLine__begin_group(FOUNDATION_CLSG, NULL);
CommandLine__declare_switch(LOG_CLSW, L"log", 2,
L"write the debugging log to include diagnostics on X");
CommandLine__declare_switch(VERSION_CLSW, L"version", 1,
L"print out version number");
CommandLine__declare_boolean_switch(CRASH_CLSW, L"crash", 1,
L"intentionally crash on internal errors, for backtracing", FALSE);
CommandLine__declare_switch(HELP_CLSW, L"help", 1,
L"print this help information");
CommandLine__declare_boolean_switch(FIXTIME_CLSW, L"fixtime", 1,
L"pretend the time is 11 a.m. on 28 March 2016 for testing", FALSE);
CommandLine__declare_switch(AT_CLSW, L"at", 2,
L"specify that this tool is installed at X");
CommandLine__end_group();
}
#line 96 "inweb/foundation-module/Chapter 1/Foundation Module.w"
;
}
#line 144 "inweb/foundation-module/Chapter 1/Foundation Module.w"
#line 167 "inweb/foundation-module/Chapter 1/Foundation Module.w"
void Foundation__end(void) {
if (Log__aspect_switched_on(MEMORY_USAGE_DA)) Memory__log_statistics();
Log__close();
Memory__free();
}
#ifdef PLATFORM_POSIX
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_MACOS
#ifdef PLATFORM_POSIX
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 81 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
#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 <spawn.h>
#include <sys/wait.h>
extern char **environ;
int Platform__system(const char *cmd) {
char *argv[] = {"sh", "-c", (char *) cmd, NULL};
pid_t pid;
int status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
if (status == 0) {
if (waitpid(pid, &status, 0) != -1) return status;
internal_error("waitpid failed");
} else {
WRITE_TO(STDERR, "posix_spawn: %s\n", strerror(status));
internal_error("posix_spawn failed");
}
return -1;
}
#endif /* PLATFORM_MACOS */
#endif /* PLATFORM_POSIX */
#ifdef PLATFORM_POSIX
#line 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; a<NO_DEFINED_DA_VALUES; a++) {
debugging_aspect *da = &(the_debugging_aspects[a]);
da->hyphenated_name = Str__new();
da->unhyphenated_name = Str__new();
da->negated_name = Str__new();
da->on_or_off = FALSE;
da->alternate = FALSE;
}
}
#line 67 "inweb/foundation-module/Chapter 2/Debugging Log.w"
;
}
if ((a < 0) || (a >= NO_DEFINED_DA_VALUES)) internal_error("aspect out of range");
debugging_aspect *da = &(the_debugging_aspects[a]);
{
#line 86 "inweb/foundation-module/Chapter 2/Debugging Log.w"
WRITE_TO(da->negated_name, "no-");
for (int i=0; name[i]; i++) {
wchar_t c = name[i];
PUT_TO(da->unhyphenated_name, c);
if (Characters__is_space_or_tab(c)) c = '-';
PUT_TO(da->hyphenated_name, c);
PUT_TO(da->negated_name, c);
}
da->on_or_off = def;
da->alternate = alt;
}
#line 72 "inweb/foundation-module/Chapter 2/Debugging Log.w"
;
}
#line 109 "inweb/foundation-module/Chapter 2/Debugging Log.w"
filename *debug_log_filename = NULL;
filename *Log__get_debug_log_filename(void) {
return debug_log_filename;
}
void Log__set_debug_log_filename(filename *F) {
debug_log_filename = F;
}
int Log__open(void) {
if ((debug_log_filename) && (DL == NULL)) {
if (STREAM_OPEN_TO_FILE(debug_log_file, debug_log_filename, ISO_ENC) == FALSE)
return FALSE;
DL = debug_log_file;
Streams__enable_debugging(DL);
LOG("Debugging log of %s\n", 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; a<NO_DEFINED_DA_VALUES; a++) {
debugging_aspect *da = &(the_debugging_aspects[a]);
da->on_or_off = new_state;
}
}
#line 210 "inweb/foundation-module/Chapter 2/Debugging Log.w"
int Log__set_aspect_from_command_line(text_stream *name, int give_error) {
int list_mode = FALSE;
if (Str__eq_wide_string(name, L"everything")) { Log__set_all_aspects(TRUE); return TRUE; }
if (Str__eq_wide_string(name, L"nothing")) { Log__set_all_aspects(FALSE); return TRUE; }
if (Str__eq_wide_string(name, L"list")) list_mode = TRUE;
for (int i=0; i<NO_DEFINED_DA_VALUES; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
if (Str__eq(name, da->negated_name)) {
da->on_or_off = FALSE; return TRUE;
}
if ((Str__eq(name, da->hyphenated_name)) ||
(Str__eq(name, da->unhyphenated_name))) {
da->on_or_off = TRUE; return TRUE;
}
if ((list_mode) && (Str__len(da->hyphenated_name) > 0)) {
PRINT("--log %S (%s)\n", da->hyphenated_name, (da->on_or_off)?"on":"off");
}
}
if ((list_mode == FALSE) && (give_error))
PRINT("No such debugging log aspect as '%S'.\n"
"(Try running -log list for a list of the valid aspects.)\n", name);
if (list_mode == TRUE) return TRUE;
return FALSE;
}
#line 241 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__tracing_on(int starred, text_stream *heading) {
if (starred) {
LOG("\n*** Entering sentence trace mode: %S ***\n", heading);
} else {
LOG("\n*** Leaving sentence trace mode: %S ***\n\n", heading);
}
for (int i=0; i<NO_DEFINED_DA_VALUES; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
int j = da->on_or_off;
da->on_or_off = da->alternate;
da->alternate = j;
}
}
#line 261 "inweb/foundation-module/Chapter 2/Debugging Log.w"
void Log__show_debugging_settings_with_state(int state) {
int c = 0;
for (int i=0; i<NO_DEFINED_DA_VALUES; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
if (da->on_or_off == state) {
c++;
LOG(" %S", da->hyphenated_name);
if (c % 6 == 0) LOG("\n");
}
}
if (c == 0) { LOG(" (nothing)\n"); } else { LOG("\n"); }
}
void Log__show_debugging_contents(void) {
if (Log__aspect_switched_on(DEBUGGING_LOG_INCLUSIONS_DA) == FALSE) return;
LOG("\n\nThat concludes the debugging log from this run.\n"
"Its contents were as follows -\n\n");
LOG("Included:\n"); Log__show_debugging_settings_with_state(TRUE);
LOG("Omitted:\n"); Log__show_debugging_settings_with_state(FALSE);
}
#line 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<NO_DEFINED_MT_VALUES; i++) {
alloc_status[i].first_in_memory = NULL;
alloc_status[i].last_in_memory = NULL;
alloc_status[i].objects_allocated = 0;
alloc_status[i].objects_count = 0;
alloc_status[i].bytes_allocated = 0;
alloc_status[i].no_allocated_together = 1;
alloc_status[i].name_of_type = "unused";
}
Memory__name_fundamental_reasons();
}
#line 160 "inweb/foundation-module/Chapter 2/Memory.w"
int no_blocks_allocated = 0;
int total_objects_allocated = 0; /* a potentially larger number, used only for the debugging log */
#line 174 "inweb/foundation-module/Chapter 2/Memory.w"
#line 176 "inweb/foundation-module/Chapter 2/Memory.w"
memblock_header *first_memblock_header = NULL; /* head of list of memory blocks */
memblock_header *current_memblock_header = NULL; /* tail of list of memory blocks */
int used_in_current_memblock = 0; /* number of bytes so far used in the tail memory block */
#line 185 "inweb/foundation-module/Chapter 2/Memory.w"
void Memory__allocate_another_block(void) {
unsigned char *cp;
memblock_header *mh;
{
#line 202 "inweb/foundation-module/Chapter 2/Memory.w"
int i;
if (no_blocks_allocated++ >= 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; i<MEMORY_GRANULARITY; i++) cp[i] = 0;
}
#line 189 "inweb/foundation-module/Chapter 2/Memory.w"
;
mh = (memblock_header *) cp;
used_in_current_memblock = sizeof(memblock_header) + SAFETY_MARGIN;
mh->the_memory = (void *) (cp + used_in_current_memblock);
{
#line 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<NO_DEFINED_MREASON_VALUES; i++) {
max_memory_at_once_for_each_need[i] = 0;
memory_claimed_for_each_need[i] = 0;
number_of_claims_for_each_need[i] = 0;
}
}
#line 635 "inweb/foundation-module/Chapter 2/Memory.w"
;
{
#line 647 "inweb/foundation-module/Chapter 2/Memory.w"
if (N > 0) {
pointer = Memory__paranoid_calloc((size_t) N, (size_t) S);
bytes_needed = N*S;
} else {
pointer = Memory__paranoid_calloc(1, (size_t) S);
bytes_needed = S;
}
if (pointer == NULL) {
Errors__fatal_with_C_string("Out of memory for %s", Memory__description_of_reason(R));
}
}
#line 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<NO_DEFINED_MREASON_VALUES; i++) {
t += max_memory_at_once_for_each_need[i];
if (total > 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; i<NO_DEFINED_MT_VALUES; i++) sorted_usage[i] = i;
qsort(sorted_usage, (size_t) NO_DEFINED_MT_VALUES, sizeof(int), Memory__compare_usage);
}
#line 768 "inweb/foundation-module/Chapter 2/Memory.w"
;
int total_for_objects_used = 0; /* out of the |total_for_objects|, the bytes used */
int total_objects = 0;
{
#line 778 "inweb/foundation-module/Chapter 2/Memory.w"
int i, j;
for (j=0; j<NO_DEFINED_MT_VALUES; j++) {
i = sorted_usage[j];
if (alloc_status[i].objects_allocated != 0) {
if (alloc_status[i].no_allocated_together == 1)
total_objects += alloc_status[i].objects_allocated;
else
total_objects += alloc_status[i].objects_allocated*
alloc_status[i].no_allocated_together;
total_for_objects_used += alloc_status[i].bytes_allocated;
}
}
}
#line 772 "inweb/foundation-module/Chapter 2/Memory.w"
;
int overhead_for_objects = total_for_objects - total_for_objects_used; /* bytes wasted */
{
#line 802 "inweb/foundation-module/Chapter 2/Memory.w"
LOG("\nReport by memory manager:\n\n");
LOG("Total consumption was %dK = %dMB, divided up in the following proportions:\n",
total, (total+512)/1024);
LOG("0.%03d: %d objects in %d frames in %d memory blocks (of %dK each):\n",
Memory__proportion(total_for_objects, total),
total_objects, total_objects_allocated, no_blocks_allocated, MEMORY_GRANULARITY/1024);
LOG(" 0.%03d: memory manager overhead - %d bytes\n",
Memory__proportion(overhead_for_objects, total), overhead_for_objects);
int i, j;
for (j=0; j<NO_DEFINED_MT_VALUES; j++) {
i = sorted_usage[j];
if (alloc_status[i].objects_allocated != 0) {
LOG(" 0.%03d: %s - ",
Memory__proportion(alloc_status[i].bytes_allocated, total),
alloc_status[i].name_of_type);
if (alloc_status[i].no_allocated_together == 1) {
LOG("%d ", alloc_status[i].objects_count);
if (alloc_status[i].objects_count != alloc_status[i].objects_allocated)
LOG("(+%d deleted) ",
alloc_status[i].objects_allocated - alloc_status[i].objects_count);
} else LOG("%d blocks of %d = %d ",
alloc_status[i].objects_allocated, alloc_status[i].no_allocated_together,
alloc_status[i].objects_allocated*alloc_status[i].no_allocated_together);
LOG("objects, %d bytes\n", alloc_status[i].bytes_allocated);
}
}
Memory__log_usage(total);
}
#line 774 "inweb/foundation-module/Chapter 2/Memory.w"
;
}
#line 832 "inweb/foundation-module/Chapter 2/Memory.w"
int Memory__compare_usage(const void *ent1, const void *ent2) {
int ix1 = *((const int *) ent1);
int ix2 = *((const int *) ent2);
return alloc_status[ix2].bytes_allocated - alloc_status[ix1].bytes_allocated;
}
#line 842 "inweb/foundation-module/Chapter 2/Memory.w"
int Memory__proportion(int bytes, int total) {
float B = (float) bytes, T = (float) total;
float P = (1000*B)/(1024*T);
return (int) P;
}
#line 849 "inweb/foundation-module/Chapter 2/Memory.w"
void *Memory__paranoid_calloc(size_t N, size_t S) {
CREATE_MUTEX(mutex);
LOCK_MUTEX(mutex);
void *P = calloc(N, S);
UNLOCK_MUTEX(mutex);
return P;
}
#line 883 "inweb/foundation-module/Chapter 2/Memory.w"
general_pointer Memory__store_gp_null(void) {
general_pointer gp;
gp.pointer_to_data = NULL;
gp.run_time_type_code = -1; /* guaranteed to differ from all |_MT| values */
return gp;
}
int Memory__test_gp_null(general_pointer gp) {
if (gp.run_time_type_code == -1) return TRUE;
return FALSE;
}
#line 942 "inweb/foundation-module/Chapter 2/Memory.w"
MAKE_REFERENCE_ROUTINES(char, 1000)
#line 243 "inweb/foundation-module/Chapter 2/Streams.w"
#line 258 "inweb/foundation-module/Chapter 2/Streams.w"
int total_file_writes = 0; /* number of text files opened for writing during the run */
#line 272 "inweb/foundation-module/Chapter 2/Streams.w"
void Streams__initialise(text_stream *stream, int from) {
if (stream == NULL) internal_error("tried to initialise NULL stream");
stream->stream_flags = from;
stream->write_to_file = NULL;
stream->write_to_memory = NULL;
stream->chars_written = 0;
stream->chars_capacity = 2147483647;
stream->stream_continues = NULL;
stream->as_HTML = NULL;
stream->file_written = NULL;
}
#line 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; j<stream->chars_written; j++) {
if (i >= buffer_size-1) break;
C_string[i++] = stream->write_to_memory[j];
}
stream = stream->stream_continues;
}
C_string[i] = 0;
}
#line 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; j<stream->chars_written; j++) {
if (i >= buffer_size-1) break;
wchar_t c = stream->write_to_memory[j];
if (c < 256) C_string[i++] = (char) c; else C_string[i++] = '?';
}
stream = stream->stream_continues;
}
C_string[i] = 0;
}
#line 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; j<stream->chars_written; j++) {
unsigned int c = (unsigned int) stream->write_to_memory[j];
if (c >= 0x800) {
if (i >= buffer_size-3) break;
to[i++] = 0xE0 + (unsigned char) (c >> 12);
to[i++] = 0x80 + (unsigned char) ((c >> 6) & 0x3f);
to[i++] = 0x80 + (unsigned char) (c & 0x3f);
} else if (c >= 0x80) {
if (i >= buffer_size-2) break;
to[i++] = 0xC0 + (unsigned char) (c >> 6);
to[i++] = 0x80 + (unsigned char) (c & 0x3f);
} else {
if (i >= buffer_size-1) break;
to[i++] = (unsigned char) c;
}
}
stream = stream->stream_continues;
}
to[i] = 0;
}
#line 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; i<L; i++) {
Streams__putc(' ', first_stream); Streams__putc(' ', first_stream);
Streams__putc(' ', first_stream); Streams__putc(' ', first_stream);
}
}
}
#line 697 "inweb/foundation-module/Chapter 2/Streams.w"
;
if (stream->stream_flags & READ_ONLY_STRF) internal_error("modifying read-only stream");
if ((stream->stream_flags) & USES_XML_ESCAPES_STRF) {
switch(c) {
case NEWLINE_IN_STRING: Streams__literal(stream, "<br>"); return;
case '&': Streams__literal(stream, "&amp;"); return;
case '<': Streams__literal(stream, "&lt;"); return;
case '>': Streams__literal(stream, "&gt;"); return;
}
}
while (stream->stream_continues) stream = stream->stream_continues;
{
#line 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; i<from->chars_written; i++) {
int c = (int) ((from->write_to_memory)[i]);
Streams__putc(c, to);
}
if (from->stream_continues) Streams__copy(to, from->stream_continues);
}
}
#line 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; i<S; i++) {
D->hash_table[i].vacant = TRUE;
D->hash_table[i].value = NULL;
D->hash_table[i].next_in_entry = NULL;
}
return D;
}
#line 51 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void Dictionaries__log(OUTPUT_STREAM, dictionary *D) {
WRITE("Dictionary:\n", (unsigned int) D); INDENT;
for (int i=0; i<D->hash_table_size; i++) {
WRITE("Slot %02d:", i);
for (dict_entry *E = &(D->hash_table[i]); E; E = E->next_in_entry)
if (E->vacant) WRITE(" vacant");
else if (D->textual) WRITE(" %S='%S'", E->key, E->value);
else WRITE(" %S=%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; i<D->hash_table_size; i++)
for (dict_entry *E = &(D->hash_table[i]); E; E = E->next_in_entry)
if (E->vacant == FALSE) {
dict_entry *E2 = Dictionaries__find_p(D2, E->key, 1);
E2->value = E->value;
}
Memory__I7_free(D->hash_table, DICTIONARY_MREASON,
D->hash_table_size*((int) sizeof(dict_entry)));
D->hash_table_size = D2->hash_table_size;
D->hash_table = D2->hash_table;
}
}
#line 127 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
{
#line 158 "inweb/foundation-module/Chapter 2/Dictionaries.w"
dict_entry *last_E = NULL;
for (dict_entry *E = &(D->hash_table[Dictionaries__hash(K, D->hash_table_size)]);
E; E = E->next_in_entry) {
last_E = E;
if (E->vacant) {
if (change == 1) {
{
#line 183 "inweb/foundation-module/Chapter 2/Dictionaries.w"
E->vacant = FALSE;
if (D->textual) E->value = Str__new(); else E->value = NULL;
E->key = Str__duplicate(K);
D->no_entries++;
}
#line 163 "inweb/foundation-module/Chapter 2/Dictionaries.w"
; return E; }
} else {
if (Str__eq(K, E->key)) {
if (change == -1)
{
#line 193 "inweb/foundation-module/Chapter 2/Dictionaries.w"
E->vacant = TRUE; D->no_entries--;
if ((D->textual) && (E->value)) Str__dispose_of(E->value);
E->value = NULL;
}
#line 166 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
return E;
}
}
}
if (change == 1) {
dict_entry *E = CREATE(dict_entry);
{
#line 183 "inweb/foundation-module/Chapter 2/Dictionaries.w"
E->vacant = FALSE;
if (D->textual) E->value = Str__new(); else E->value = NULL;
E->key = Str__duplicate(K);
D->no_entries++;
}
#line 173 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
last_E->next_in_entry = E;
return E;
}
return NULL;
}
#line 128 "inweb/foundation-module/Chapter 2/Dictionaries.w"
;
}
#line 202 "inweb/foundation-module/Chapter 2/Dictionaries.w"
void *Dictionaries__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; i<D->hash_table_size; i++)
for (dict_entry *E = &(D->hash_table[i]); E; E = E->next_in_entry)
if (E->vacant == FALSE)
Str__dispose_of(E->value);
Memory__I7_free(D->hash_table, DICTIONARY_MREASON, D->hash_table_size*((int) sizeof(dict_entry)));
D->hash_table = NULL;
}
#line 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; i<argc; i++) {
int switched = FALSE;
char *p = argv[i];
while (p[0] == '-') { p++; switched = TRUE; } /* allow a doubled-dash as a single */
TEMPORARY_TEXT(opt);
Streams__write_locale_string(opt, p);
TEMPORARY_TEXT(arg);
if (i+1 < argc) Streams__write_locale_string(arg, argv[i+1]);
if (switched) {
int N = CommandLine__read_pair(crs, opt, arg);
if (N == 0)
Errors__fatal_with_text("unknown command line switch: -%S", opt);
i += N - 1;
} else {
CommandLine__read_one(crs, opt);
}
DISCARD_TEXT(opt);
DISCARD_TEXT(arg);
}
}
#line 215 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
filename *command_line_file = NULL;
void CommandLine__also_read_file(filename *F) {
command_line_file = F;
}
#line 226 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
linked_list *command_line_logs = NULL;
void CommandLine__record_log(text_stream *line) {
if (command_line_logs == NULL)
command_line_logs = NEW_LINKED_LIST(text_stream);
ADD_TO_LINKED_LIST(line, text_stream, command_line_logs);
}
void CommandLine__play_back_log(void) {
if (command_line_logs) {
text_stream *line;
LOOP_OVER_LINKED_LIST(line, text_stream, command_line_logs)
LOG("%S\n", line);
}
}
#line 250 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
void CommandLine__read_file(clf_reader_state *crs) {
text_stream *logline = Str__new();
WRITE_TO(logline, "Reading further switches from file: %f", command_line_file);
CommandLine__record_log(logline);
if (command_line_file)
TextFiles__read(command_line_file, FALSE,
NULL, FALSE, CommandLine__read_file_helper, NULL, (void *) crs);
command_line_file = NULL;
text_stream *lastline = Str__new();
WRITE_TO(lastline, "Completed expert settings file");
CommandLine__record_log(lastline);
}
void CommandLine__read_file_helper(text_stream *text, text_file_position *tfp, void *state) {
clf_reader_state *crs = (clf_reader_state *) state;
match_results mr = Regexp__create_mr();
if ((Str__is_whitespace(text)) || (Regexp__match(&mr, text, L" *#%c*"))) {
;
} else {
text_stream *logline = Str__new();
WRITE_TO(logline, "line %d: %S", tfp->line_count, text);
CommandLine__record_log(logline);
if (Regexp__match(&mr, text, L" *-*(%C+) (%c+?) *")) {
int N = CommandLine__read_pair(crs, mr.exp[0], mr.exp[1]);
if (N == 0)
Errors__fatal_with_text("unknown command line switch: -%S", mr.exp[0]);
if (N == 1)
Errors__fatal_with_text("command line switch does not take value: -%S", mr.exp[0]);
} else if (Regexp__match(&mr, text, L" *-*(%C+) *")) {
int N = CommandLine__read_pair(crs, mr.exp[0], NULL);
if (N == 0)
Errors__fatal_with_text("unknown command line switch: -%S", mr.exp[0]);
if (N == 2)
Errors__fatal_with_text("command line switch requires value: -%S", mr.exp[0]);
} else {
Errors__in_text_file("illegible line in expert settings file", tfp);
WRITE_TO(STDERR, "'%S'\n", text);
}
}
Regexp__dispose_of(&mr);
}
void CommandLine__read_one(clf_reader_state *crs, text_stream *opt) {
(*(crs->g))(crs->nrt++, opt, crs->state);
crs->subs = TRUE;
}
#line 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-alpha.1+1A19";
if (svn[0]) PRINT(" version %s", svn);
char *vname = "Escape to Danger";
if (vname[0]) PRINT(" '%s'", vname);
char *d = "13 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; i<N; i++) {
command_line_switch *cls = sorted_table[i];
if (cls->switch_group != filter) continue;
if ((cls->form == BOOLEAN_OFF_CLSF) || (cls->form == BOOLEAN_ON_CLSF)) {
if (cls->active_by_default) continue;
}
text_stream *label = switch_group_names[filter];
if (new_para_needed == FALSE) {
if (Str__len(label) > 0) WRITE("%S:\n", label);
new_para_needed = TRUE;
}
TEMPORARY_TEXT(line);
if (Str__len(label) > 0) WRITE_TO(line, " ");
WRITE_TO(line, "-%S", cls->switch_name);
if (cls->form == NUMERICAL_CLSF) WRITE_TO(line, "=N");
if (cls->form == TEXTUAL_CLSF) WRITE_TO(line, "=X");
if (cls->valency > 1) WRITE_TO(line, " X");
while (Str__len(line) < max+7) WRITE_TO(line, " ");
WRITE_TO(line, "%S", cls->help_text);
if (cls->form == BOOLEAN_ON_CLSF)
WRITE_TO(line, " (default is -no-%S)", cls->switch_name);
if (cls->form == BOOLEAN_OFF_CLSF)
WRITE_TO(line, " (default is -%S)", cls->negates->switch_name);
WRITE("%S\n", line);
DISCARD_TEXT(line);
}
}
#line 433 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
;
for (filter = NO_CLSG; filter<NO_DEFINED_CLSG_VALUES; filter++)
if ((filter != NO_CLSG) && (filter != FOUNDATION_CLSG))
{
#line 444 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
if (new_para_needed) {
WRITE("\n");
new_para_needed = FALSE;
}
for (int i=0; i<N; i++) {
command_line_switch *cls = sorted_table[i];
if (cls->switch_group != filter) continue;
if ((cls->form == BOOLEAN_OFF_CLSF) || (cls->form == BOOLEAN_ON_CLSF)) {
if (cls->active_by_default) continue;
}
text_stream *label = switch_group_names[filter];
if (new_para_needed == FALSE) {
if (Str__len(label) > 0) WRITE("%S:\n", label);
new_para_needed = TRUE;
}
TEMPORARY_TEXT(line);
if (Str__len(label) > 0) WRITE_TO(line, " ");
WRITE_TO(line, "-%S", cls->switch_name);
if (cls->form == NUMERICAL_CLSF) WRITE_TO(line, "=N");
if (cls->form == TEXTUAL_CLSF) WRITE_TO(line, "=X");
if (cls->valency > 1) WRITE_TO(line, " X");
while (Str__len(line) < max+7) WRITE_TO(line, " ");
WRITE_TO(line, "%S", cls->help_text);
if (cls->form == BOOLEAN_ON_CLSF)
WRITE_TO(line, " (default is -no-%S)", cls->switch_name);
if (cls->form == BOOLEAN_OFF_CLSF)
WRITE_TO(line, " (default is -%S)", cls->negates->switch_name);
WRITE("%S\n", line);
DISCARD_TEXT(line);
}
}
#line 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; i<N; i++) {
command_line_switch *cls = sorted_table[i];
if (cls->switch_group != filter) continue;
if ((cls->form == BOOLEAN_OFF_CLSF) || (cls->form == BOOLEAN_ON_CLSF)) {
if (cls->active_by_default) continue;
}
text_stream *label = switch_group_names[filter];
if (new_para_needed == FALSE) {
if (Str__len(label) > 0) WRITE("%S:\n", label);
new_para_needed = TRUE;
}
TEMPORARY_TEXT(line);
if (Str__len(label) > 0) WRITE_TO(line, " ");
WRITE_TO(line, "-%S", cls->switch_name);
if (cls->form == NUMERICAL_CLSF) WRITE_TO(line, "=N");
if (cls->form == TEXTUAL_CLSF) WRITE_TO(line, "=X");
if (cls->valency > 1) WRITE_TO(line, " X");
while (Str__len(line) < max+7) WRITE_TO(line, " ");
WRITE_TO(line, "%S", cls->help_text);
if (cls->form == BOOLEAN_ON_CLSF)
WRITE_TO(line, " (default is -no-%S)", cls->switch_name);
if (cls->form == BOOLEAN_OFF_CLSF)
WRITE_TO(line, " (default is -%S)", cls->negates->switch_name);
WRITE("%S\n", line);
DISCARD_TEXT(line);
}
}
#line 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 205 "inweb/foundation-module/Chapter 3/Pathnames.w"
void Pathnames__relative_URL(OUTPUT_STREAM, pathname *from, pathname *to) {
TEMPORARY_TEXT(url);
int found = FALSE;
for (pathname *P = to; P && (found == FALSE); P = Pathnames__up(P)) {
TEMPORARY_TEXT(PT);
WRITE_TO(PT, "%p", P);
int q_up_count = 0;
for (pathname *Q = from; Q && (found == FALSE); Q = Pathnames__up(Q)) {
TEMPORARY_TEXT(QT);
WRITE_TO(QT, "%p", Q);
if (Str__eq(PT, QT)) {
for (int i=0; i<q_up_count; i++) WRITE_TO(url, "../");
TEMPORARY_TEXT(FPT);
WRITE_TO(FPT, "%p", to);
Str__substr(url, Str__at(FPT, Str__len(PT) + 1), Str__end(FPT));
found = TRUE;
}
DISCARD_TEXT(QT);
q_up_count++;
}
DISCARD_TEXT(PT);
}
if (found == FALSE) {
for (pathname *Q = from; Q; Q = Pathnames__up(Q)) WRITE_TO(url, "../");
WRITE_TO(url, "%p", to);
}
WRITE("%S", url);
if ((Str__len(url) > 0) && (Str__get_last_char(url) != '/')) WRITE("/");
DISCARD_TEXT(url);
}
#line 241 "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 259 "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("<no file>");
else {
if (F->pathname_of_location) {
Pathnames__writer(OUT, format_string, (void *) F->pathname_of_location);
if (format_string[0] == '/') PUT('/');
else PUT(FOLDER_SEPARATOR);
}
WRITE("%S", F->leafname);
}
}
#line 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 175 "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 211 "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 231 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
FILE *CIFilingSystem__fopen(const char *path, const char *mode) {
return fopen(path, mode);
}
#endif /* PLATFORM_POSIX */
#line 14 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__quote_path(OUTPUT_STREAM, pathname *P) {
TEMPORARY_TEXT(FN);
WRITE_TO(FN, "%p", P);
Shell__quote_text(OUT, FN);
DISCARD_TEXT(FN);
}
void Shell__quote_file(OUTPUT_STREAM, filename *F) {
TEMPORARY_TEXT(FN);
WRITE_TO(FN, "%f", F);
Shell__quote_text(OUT, FN);
DISCARD_TEXT(FN);
}
void Shell__plain(OUTPUT_STREAM, char *raw) {
WRITE("%s", raw);
}
void Shell__plain_text(OUTPUT_STREAM, text_stream *raw) {
WRITE("%S", raw);
}
void Shell__quote_text(OUTPUT_STREAM, text_stream *raw) {
PUT(SHELL_QUOTE_CHARACTER);
LOOP_THROUGH_TEXT(pos, raw) {
wchar_t c = Str__get(pos);
if (c == SHELL_QUOTE_CHARACTER) PUT('\\');
PUT(c);
}
PUT(SHELL_QUOTE_CHARACTER);
PUT(' ');
}
#line 50 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__apply(char *command, filename *F) {
TEMPORARY_TEXT(COMMAND)
Shell__plain(COMMAND, command);
Shell__plain(COMMAND, " ");
Shell__quote_file(COMMAND, F);
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
void Shell__apply_S(text_stream *command, filename *F) {
TEMPORARY_TEXT(COMMAND)
Shell__plain_text(COMMAND, command);
Shell__plain(COMMAND, " ");
Shell__quote_file(COMMAND, F);
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
#line 70 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__rm(filename *F) {
Shell__apply("rm", F);
}
void Shell__copy(filename *F, pathname *T, char *options) {
TEMPORARY_TEXT(COMMAND)
Shell__plain(COMMAND, "cp ");
Shell__plain(COMMAND, options);
Shell__plain(COMMAND, " ");
Shell__quote_file(COMMAND, F);
Shell__quote_path(COMMAND, T);
Shell__run(COMMAND);
DISCARD_TEXT(COMMAND)
}
#line 89 "inweb/foundation-module/Chapter 3/Shell.w"
void Shell__redirect(OUTPUT_STREAM, filename *F) {
Shell__plain(OUT, ">");
Shell__quote_file(OUT, F);
Shell__plain(OUT, "2>&1");
}
#line 105 "inweb/foundation-module/Chapter 3/Shell.w"
int shell_verbosity = FALSE;
void Shell__verbose(void) {
shell_verbosity = TRUE;
}
int Shell__run(OUTPUT_STREAM) {
if (shell_verbosity) PRINT("shell: %S\n", OUT);
LOGIF(SHELL_USAGE, "shell: %S\n", OUT);
char spool[SPOOL_LENGTH];
Streams__write_as_locale_string(spool, OUT, SPOOL_LENGTH);
if (debugger_mode) {
WRITE_TO(STDOUT, "debugger mode suppressing shell command: %S\n", OUT);
return 0;
}
int rv = Platform__system(spool);
if (rv == -1) {
WRITE_TO(STDERR, "shell: %S\n", OUT);
internal_error("OS shell error");
}
if (rv == 127) {
WRITE_TO(STDERR, "shell: %S\n", OUT);
internal_error("Execution of the shell failed");
}
return rv;
}
#line 13 "inweb/foundation-module/Chapter 3/Directories.w"
#line 19 "inweb/foundation-module/Chapter 3/Directories.w"
scan_directory *Directories__open(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<max-1)); i++) to[i] = from[i];
to[i] = 0;
}
#line 14 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__len(wchar_t *p) {
return (int) wcslen(p);
}
#line 21 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__cmp(wchar_t *A, wchar_t *B) {
return wcscmp(A, B);
}
#line 26 "inweb/foundation-module/Chapter 4/Wide Strings.w"
int Wide__atoi(wchar_t *p) {
return (int) wcstol(p, NULL, 10);
}
#line 38 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__new(void) {
return Str__new_with_capacity(32);
}
text_stream *Str__new_with_capacity(int c) {
text_stream *S = CREATE(text_stream);
if (Streams__open_to_memory(S, c)) return S;
return NULL;
}
void Str__dispose_of(text_stream *text) {
if (text) STREAM_CLOSE(text);
}
#line 57 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__duplicate(text_stream *E) {
if (E == NULL) return Str__new();
text_stream *S = CREATE(text_stream);
if (Streams__open_to_memory(S, Str__len(E)+4)) {
Streams__copy(S, E);
return S;
}
return NULL;
}
#line 73 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__new_from_wide_string(wchar_t *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_wide_string(S, C_string)) return S;
return NULL;
}
text_stream *Str__new_from_ISO_string(char *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_ISO_string(S, C_string)) return S;
return NULL;
}
text_stream *Str__new_from_UTF8_string(char *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_UTF8_string(S, C_string)) return S;
return NULL;
}
text_stream *Str__new_from_locale_string(char *C_string) {
text_stream *S = CREATE(text_stream);
if (Streams__open_from_locale_string(S, C_string)) return S;
return NULL;
}
#line 100 "inweb/foundation-module/Chapter 4/String Manipulation.w"
text_stream *Str__from_wide_string(text_stream *S, wchar_t *c_string) {
if (Streams__open_from_wide_string(S, c_string) == FALSE) return NULL;
return S;
}
text_stream *Str__from_locale_string(text_stream *S, char *c_string) {
if (Streams__open_from_locale_string(S, c_string) == FALSE) return NULL;
return S;
}
#line 113 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__copy_to_ISO_string(char *C_string, text_stream *S, int buffer_size) {
Streams__write_as_ISO_string(C_string, S, buffer_size);
}
void Str__copy_to_UTF8_string(char *C_string, text_stream *S, int buffer_size) {
Streams__write_as_UTF8_string(C_string, S, buffer_size);
}
void Str__copy_to_wide_string(wchar_t *C_string, text_stream *S, int buffer_size) {
Streams__write_as_wide_string(C_string, S, buffer_size);
}
void Str__copy_to_locale_string(char *C_string, text_stream *S, int buffer_size) {
Streams__write_as_locale_string(C_string, S, buffer_size);
}
#line 132 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__atoi(text_stream *S, int index) {
char buffer[32];
int i = 0;
for (string_position P = Str__at(S, index);
((i < 31) && (P.index < Str__len(S))); P = Str__forward(P))
buffer[i++] = (char) Str__get(P);
buffer[i] = 0;
return atoi(buffer);
}
#line 146 "inweb/foundation-module/Chapter 4/String Manipulation.w"
int Str__len(text_stream *S) {
return Streams__get_position(S);
}
#line 163 "inweb/foundation-module/Chapter 4/String Manipulation.w"
#line 167 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__start(text_stream *S) {
string_position P; P.S = S; P.index = 0; return P;
}
string_position Str__at(text_stream *S, int i) {
if (i < 0) i = 0;
if (i > Str__len(S)) i = Str__len(S);
string_position P; P.S = S; P.index = i; return P;
}
string_position Str__end(text_stream *S) {
string_position P; P.S = S; P.index = Str__len(S); return P;
}
#line 184 "inweb/foundation-module/Chapter 4/String Manipulation.w"
string_position Str__back(string_position P) {
if (P.index > 0) P.index--; return P;
}
string_position Str__forward(string_position P) {
P.index++; return P;
}
string_position Str__plus(string_position P, int increment) {
P.index += increment; return P;
}
int Str__width_between(string_position P1, string_position P2) {
if (P1.S != P2.S) internal_error("positions are in different strings");
return P2.index - P1.index;
}
int Str__in_range(string_position P) {
if (P.index < Str__len(P.S)) return TRUE;
return FALSE;
}
int Str__index(string_position P) {
return P.index;
}
#line 222 "inweb/foundation-module/Chapter 4/String Manipulation.w"
wchar_t Str__get(string_position P) {
if ((P.S == NULL) || (P.index < 0)) return 0;
return Streams__get_char_at_index(P.S, P.index);
}
wchar_t Str__get_at(text_stream *S, int index) {
if ((S == NULL) || (index < 0)) return 0;
return Streams__get_char_at_index(S, index);
}
wchar_t Str__get_first_char(text_stream *S) {
return Str__get(Str__at(S, 0));
}
wchar_t Str__get_last_char(text_stream *S) {
int L = Str__len(S);
if (L == 0) return 0;
return Str__get(Str__at(S, L-1));
}
#line 243 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__put(string_position P, wchar_t C) {
if (P.index < 0) internal_error("wrote before start of string");
if (P.S == NULL) internal_error("wrote to null stream");
int ext = Str__len(P.S);
if (P.index > ext) internal_error("wrote beyond end of string");
if (P.index == ext) {
if (C) PUT_TO(P.S, (int) C);
return;
}
Streams__put_char_at_index(P.S, P.index, C);
}
void Str__put_at(text_stream *S, int index, wchar_t C) {
Str__put(Str__at(S, index), C);
}
#line 262 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__clear(text_stream *S) {
Str__truncate(S, 0);
}
void Str__truncate(text_stream *S, int len) {
if (len < 0) len = 0;
if (len < Str__len(S)) Str__put(Str__at(S, len), 0);
}
#line 274 "inweb/foundation-module/Chapter 4/String Manipulation.w"
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<N; i++)
if (Str__get_at(S1, i) != Str__get_at(S2, i))
return FALSE;
return TRUE;
}
int Str__suffix_eq(text_stream *S1, text_stream *S2, int N) {
int L1 = Str__len(S1), L2 = Str__len(S2);
if ((N > L1) || (N > L2)) return FALSE;
for (int i=1; i<=N; i++)
if (Str__get_at(S1, L1-i) != Str__get_at(S2, L2-i))
return FALSE;
return TRUE;
}
int Str__begins_with_wide_string(text_stream *S, wchar_t *prefix) {
if ((prefix == NULL) || (*prefix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0; prefix[i]; i++)
if (Str__get_at(S, i) != prefix[i])
return FALSE;
return TRUE;
}
int Str__ends_with_wide_string(text_stream *S, wchar_t *suffix) {
if ((suffix == NULL) || (*suffix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0, at = Str__len(S) - (int) wcslen(suffix); suffix[i]; i++)
if (Str__get_at(S, at+i) != suffix[i])
return FALSE;
return TRUE;
}
#line 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; i<L; i++)
Str__put(Str__at(S, i), Str__get(Str__at(S, i+n)));
Str__truncate(S, L);
}
}
#line 524 "inweb/foundation-module/Chapter 4/String Manipulation.w"
void Str__substr(OUTPUT_STREAM, string_position from, string_position to) {
if (from.S != to.S) internal_error("substr on two different strings");
for (int i = from.index; i < to.index; i++)
PUT(Str__get_at(from.S, i));
}
int Str__includes_character(text_stream *S, wchar_t c) {
if (S)
LOOP_THROUGH_TEXT(pos, S)
if (Str__get(pos) == c)
return TRUE;
return FALSE;
}
int Str__includes_wide_string_at(text_stream *S, wchar_t *prefix, int j) {
if ((prefix == NULL) || (*prefix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0; prefix[i]; i++)
if (Str__get_at(S, i+j) != prefix[i])
return FALSE;
return TRUE;
}
int Str__includes_wide_string_at_insensitive(text_stream *S, wchar_t *prefix, int j) {
if ((prefix == NULL) || (*prefix == 0)) return TRUE;
if (S == NULL) return FALSE;
for (int i = 0; prefix[i]; i++)
if (Characters__tolower(Str__get_at(S, i+j)) != Characters__tolower(prefix[i]))
return FALSE;
return TRUE;
}
int Str__includes(text_stream *S, text_stream *T) {
int LS = Str__len(S);
int LT = Str__len(T);
for (int i=0; i<LS-LT; i++) {
int failed = FALSE;
for (int j=0; j<LT; j++)
if (Str__get_at(S, i+j) != Str__get_at(T, j)) {
failed = TRUE;
break;
}
if (failed == FALSE) return TRUE;
}
return FALSE;
}
int Str__includes_at(text_stream *line, int i, text_stream *pattern) {
if (Str__len(pattern) == 0) return FALSE;
if (i < 0) return FALSE;
if (i + Str__len(pattern) > Str__len(line)) return FALSE;
LOOP_THROUGH_TEXT(pos, pattern)
if (Str__get(pos) != Str__get_at(line, i++))
return FALSE;
return TRUE;
}
#line 592 "inweb/foundation-module/Chapter 4/String Manipulation.w"
dictionary *string_literals_dictionary = NULL;
text_stream *Str__literal(wchar_t *wide_C_string) {
text_stream *answer = NULL;
CREATE_MUTEX(mutex);
LOCK_MUTEX(mutex);
{
#line 604 "inweb/foundation-module/Chapter 4/String Manipulation.w"
if (string_literals_dictionary == NULL)
string_literals_dictionary = Dictionaries__new(100, TRUE);
answer = Dictionaries__get_text_literal(string_literals_dictionary, wide_C_string);
if (answer == NULL) {
Dictionaries__create_literal(string_literals_dictionary, wide_C_string);
answer = Dictionaries__get_text_literal(string_literals_dictionary, wide_C_string);
WRITE_TO(answer, "%w", wide_C_string);
Streams__mark_as_read_only(answer);
}
}
#line 598 "inweb/foundation-module/Chapter 4/String Manipulation.w"
;
UNLOCK_MUTEX(mutex);
return answer;
}
#line 15 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__exists(filename *F) {
FILE *HANDLE = Filenames__fopen(F, "rb");
if (HANDLE == NULL) return FALSE;
fclose(HANDLE);
return TRUE;
}
#line 35 "inweb/foundation-module/Chapter 4/Text Files.w"
#line 39 "inweb/foundation-module/Chapter 4/Text Files.w"
int TextFiles__get_line_count(text_file_position *tfp) {
if (tfp == NULL) return 0;
return tfp->line_count;
}
#line 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 136 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
#line 144 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
match_results Regexp__create_mr(void) {
match_results mr;
mr.no_matched_texts = 0;
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++) {
mr.exp[i] = NULL;
mr.exp_at[i] = -1;
}
return mr;
}
void Regexp__dispose_of(match_results *mr) {
if (mr) {
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
if (mr->exp[i]) {
STREAM_CLOSE(mr->exp[i]);
mr->exp[i] = NULL;
}
mr->no_matched_texts = 0;
}
}
#line 168 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match(match_results *mr, text_stream *text, wchar_t *pattern) {
if (mr) Regexp__prepare(mr);
int rv = (Regexp__match_r(mr, text, pattern, NULL, FALSE) >= 0)?TRUE:FALSE;
if ((mr) && (rv == FALSE)) Regexp__dispose_of(mr);
return rv;
}
int Regexp__match_from(match_results *mr, text_stream *text, wchar_t *pattern,
int x, int allow_partial) {
int match_to = x;
if (x < Str__len(text)) {
if (mr) Regexp__prepare(mr);
match_position at;
at.tpos = x; at.ppos = 0; at.bc = 0; at.bl = 0;
match_to = Regexp__match_r(mr, text, pattern, &at, allow_partial);
if (match_to == -1) {
match_to = x;
if (mr) Regexp__dispose_of(mr);
}
}
return match_to - x;
}
void Regexp__prepare(match_results *mr) {
if (mr) {
mr->no_matched_texts = 0;
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++) {
mr->exp_at[i] = -1;
if (mr->exp[i]) STREAM_CLOSE(mr->exp[i]);
mr->exp_storage[i].match_text_struct =
Streams__new_buffer(
MATCH_TEXT_INITIAL_ALLOCATION, mr->exp_storage[i].match_text_storage);
mr->exp_storage[i].match_text_struct.stream_flags |= FOR_RE_STRF;
mr->exp[i] = &(mr->exp_storage[i].match_text_struct);
}
}
}
#line 207 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__match_r(match_results *mr, text_stream *text, wchar_t *pattern,
match_position *scan_from, int allow_partial) {
match_position at;
if (scan_from) at = *scan_from;
else { at.tpos = 0; at.ppos = 0; at.bc = 0; at.bl = 0; }
while ((Str__get_at(text, at.tpos)) || (pattern[at.ppos])) {
if ((allow_partial) && (pattern[at.ppos] == 0)) break;
{
#line 242 "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 215 "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 260 "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 220 "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 268 "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 224 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
int reps = 0;
{
#line 279 "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 227 "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 285 "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 232 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
/* no match length worked, so no match */
return -1;
}
{
#line 294 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
if (mr) {
for (int i=0; i<at.bc; i++) {
Str__clear(mr->exp[i]);
for (int j = at.brackets_start[i]; j <= at.brackets_end[i]; j++)
PUT_TO(mr->exp[i], Str__get_at(text, j));
mr->exp_at[i] = at.brackets_start[i];
}
mr->no_matched_texts = at.bc;
}
}
#line 237 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
;
return at.tpos;
}
#line 337 "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+1;
ppos += 2;
while ((pattern[ppos]) && (pattern[ppos] != ']')) ppos++;
*to = ppos - 1; *len = ppos - *from + 2;
return LITERAL_CLASS;
case ' ':
*len = 1; return WHITESPACE_CLASS;
}
*len = 1; *from = ppos; *to = ppos; return LITERAL_CLASS;
}
#line 367 "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:
if ((range_to > range_from) && (drawn_from[range_from] == '^')) {
range_from++; reverse = reverse?FALSE:TRUE;
}
for (int j = range_from; j <= range_to; j++) {
int c1 = drawn_from[j], c2 = c1;
if ((j+1 < range_to) && (drawn_from[j+1] == '-')) { c2 = drawn_from[j+2]; j += 2; }
if ((c >= c1) && (c <= c2)) {
match = TRUE; break;
}
}
break;
}
if (reverse) match = (match)?FALSE:TRUE;
return match;
}
#line 414 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
int Regexp__replace(text_stream *text, wchar_t *pattern, wchar_t *replacement, int options) {
TEMPORARY_TEXT(altered);
match_results mr = Regexp__create_mr();
int changes = 0;
for (int i=0, L=Str__len(text); i<L; i++) {
match_position mp; mp.tpos = i; mp.ppos = 0; mp.bc = 0; mp.bl = 0;
Regexp__prepare(&mr);
int try = Regexp__match_r(&mr, text, pattern, &mp, TRUE);
if (try >= 0) {
if (replacement)
for (int j=0; replacement[j]; j++) {
int c = replacement[j];
if (c == '%') {
j++;
int ind = replacement[j] - '0';
if ((ind >= 0) && (ind < MAX_BRACKETED_SUBEXPRESSIONS))
WRITE_TO(altered, "%S", mr.exp[ind]);
else
PUT_TO(altered, replacement[j]);
} else {
PUT_TO(altered, replacement[j]);
}
}
int left = L - try;
changes++;
Regexp__dispose_of(&mr);
L = Str__len(text); i = L-left-1;
if ((options & REP_REPEATING) == 0) {
{
#line 453 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
for (i++; i<L; i++)
PUT_TO(altered, Str__get_at(text, i));
}
#line 441 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
; break; }
continue;
} else PUT_TO(altered, Str__get_at(text, i));
if (options & REP_ATSTART) {
{
#line 453 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
for (i++; i<L; i++)
PUT_TO(altered, Str__get_at(text, i));
}
#line 444 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
; break; }
}
Regexp__dispose_of(&mr);
if (changes > 0) Str__copy(text, altered);
DISCARD_TEXT(altered);
return changes;
}
#line 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("</%s>", 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("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ");
WRITE("\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
HTML_OPEN_WITH("html", "xmlns=\"http://www.w3.org/1999/xhtml\"");
} else {
WRITE("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" ");
WRITE("\"http://www.w3.org/TR/html4/loose.dtd\">\n");
HTML_OPEN("html");
}
WRITE("\n");
HTML_OPEN("head");
HTML_TAG_WITH("meta", "http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"");
if (CSS_file)
HTML_TAG_WITH("link", "href=\"%/f\" rel=\"stylesheet\" type=\"text/css\"", CSS_file);
}
void HTML__end_head(OUTPUT_STREAM) {
HTML_CLOSE("head");
}
#line 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");
}
void HTML__close_CSS(OUTPUT_STREAM) {
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("<a href=\"%S\" class=\"%S\"", to, cl);
if (Str__len(ti) > 0) WRITE(" title=\"%S\"", ti);
if (Str__len(on) > 0) WRITE(" onclick=\"%S\"", on);
WRITE(">");
}
void HTML__end_link(OUTPUT_STREAM) {
HTML_CLOSE("a");
}
#line 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("&nbsp;&nbsp;&nbsp;&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_centred(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"center\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"center\" valign=\"top\"");
}
void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" colspan=\"%d\" width=\"%d\"", sp, width)
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" colspan=\"%d\"", sp);
}
void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "style=\"white-space:nowrap;\" align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "style=\"white-space:nowrap;\" align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "style=\"padding-top: 3px;\" align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "style=\"padding-top: 3px;\" align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_nw(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "nowrap=\"nowrap\" align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "nowrap=\"nowrap\" align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_w(OUTPUT_STREAM, int width) {
WRITE("&nbsp;");
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\"");
}
void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) {
HTML_CLOSE("td");
if (width > 0) HTML_OPEN_WITH("td", "align=\"right\" valign=\"top\" width=\"%d\"", width)
else HTML_OPEN_WITH("td", "align=\"right\" valign=\"top\"");
}
void HTML__end_html_row(OUTPUT_STREAM) {
HTML_CLOSE("td");
HTML_CLOSE("tr");
}
void HTML__end_html_table(OUTPUT_STREAM) {
HTML_CLOSE("table");
}
#line 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("<!--%S-->\n", text);
}
void HTML__heading(OUTPUT_STREAM, char *tag, text_stream *text) {
HTML_OPEN(tag);
WRITE("%S", text);
HTML_CLOSE(tag);
WRITE("\n");
}
void HTML__hr(OUTPUT_STREAM, char *class) {
if (class) HTML_TAG_WITH("hr", "class=\"%s\"", class)
else HTML_TAG("hr");
}
#line 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("<?xml version=\"1.0\"?>\n");
WRITE("<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">\n");
INDENT;
WRITE("<rootfiles>\n");
INDENT;
WRITE("<rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\" />\n");
OUTDENT;
WRITE("</rootfiles>\n");
OUTDENT;
WRITE("</container>\n");
STREAM_CLOSE(OUT);
}
#line 236 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
pathname *OEBPS = Pathnames__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("<?xml version='1.0' encoding='utf-8'?>\n");
WRITE("<package xmlns=\"http://www.idpf.org/2007/opf\"\n");
WRITE("xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n");
WRITE("unique-identifier=\"bookid\" version=\"2.0\">\n"); INDENT;
{
#line 357 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<metadata>\n"); INDENT;
ebook_datum *D = NULL;
LOOP_OVER_LINKED_LIST(D, ebook_datum, B->metadata_list) {
WRITE("<dc:%S", D->key);
if (Str__eq_wide_string(D->key, L"identifier")) WRITE(" id=\"bookid\"");
WRITE(">");
WRITE("%S</dc:%S>\n", D->value, D->key);
}
WRITE("<meta name=\"cover\" content=\"cover-image\" />\n");
OUTDENT; WRITE("</metadata>\n");
}
#line 345 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 369 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<manifest>\n"); INDENT;
WRITE("<item id=\"ncx\" href=\"toc.ncx\" media-type=\"application/x-dtbncx+xml\"/>\n");
{
#line 377 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
int cssc = 1;
if (B->CSS_file_throughout)
WRITE("<item id=\"css%d\" href=\"%S\" media-type=\"text/css\"/>\n",
cssc++, Filenames__get_leafname(B->CSS_file_throughout));
ebook_volume *V;
LOOP_OVER_LINKED_LIST(V, ebook_volume, B->ebook_volume_list)
if (V->CSS_file)
WRITE("<item id=\"css%d\" href=\"%S\" media-type=\"text/css\"/>\n",
cssc++, Filenames__get_leafname(V->CSS_file));
}
#line 371 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 388 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list)
WRITE("<item id=\"%S\" href=\"%S\" media-type=\"application/xhtml+xml\"/>\n",
P->page_ID, Filenames__get_leafname(P->relative_URL));
}
#line 372 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 394 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_image *I;
LOOP_OVER_LINKED_LIST(I, ebook_image, B->ebook_image_list) {
char *image_type = "";
switch (Filenames__guess_format(I->relative_URL)) {
case FORMAT_PERHAPS_PNG: image_type = "png"; break;
case FORMAT_PERHAPS_JPEG: image_type = "jpeg"; break;
case FORMAT_PERHAPS_SVG: image_type = "svg"; break;
case FORMAT_PERHAPS_GIF: image_type = "gif"; break;
default: Errors__nowhere("image not .gif, .png, .jpg or .svg"); break;
}
WRITE("<item id=\"%S\" href=\"%/f\" media-type=\"image/%s\"/>\n",
I->image_ID, I->relative_URL, image_type);
}
}
#line 373 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
OUTDENT; WRITE("</manifest>\n");
}
#line 346 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 409 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<spine toc=\"ncx\">\n"); INDENT;
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
WRITE("<itemref idref=\"%S\"", P->page_ID);
if (Str__len(P->page_type) > 0) WRITE(" linear=\"no\"");
WRITE("/>\n");
}
OUTDENT; WRITE("</spine>\n");
}
#line 347 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 419 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<guide>\n"); INDENT;
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
if (Str__len(P->page_type) > 0) {
WRITE("<reference href=\"%S\" type=\"%S\" title=\"%S\"/>\n",
Filenames__get_leafname(P->relative_URL), P->page_type, P->page_title);
}
}
OUTDENT; WRITE("</guide>\n");
}
#line 348 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
OUTDENT; WRITE("</package>\n");
STREAM_CLOSE(OUT);
}
#line 309 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 434 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
filename *toc = Filenames__in_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("<?xml version='1.0' encoding='utf-8'?>\n");
WRITE("<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\"\n");
WRITE(" \"http://www.daisy.org/z3986/2005/ncx-2005-1.dtd\">\n");
WRITE("<ncx xmlns=\"http://www.daisy.org/z3986/2005/ncx/\" version=\"2005-1\">\n");
int depth = 1; /* there are surely at least sections */
if (LinkedLists__len(B->ebook_chapter_list) > 0) depth = 2;
if (LinkedLists__len(B->ebook_volume_list) > 0) depth = 3;
{
#line 456 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<head>\n"); INDENT;
WRITE("<meta name=\"dtb:uid\" content=\"%S\"/>\n", Epub__get_metadata(B, L"identifier"));
WRITE("<meta name=\"dtb:depth\" content=\"%d\"/>\n", depth);
WRITE("<meta name=\"dtb:totalPageCount\" content=\"0\"/>\n");
WRITE("<meta name=\"dtb:maxPageNumber\" content=\"0\"/>\n");
OUTDENT; WRITE("</head>\n");
WRITE("<docTitle>\n"); INDENT;
WRITE("<text>%S</text>\n", Epub__get_metadata(B, L"title"));
OUTDENT; WRITE("</docTitle>\n");
}
#line 449 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 467 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navMap>\n"); INDENT;
int navpoint_count = 1;
int navmap_depth = 1;
int phase = 0;
{
#line 486 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
int in_phase = 1;
if ((Str__eq_wide_string(P->page_ID, L"cover")) ||
(Str__eq_wide_string(P->page_ID, L"index")))
in_phase = 0;
if ((in_phase == phase) && (P->nav_entry_written == FALSE)) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 493 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel> <content src=\"%S\"/>\n",
P->page_title, Filenames__get_leafname(P->relative_URL));
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 496 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
}
#line 471 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
ebook_volume *V = NULL;
LOOP_OVER_LINKED_LIST(V, ebook_volume, B->ebook_volume_list) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 474 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", V->volume_title);
WRITE("<content src=\"%S\"/>\n", Filenames__get_leafname(V->volume_starts->relative_URL));
{
#line 501 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_chapter *C = NULL;
LOOP_OVER_LINKED_LIST(C, ebook_chapter, B->ebook_chapter_list)
if (C->in_volume == V) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 504 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", C->chapter_title);
WRITE("<content src=\"%S\"/>\n", C->start_URL);
if (C->ebook_mark_list)
{
#line 531 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_mark *M;
LOOP_OVER_LINKED_LIST(M, ebook_mark, C->ebook_mark_list) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 533 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", M->mark_text);
WRITE("<content src=\"%S\"/>\n", M->mark_URL);
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 536 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
#line 508 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
else
{
#line 519 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
if ((P->in_chapter == C) && (P->nav_entry_written == FALSE)) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 522 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel>", P->page_title);
WRITE("<content src=\"%S\"/>\n", Filenames__get_leafname(P->relative_URL));
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 525 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
P->nav_entry_written = TRUE;
}
}
}
#line 510 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list)
if (P->in_chapter == C)
P->nav_entry_written = TRUE;
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 515 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
#line 477 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 478 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
phase = 1;
{
#line 486 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
ebook_page *P;
LOOP_OVER_LINKED_LIST(P, ebook_page, B->ebook_page_list) {
int in_phase = 1;
if ((Str__eq_wide_string(P->page_ID, L"cover")) ||
(Str__eq_wide_string(P->page_ID, L"index")))
in_phase = 0;
if ((in_phase == phase) && (P->nav_entry_written == FALSE)) {
{
#line 540 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
WRITE("<navPoint id=\"navpoint-%d\" playOrder=\"%d\">\n",
navpoint_count, navpoint_count);
navpoint_count++;
navmap_depth++; INDENT;
}
#line 493 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("<navLabel><text>%S</text></navLabel> <content src=\"%S\"/>\n",
P->page_title, Filenames__get_leafname(P->relative_URL));
{
#line 546 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
navmap_depth--;
if (navmap_depth < 1) internal_error("navMap numbering awry");
OUTDENT; WRITE("</navPoint>\n");
}
#line 496 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
}
}
}
#line 481 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
OUTDENT; WRITE("</navMap>\n");
if (navmap_depth != 1) internal_error("navMap numbering unbalanced");
}
#line 450 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
WRITE("</ncx>\n");
STREAM_CLOSE(OUT);
}
#line 310 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
;
{
#line 551 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
pathname *up = Pathnames__from_text(TL_IS_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<SEMVER_NUMBER_DEPTH; i++) V.version_numbers[i] = -1;
V.prerelease_segments = NULL;
V.build_metadata = NULL;
return V;
#pragma clang diagnostic pop
}
int VersionNumbers__is_null(semantic_version_number V) {
for (int i=0, allow=TRUE; i<SEMVER_NUMBER_DEPTH; i++) {
if (V.version_numbers[i] < -1) return TRUE; /* should never happen */
if (V.version_numbers[i] == -1) allow = FALSE;
else if (allow == FALSE) return TRUE; /* should never happen */
}
if (V.version_numbers[0] < 0) return TRUE;
return FALSE;
}
#line 103 "inweb/foundation-module/Chapter 7/Version Numbers.w"
void VersionNumbers__to_text(OUTPUT_STREAM, semantic_version_number V) {
if (VersionNumbers__is_null(V)) { WRITE("null"); return; }
for (int i=0; (i<SEMVER_NUMBER_DEPTH) && (V.version_numbers[i] >= 0); i++) {
if (i>0) WRITE(".");
WRITE("%d", V.version_numbers[i]);
}
if (V.prerelease_segments) {
int c = 0;
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, V.prerelease_segments) {
if (c++ == 0) WRITE("-"); else WRITE(".");
WRITE("%S", T);
}
}
if (V.build_metadata) WRITE("+%S", V.build_metadata);
}
#line 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<SEMVER_NUMBER_DEPTH; i++) {
int N1 = VersionNumbers__floor(V1.version_numbers[i]);
int N2 = VersionNumbers__floor(V2.version_numbers[i]);
if (N1 > N2) return FALSE;
if (N1 < N2) return TRUE;
}
linked_list_item *I1 = (V1.prerelease_segments)?(LinkedLists__first(V1.prerelease_segments)):NULL;
linked_list_item *I2 = (V2.prerelease_segments)?(LinkedLists__first(V2.prerelease_segments)):NULL;
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 64 "inweb/foundation-module/Chapter 8/Web Structure.w"
#line 82 "inweb/foundation-module/Chapter 8/Web Structure.w"
#line 90 "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 108 "inweb/foundation-module/Chapter 8/Web Structure.w"
Wm->bibliographic_data = NEW_LINKED_LIST(web_bibliographic_datum);
Bibliographic__initialise_data(Wm);
}
#line 98 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 112 "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 99 "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 132 "inweb/foundation-module/Chapter 8/Web Structure.w"
Bibliographic__check_required_data(Wm);
BuildFiles__set_bibliographic_data_for(Wm);
BuildFiles__deduce_semver(Wm);
}
#line 102 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 139 "inweb/foundation-module/Chapter 8/Web Structure.w"
int sequential = FALSE; /* are we numbering sections sequentially? */
if (Str__eq(Bibliographic__get_datum(Wm, TL_IS_19), TL_IS_20))
sequential = TRUE;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) {
int section_counter = 1;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) {
if (Str__len(Sm->sect_range) == 0)
{
#line 154 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (sequential) {
WRITE_TO(Sm->sect_range, "%S/", Cm->ch_range);
WRITE_TO(Sm->sect_range, "s%d", section_counter);
} else {
text_stream *from = Sm->sect_title;
int letters_from_each_word = 5;
do {
Str__clear(Sm->sect_range);
WRITE_TO(Sm->sect_range, "%S/", Cm->ch_range);
{
#line 174 "inweb/foundation-module/Chapter 8/Web Structure.w"
int sn = 0, sw = Str__len(Sm->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(Sm->sect_range, sw++, l);
Str__put_at(Sm->sect_range, sw, 0);
letters_from_current_word++;
}
}
}
}
sn++;
}
}
#line 163 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
if (--letters_from_each_word == 0) break;
} while (Str__len(Sm->sect_range) > 5);
{
#line 199 "inweb/foundation-module/Chapter 8/Web Structure.w"
TEMPORARY_TEXT(original_range);
Str__copy(original_range, Sm->sect_range);
int disnum = 0, collision = FALSE;
do {
if (disnum++ > 0) {
int ldn = 4;
if (disnum >= 1000) ldn = 3;
else if (disnum >= 100) ldn = 2;
else if (disnum >= 10) ldn = 1;
else ldn = 0;
Str__clear(Sm->sect_range);
WRITE_TO(Sm->sect_range, "%S", original_range);
Str__truncate(Sm->sect_range, Str__len(Sm->sect_range) - ldn);
WRITE_TO(Sm->sect_range, "%d", disnum);
}
collision = FALSE;
chapter_md *Cm2;
section_md *Sm2;
LOOP_OVER_LINKED_LIST(Cm2, chapter_md, Wm->chapters_md)
LOOP_OVER_LINKED_LIST(Sm2, section_md, Cm2->sections_md)
if ((Sm2 != Sm) && (Str__eq(Sm2->sect_range, Sm->sect_range))) {
collision = TRUE; break;
}
} while (collision);
DISCARD_TEXT(original_range);
}
#line 167 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
}
#line 148 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
section_counter++;
}
}
}
#line 103 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
return Wm;
}
#line 264 "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 284 "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 269 "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 320 "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 344 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (Str__eq(line, TL_IS_21))
RS->Wm->default_syntax = V1_SYNTAX;
else if (Str__eq(line, TL_IS_22))
RS->Wm->default_syntax = V2_SYNTAX;
}
#line 329 "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 355 "inweb/foundation-module/Chapter 8/Web Structure.w"
RS->halted = TRUE;
text_stream *new_chapter_range = TL_IS_23;
text_stream *language_name = NULL;
line = TL_IS_24;
{
#line 556 "inweb/foundation-module/Chapter 8/Web Structure.w"
chapter_md *Cm = CREATE(chapter_md);
Cm->ch_range = Str__duplicate(new_chapter_range);
if (line == NULL) PRINT("Nullity!\n");
Cm->ch_title = Str__duplicate(line);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, Cm->ch_title, L"(%c*?): *(%c*)")) {
Cm->ch_basic_title = Str__duplicate(mr.exp[0]);
Cm->ch_decorated_title = Str__duplicate(mr.exp[1]);
} else {
Cm->ch_basic_title = Str__duplicate(Cm->ch_title);
Cm->ch_decorated_title = Str__new();
}
Regexp__dispose_of(&mr);
Cm->rubric = Str__new();
Cm->ch_language_name = language_name;
Cm->imported = TRUE;
Cm->sections_md = NEW_LINKED_LIST(section_md);
if (RS->main_web_not_module) Cm->imported = FALSE;
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->Wm->chapters_md);
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->reading_from->chapters_md);
RS->chapter_being_scanned = Cm;
}
#line 359 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
line = TL_IS_25;
filename_of_single_file_web = tfp->text_file_filename;
{
#line 584 "inweb/foundation-module/Chapter 8/Web Structure.w"
section_md *Sm = CREATE(section_md);
{
#line 593 "inweb/foundation-module/Chapter 8/Web Structure.w"
Sm->source_file_for_section = filename_of_single_file_web;
Sm->using_syntax = syntax;
Sm->is_a_singleton = FALSE;
Sm->titling_line_to_insert = Str__duplicate(RS->titling_line_to_insert);
Sm->sect_range = Str__new();
Str__clear(RS->titling_line_to_insert);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+) %^\"(%c+)\" *")) {
Sm->sect_title = Str__duplicate(mr.exp[0]);
Sm->tag_name = Str__duplicate(mr.exp[1]);
} else {
Sm->sect_title = Str__duplicate(line);
Sm->tag_name = NULL;
}
Regexp__dispose_of(&mr);
}
#line 585 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 611 "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 586 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 619 "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 630 "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_28);
Sm->sect_independent_language = Str__duplicate(p);
}
#line 624 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
Str__copy(Sm->sect_title, title_alone);
}
Regexp__dispose_of(&mr);
}
#line 587 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
if (Sm->source_file_for_section == NULL)
{
#line 640 "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 590 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 362 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
return;
}
#line 334 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 371 "inweb/foundation-module/Chapter 8/Web Structure.w"
if (Str__len(line) == 0)
{
#line 379 "inweb/foundation-module/Chapter 8/Web Structure.w"
RS->in_biblio = FALSE;
}
#line 371 "inweb/foundation-module/Chapter 8/Web Structure.w"
else if (RS->in_biblio)
{
#line 385 "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 405 "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 392 "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 372 "inweb/foundation-module/Chapter 8/Web Structure.w"
else
{
#line 428 "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 441 "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 432 "inweb/foundation-module/Chapter 8/Web Structure.w"
else
{
#line 453 "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 548 "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_27);
else if (Regexp__match(&mr, language_name, L" *(%c*?) *"))
language_name = mr.exp[0];
Regexp__dispose_of(&mr);
}
#line 461 "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_26);
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 <number>: Title', "
"'Appendix <letter A to O>: Title',\n");
WRITE_TO(STDERR, "'Manual', 'Preliminaries' or 'Sections')\n");
DISCARD_TEXT(err);
}
if (this_is_a_chapter)
{
#line 556 "inweb/foundation-module/Chapter 8/Web Structure.w"
chapter_md *Cm = CREATE(chapter_md);
Cm->ch_range = Str__duplicate(new_chapter_range);
if (line == NULL) PRINT("Nullity!\n");
Cm->ch_title = Str__duplicate(line);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, Cm->ch_title, L"(%c*?): *(%c*)")) {
Cm->ch_basic_title = Str__duplicate(mr.exp[0]);
Cm->ch_decorated_title = Str__duplicate(mr.exp[1]);
} else {
Cm->ch_basic_title = Str__duplicate(Cm->ch_title);
Cm->ch_decorated_title = Str__new();
}
Regexp__dispose_of(&mr);
Cm->rubric = Str__new();
Cm->ch_language_name = language_name;
Cm->imported = TRUE;
Cm->sections_md = NEW_LINKED_LIST(section_md);
if (RS->main_web_not_module) Cm->imported = FALSE;
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->Wm->chapters_md);
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->reading_from->chapters_md);
RS->chapter_being_scanned = Cm;
}
#line 539 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
DISCARD_TEXT(new_chapter_range);
DISCARD_TEXT(pdf_leafname);
Regexp__dispose_of(&mr);
}
#line 433 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
} else
{
#line 584 "inweb/foundation-module/Chapter 8/Web Structure.w"
section_md *Sm = CREATE(section_md);
{
#line 593 "inweb/foundation-module/Chapter 8/Web Structure.w"
Sm->source_file_for_section = filename_of_single_file_web;
Sm->using_syntax = syntax;
Sm->is_a_singleton = FALSE;
Sm->titling_line_to_insert = Str__duplicate(RS->titling_line_to_insert);
Sm->sect_range = Str__new();
Str__clear(RS->titling_line_to_insert);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c+) %^\"(%c+)\" *")) {
Sm->sect_title = Str__duplicate(mr.exp[0]);
Sm->tag_name = Str__duplicate(mr.exp[1]);
} else {
Sm->sect_title = Str__duplicate(line);
Sm->tag_name = NULL;
}
Regexp__dispose_of(&mr);
}
#line 585 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 611 "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 586 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
{
#line 619 "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 630 "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_28);
Sm->sect_independent_language = Str__duplicate(p);
}
#line 624 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
Str__copy(Sm->sect_title, title_alone);
}
Regexp__dispose_of(&mr);
}
#line 587 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
if (Sm->source_file_for_section == NULL)
{
#line 640 "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 590 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 434 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 373 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 336 "inweb/foundation-module/Chapter 8/Web Structure.w"
;
}
#line 657 "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_29);
}
#line 668 "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_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->declaration_mandatory = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_33, NULL); bd->declaration_mandatory = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_34, NULL);
bd->alias = Bibliographic__set_datum(Wm, TL_IS_35, NULL); /* alias US to UK spelling */
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, NULL);
Bibliographic__set_datum(Wm, TL_IS_41, NULL);
Bibliographic__set_datum(Wm, TL_IS_42, TL_IS_43);
Bibliographic__set_datum(Wm, TL_IS_44, NULL);
Bibliographic__set_datum(Wm, TL_IS_45, NULL);
Bibliographic__set_datum(Wm, TL_IS_46, NULL);
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, TL_IS_52); bd->on_or_off = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_53, TL_IS_54); bd->on_or_off = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_55, TL_IS_56); bd->on_or_off = TRUE;
bd = Bibliographic__set_datum(Wm, TL_IS_57, TL_IS_58);
bd = Bibliographic__set_datum(Wm, TL_IS_59, TL_IS_60);
bd = Bibliographic__set_datum(Wm, TL_IS_61, TL_IS_62);
bd = Bibliographic__set_datum(Wm, TL_IS_63, TL_IS_64);
bd = Bibliographic__set_datum(Wm, TL_IS_65, TL_IS_66);
bd = Bibliographic__set_datum(Wm, TL_IS_67, TL_IS_68);
bd = Bibliographic__set_datum(Wm, TL_IS_69, TL_IS_70);
bd = Bibliographic__set_datum(Wm, TL_IS_71, NULL);
}
#line 86 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
void Bibliographic__check_required_data(web_md *Wm) {
web_bibliographic_datum *bd;
LOOP_OVER_BIBLIOGRAPHIC_DATA(bd, Wm)
if ((bd->declaration_mandatory) &&
(Str__len(bd->value) == 0))
Errors__fatal_with_text(
"The web does not specify '%S: ...'", bd->key);
}
#line 99 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
text_stream *Bibliographic__get_datum(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if (bd) return bd->value;
return NULL;
}
int Bibliographic__data_exists(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if ((bd) && (Str__len(bd->value) > 0)) return TRUE;
return FALSE;
}
web_bibliographic_datum *Bibliographic__look_up_datum(web_md *Wm, text_stream *key) {
web_bibliographic_datum *bd;
LOOP_OVER_BIBLIOGRAPHIC_DATA(bd, Wm)
if (Str__eq(key, bd->key)) {
if (bd->alias) return bd->alias;
return bd;
}
return NULL;
}
#line 126 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
web_bibliographic_datum *Bibliographic__set_datum(web_md *Wm, text_stream *key, text_stream *val) {
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
if (bd == NULL)
{
#line 135 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
bd = CREATE(web_bibliographic_datum);
bd->key = Str__duplicate(key);
bd->value = Str__duplicate(val);
bd->declaration_mandatory = FALSE;
bd->declaration_permitted = TRUE;
bd->on_or_off = FALSE;
bd->alias = NULL;
ADD_TO_LINKED_LIST(bd, web_bibliographic_datum, Wm->bibliographic_data);
}
#line 128 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
else Str__copy(bd->value, val);
if (Str__eq_wide_string(key, L"Title"))
{
#line 150 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
TEMPORARY_TEXT(recapped);
Str__copy(recapped, val);
LOOP_THROUGH_TEXT(P, recapped)
Str__put(P, toupper(Str__get(P)));
Bibliographic__set_datum(Wm, TL_IS_72, recapped);
DISCARD_TEXT(recapped);
}
#line 130 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
;
return bd;
}
#line 29 "inweb/foundation-module/Chapter 8/Web Modules.w"
#line 31 "inweb/foundation-module/Chapter 8/Web Modules.w"
module *WebModules__new(text_stream *name, pathname *at, int m) {
module *M = CREATE(module);
M->module_location = at;
M->module_name = Str__duplicate(name);
M->dependencies = NEW_LINKED_LIST(module);
M->origin_marker = m;
M->module_tag = TL_IS_73;
M->chapters_md = NEW_LINKED_LIST(chapter_md);
M->sections_md = NEW_LINKED_LIST(section_md);
return M;
}
#line 52 "inweb/foundation-module/Chapter 8/Web Modules.w"
module *WebModules__create_main_module(web_md *WS) {
return WebModules__new(TL_IS_74, WS->path_to_web, READING_WEB_MOM);
}
#line 63 "inweb/foundation-module/Chapter 8/Web Modules.w"
void WebModules__dependency(module *A, module *B) {
if ((A == NULL) || (B == NULL)) internal_error("no module");
ADD_TO_LINKED_LIST(B, module, A->dependencies);
}
#line 77 "inweb/foundation-module/Chapter 8/Web Modules.w"
#line 79 "inweb/foundation-module/Chapter 8/Web Modules.w"
module_search *WebModules__make_search_path(pathname *ext_path) {
module_search *ms = CREATE(module_search);
ms->path_to_search = ext_path;
return ms;
}
#line 89 "inweb/foundation-module/Chapter 8/Web Modules.w"
module *WebModules__find(web_md *WS, module_search *ms, text_stream *name, pathname *X) {
TEMPORARY_TEXT(T);
WRITE_TO(T, "%S-module", name);
pathname *tries[4];
tries[0] = WS?(WS->path_to_web):NULL;
tries[1] = tries[0]?(Pathnames__up(tries[0])):NULL;
tries[2] = X;
tries[3] = ms->path_to_search;
int N = 4;
for (int i=0; i<N; i++) {
pathname *P = Pathnames__from_text_relative(tries[i], T);
if ((P) && (WebModules__exists(P)))
{
#line 110 "inweb/foundation-module/Chapter 8/Web Modules.w"
module *M = WebModules__new(name, P, READING_WEB_MOM);
WebModules__dependency(WS->as_module, M);
return M;
}
#line 100 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
DISCARD_TEXT(T);
return NULL;
}
#line 118 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__exists(pathname *P) {
return WebMetadata__directory_looks_like_a_web(P);
}
#line 141 "inweb/foundation-module/Chapter 8/Web Modules.w"
int WebModules__named_reference(module **return_M, section_md **return_Sm,
int *named_as_module, text_stream *title, module *from_M, text_stream *text, int list) {
*return_M = NULL; *return_Sm = NULL; *named_as_module = FALSE;
module *M;
int finds = 0;
if (from_M == NULL) return 0;
match_results mr = Regexp__create_mr();
text_stream *seek = text;
if (Regexp__match(&mr, text, L"(%C+?): *(%c+?) *")) {
LOOP_OVER_LINKED_LIST(M, module, from_M->dependencies)
if (Str__eq_insensitive(M->module_name, mr.exp[0])) {
seek = mr.exp[1];
{
#line 172 "inweb/foundation-module/Chapter 8/Web Modules.w"
if (M == NULL) internal_error("no module");
if (Str__eq_insensitive(M->module_name, seek))
{
#line 188 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, M->sections_md);
*named_as_module = TRUE;
WRITE_TO(title, "the %S module", M->module_name);
}
if (list) WRITE_TO(STDERR, "(%d) Module '%S'\n", finds, M->module_name);
}
#line 174 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, M->chapters_md) {
if ((Str__eq_insensitive(Cm->ch_title, seek)) ||
(Str__eq_insensitive(Cm->ch_basic_title, seek)) ||
(Str__eq_insensitive(Cm->ch_decorated_title, seek)))
{
#line 197 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, Cm->sections_md);
WRITE_TO(title, "%S", Cm->ch_title);
}
if (list) WRITE_TO(STDERR, "(%d) Chapter '%S'\n", finds, Cm->ch_title);
}
#line 181 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md)
if (Str__eq_insensitive(Sm->sect_title, seek))
{
#line 205 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = Sm;
WRITE_TO(title, "%S", Sm->sect_title);
}
if (list) WRITE_TO(STDERR, "(%d) Section '%S'\n", finds, Sm->sect_title);
}
#line 184 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
#line 153 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
Regexp__dispose_of(&mr);
seek = text;
for (int stage = 1; ((finds == 0) && (stage <= 2)); stage++) {
if (stage == 1) {
M = from_M;
{
#line 172 "inweb/foundation-module/Chapter 8/Web Modules.w"
if (M == NULL) internal_error("no module");
if (Str__eq_insensitive(M->module_name, seek))
{
#line 188 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, M->sections_md);
*named_as_module = TRUE;
WRITE_TO(title, "the %S module", M->module_name);
}
if (list) WRITE_TO(STDERR, "(%d) Module '%S'\n", finds, M->module_name);
}
#line 174 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, M->chapters_md) {
if ((Str__eq_insensitive(Cm->ch_title, seek)) ||
(Str__eq_insensitive(Cm->ch_basic_title, seek)) ||
(Str__eq_insensitive(Cm->ch_decorated_title, seek)))
{
#line 197 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, Cm->sections_md);
WRITE_TO(title, "%S", Cm->ch_title);
}
if (list) WRITE_TO(STDERR, "(%d) Chapter '%S'\n", finds, Cm->ch_title);
}
#line 181 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md)
if (Str__eq_insensitive(Sm->sect_title, seek))
{
#line 205 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = Sm;
WRITE_TO(title, "%S", Sm->sect_title);
}
if (list) WRITE_TO(STDERR, "(%d) Section '%S'\n", finds, Sm->sect_title);
}
#line 184 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
#line 161 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
if (stage == 2) {
LOOP_OVER_LINKED_LIST(M, module, from_M->dependencies)
{
#line 172 "inweb/foundation-module/Chapter 8/Web Modules.w"
if (M == NULL) internal_error("no module");
if (Str__eq_insensitive(M->module_name, seek))
{
#line 188 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, M->sections_md);
*named_as_module = TRUE;
WRITE_TO(title, "the %S module", M->module_name);
}
if (list) WRITE_TO(STDERR, "(%d) Module '%S'\n", finds, M->module_name);
}
#line 174 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
chapter_md *Cm;
section_md *Sm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, M->chapters_md) {
if ((Str__eq_insensitive(Cm->ch_title, seek)) ||
(Str__eq_insensitive(Cm->ch_basic_title, seek)) ||
(Str__eq_insensitive(Cm->ch_decorated_title, seek)))
{
#line 197 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = FIRST_IN_LINKED_LIST(section_md, Cm->sections_md);
WRITE_TO(title, "%S", Cm->ch_title);
}
if (list) WRITE_TO(STDERR, "(%d) Chapter '%S'\n", finds, Cm->ch_title);
}
#line 181 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md)
if (Str__eq_insensitive(Sm->sect_title, seek))
{
#line 205 "inweb/foundation-module/Chapter 8/Web Modules.w"
finds++;
if (finds == 1) {
*return_M = M; *return_Sm = Sm;
WRITE_TO(title, "%S", Sm->sect_title);
}
if (list) WRITE_TO(STDERR, "(%d) Section '%S'\n", finds, Sm->sect_title);
}
#line 184 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
#line 165 "inweb/foundation-module/Chapter 8/Web Modules.w"
;
}
}
return finds;
}
#line 10 "inweb/foundation-module/Chapter 8/Build Files.w"
filename *BuildFiles__build_file_for_web(web_md *WS) {
filename *F = Filenames__in_folder(WS->path_to_web, TL_IS_75);
if (TextFiles__exists(F)) return F;
F = Filenames__in_folder(NULL, TL_IS_76);
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_77, bfd.prerelease_text);
if (Str__len(bfd.build_code) > 0)
Bibliographic__set_datum(WS, TL_IS_78, bfd.build_code);
if (Str__len(bfd.build_date) > 0)
Bibliographic__set_datum(WS, TL_IS_79, 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_80);
if (Str__len(s) > 0) WRITE_TO(combined, "%S", s);
else {
text_stream *v = Bibliographic__get_datum(WS, TL_IS_81);
if (Str__len(v) > 0) WRITE_TO(combined, "%S", v);
text_stream *p = Bibliographic__get_datum(WS, TL_IS_82);
if (Str__len(p) > 0) WRITE_TO(combined, "-%S", p);
text_stream *b = Bibliographic__get_datum(WS, TL_IS_83);
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_84, 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 58 "inweb/Chapter 1/Basics.w"
ALLOCATE_IN_ARRAYS(source_line, 1000)
ALLOCATE_INDIVIDUALLY(breadcrumb_request)
ALLOCATE_INDIVIDUALLY(chapter)
ALLOCATE_INDIVIDUALLY(colony)
ALLOCATE_INDIVIDUALLY(colony_member)
ALLOCATE_INDIVIDUALLY(colouring_language_block)
ALLOCATE_INDIVIDUALLY(colouring_rule)
ALLOCATE_INDIVIDUALLY(enumeration_set)
ALLOCATE_INDIVIDUALLY(hash_table_entry_usage)
ALLOCATE_INDIVIDUALLY(hash_table_entry)
ALLOCATE_INDIVIDUALLY(language_function)
ALLOCATE_INDIVIDUALLY(language_type)
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_plugin)
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_86);
if (args.verbose_switch) PRINT("Installation path is %p\n", path_to_inweb);
path_to_inweb_patterns = Pathnames__subfolder(path_to_inweb, TL_IS_87);
path_to_inweb_materials = Pathnames__subfolder(path_to_inweb, TL_IS_88);
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);
}
if (no_inweb_errors == 0) {
if (ins->inweb_mode == TRANSLATE_MODE)
{
#line 111 "inweb/Chapter 1/Program Control.w"
if ((ins->makefile_setting) && (ins->prototype_setting == NULL))
ins->prototype_setting = Filenames__from_text(TL_IS_89);
if ((ins->gitignore_setting) && (ins->prototype_setting == NULL))
ins->prototype_setting = Filenames__from_text(TL_IS_90);
if ((ins->writeme_setting) && (ins->prototype_setting == NULL))
ins->prototype_setting = Filenames__from_text(TL_IS_91);
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 130 "inweb/Chapter 1/Program Control.w"
Languages__read_definitions(NULL);
Languages__show(STDOUT);
}
#line 102 "inweb/Chapter 1/Program Control.w"
else if ((ins->test_language_setting) || (ins->test_language_on_setting))
{
#line 136 "inweb/Chapter 1/Program Control.w"
if ((ins->test_language_setting) && (ins->test_language_on_setting)) {
TEMPORARY_TEXT(matter);
TEMPORARY_TEXT(coloured);
Painter__colour_file(ins->test_language_setting, ins->test_language_on_setting,
matter, coloured);
PRINT("Test of colouring for language %S:\n%S\n%S\n",
ins->test_language_setting->language_name, matter, coloured);
DISCARD_TEXT(matter);
DISCARD_TEXT(coloured);
} else {
Errors__fatal("-test-language and -test-language-on must both be given");
}
}
#line 103 "inweb/Chapter 1/Program Control.w"
else if (ins->inweb_mode != NO_MODE)
{
#line 152 "inweb/Chapter 1/Program Control.w"
Reader__print_web_statistics(W);
if (ins->inweb_mode == ANALYSE_MODE)
{
#line 160 "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 153 "inweb/Chapter 1/Program Control.w"
;
if (ins->inweb_mode == TANGLE_MODE)
{
#line 193 "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 216 "inweb/Chapter 1/Program Control.w"
tn = NULL;
if (Bibliographic__data_exists(W->md, TL_IS_92))
Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_93));
else
Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_94));
Str__concatenate(tangle_leaf, W->main_language->file_extension);
}
#line 196 "inweb/Chapter 1/Program Control.w"
;
} else if (Reader__get_section_for_range(W, ins->chosen_range)) {
{
#line 226 "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 198 "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 154 "inweb/Chapter 1/Program Control.w"
;
if (ins->inweb_mode == WEAVE_MODE)
{
#line 234 "inweb/Chapter 1/Program Control.w"
Numbering__number_web(W);
theme_tag *tag = Tags__find_by_name(ins->tag_setting, FALSE);
if ((Str__len(ins->tag_setting) > 0) && (tag == NULL))
Errors__fatal_with_text("no such theme as '%S'", ins->tag_setting);
weave_pattern *pattern = Patterns__find(W, ins->weave_pattern);
if ((ins->chosen_range_actually_chosen == FALSE) && (ins->chosen_file == NULL))
Configuration__set_range(ins, pattern->default_range);
int r = Formats__begin_weaving(W, pattern);
if (r != SWARM_OFF_SWM) ins->swarm_mode = r;
{
#line 264 "inweb/Chapter 1/Program Control.w"
section *S; int k = 1;
LOOP_OVER(S, section)
if (Reader__range_within(S->md->sect_range, ins->chosen_range))
S->printed_number = k++;
}
#line 246 "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->breadcrumb_setting, ins->navigation_setting);
} else {
Swarm__weave(W, ins->chosen_range, ins->swarm_mode, tag, pattern,
ins->weave_to_setting, ins->weave_into_setting,
ins->breadcrumb_setting, ins->navigation_setting);
}
Formats__end_weaving(W, pattern);
}
#line 155 "inweb/Chapter 1/Program Control.w"
;
}
#line 104 "inweb/Chapter 1/Program Control.w"
;
}
}
#line 275 "inweb/Chapter 1/Program Control.w"
void Main__error_in_web(text_stream *message, source_line *sl) {
if (sl) {
Errors__in_text_file_S(message, &(sl->source));
WRITE_TO(STDERR, "%07d %S\n", sl->source.line_count, sl->text);
} else {
Errors__in_text_file_S(message, NULL);
}
no_inweb_errors++;
}
#line 50 "inweb/Chapter 1/Configuration.w"
#line 57 "inweb/Chapter 1/Configuration.w"
inweb_instructions Configuration__read(int argc, char **argv) {
inweb_instructions args;
{
#line 77 "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.makefile_setting = NULL;
args.gitignore_setting = NULL;
args.advance_setting = NULL;
args.writeme_setting = NULL;
args.prototype_setting = NULL;
args.navigation_setting = NULL;
args.colony_setting = NULL;
args.member_setting = NULL;
args.breadcrumb_setting = NEW_LINKED_LIST(breadcrumb_request);
args.tag_setting = Str__new();
args.weave_pattern = Str__new();
args.import_setting = NULL;
args.targets = 0;
args.test_language_setting = NULL;
args.test_language_on_setting = NULL;
}
#line 59 "inweb/Chapter 1/Configuration.w"
;
{
#line 160 "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_96);
CommandLine__declare_switch(LANGUAGE_CLSW, L"read-language", 2,
L"read language definition from file X");
CommandLine__declare_switch(LANGUAGES_CLSW, L"read-languages", 2,
L"read all language definitions in path X");
CommandLine__declare_switch(SHOW_LANGUAGES_CLSW, L"show-languages", 1,
L"list programming languages supported by Inweb");
CommandLine__declare_switch(TEST_LANGUAGE_CLSW, L"test-language", 2,
L"test language X on...");
CommandLine__declare_switch(TEST_LANGUAGE_ON_CLSW, L"test-language-on", 2,
L"...the code in the file X");
CommandLine__end_group();
CommandLine__begin_group(ANALYSIS_CLSG,
TL_IS_97);
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_98);
CommandLine__declare_switch(WEAVE_CLSW, L"weave", 1,
L"weave the web into human-readable form");
CommandLine__declare_switch(WEAVE_INTO_CLSW, L"weave-into", 2,
L"weave, but into directory X");
CommandLine__declare_switch(WEAVE_TO_CLSW, L"weave-to", 2,
L"weave, but to filename X (for single files only)");
CommandLine__declare_switch(OPEN_CLSW, L"open", 1,
L"weave then open woven file");
CommandLine__declare_switch(WEAVE_AS_CLSW, L"weave-as", 2,
L"set weave pattern to X (default is 'HTML')");
CommandLine__declare_switch(WEAVE_TAG_CLSW, L"weave-tag", 2,
L"weave, but only using material tagged as X");
CommandLine__declare_switch(BREADCRUMB_CLSW, L"breadcrumb", 2,
L"use the text X as a breadcrumb in overhead navigation");
CommandLine__declare_switch(NAVIGATION_CLSW, L"navigation", 2,
L"use the file X as a column of navigation links");
CommandLine__end_group();
CommandLine__begin_group(TANGLING_CLSG,
TL_IS_99);
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__begin_group(COLONIAL_CLSG,
TL_IS_100);
CommandLine__declare_switch(COLONY_CLSW, L"colony", 2,
L"use the file X as a list of webs in this colony");
CommandLine__declare_switch(MEMBER_CLSW, L"member", 2,
L"use member X from the colony as our web");
CommandLine__end_group();
CommandLine__declare_boolean_switch(VERBOSE_CLSW, L"verbose", 1,
L"explain what inweb is doing", FALSE);
CommandLine__declare_switch(IMPORT_FROM_CLSW, L"import-from", 2,
L"specify that imported modules are at pathname X");
}
#line 60 "inweb/Chapter 1/Configuration.w"
;
CommandLine__read(argc, argv, &args, &Configuration__switch, &Configuration__bareword);
{
#line 364 "inweb/Chapter 1/Configuration.w"
if (args.colony_setting) Colonies__load(args.colony_setting);
if (Str__len(args.member_setting) > 0) {
if ((args.chosen_web == NULL) && (args.chosen_file == NULL)) {
colony_member *CM = Colonies__find(args.member_setting);
if (CM == NULL) Errors__fatal("the colony has no member of that name");
Configuration__bareword(0, CM->path, &args);
if (Str__len(args.weave_pattern) == 0)
args.weave_pattern = CM->default_weave_pattern;
if (LinkedLists__len(args.breadcrumb_setting) == 0)
args.breadcrumb_setting = CM->breadcrumb_tail;
if (args.navigation_setting == NULL)
args.navigation_setting = CM->navigation;
if (args.weave_into_setting == NULL)
args.weave_into_setting = CM->weave_path;
} else {
Errors__fatal("cannot specify a web and also use -member");
}
}
}
#line 62 "inweb/Chapter 1/Configuration.w"
;
if (Str__len(args.weave_pattern) == 0) WRITE_TO(args.weave_pattern, "HTML");
if ((args.chosen_web == NULL) && (args.chosen_file == NULL)) {
if ((args.makefile_setting) || (args.gitignore_setting))
args.inweb_mode = TRANSLATE_MODE;
if (args.inweb_mode != TRANSLATE_MODE)
args.inweb_mode = NO_MODE;
}
if (Str__len(args.chosen_range) == 0) {
Str__copy(args.chosen_range, TL_IS_95);
}
return args;
}
#line 116 "inweb/Chapter 1/Configuration.w"
#line 118 "inweb/Chapter 1/Configuration.w"
#line 124 "inweb/Chapter 1/Configuration.w"
#line 126 "inweb/Chapter 1/Configuration.w"
#line 137 "inweb/Chapter 1/Configuration.w"
#line 139 "inweb/Chapter 1/Configuration.w"
#line 148 "inweb/Chapter 1/Configuration.w"
#line 150 "inweb/Chapter 1/Configuration.w"
#line 153 "inweb/Chapter 1/Configuration.w"
#line 155 "inweb/Chapter 1/Configuration.w"
#line 158 "inweb/Chapter 1/Configuration.w"
#line 258 "inweb/Chapter 1/Configuration.w"
void Configuration__switch(int id, int val, text_stream *arg, void *state) {
inweb_instructions *args = (inweb_instructions *) state;
switch (id) {
/* Miscellaneous */
case VERBOSE_CLSW: args->verbose_switch = TRUE; break;
case IMPORT_FROM_CLSW: args->import_setting = Pathnames__from_text(arg); break;
/* Analysis */
case LANGUAGE_CLSW:
Languages__read_definition(Filenames__from_text(arg)); break;
case LANGUAGES_CLSW:
Languages__read_definitions(Pathnames__from_text(arg)); break;
case SHOW_LANGUAGES_CLSW:
args->show_languages_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case TEST_LANGUAGE_CLSW:
args->test_language_setting =
Languages__read_definition(Filenames__from_text(arg));
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case TEST_LANGUAGE_ON_CLSW:
args->test_language_on_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case CATALOGUE_CLSW:
args->catalogue_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case FUNCTIONS_CLSW:
args->functions_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case STRUCTURES_CLSW:
args->structures_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case ADVANCE_CLSW:
args->advance_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
case MAKEFILE_CLSW:
args->makefile_setting = Filenames__from_text(arg);
if (args->inweb_mode != TRANSLATE_MODE)
Configuration__set_fundamental_mode(args, ANALYSE_MODE);
break;
case GITIGNORE_CLSW:
args->gitignore_setting = Filenames__from_text(arg);
if (args->inweb_mode != TRANSLATE_MODE)
Configuration__set_fundamental_mode(args, ANALYSE_MODE);
break;
case ADVANCE_FILE_CLSW:
args->advance_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TRANSLATE_MODE);
break;
case WRITEME_CLSW:
args->writeme_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TRANSLATE_MODE);
break;
case PROTOTYPE_CLSW:
args->prototype_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TRANSLATE_MODE); break;
case SCAN_CLSW:
args->scan_switch = TRUE;
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
/* Weave-related */
case WEAVE_CLSW:
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case WEAVE_INTO_CLSW:
args->weave_into_setting = Pathnames__from_text(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case WEAVE_TO_CLSW:
args->weave_to_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case 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(Colonies__request_breadcrumb(arg),
breadcrumb_request, args->breadcrumb_setting);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
case NAVIGATION_CLSW:
args->navigation_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
/* Colonial */
case COLONY_CLSW:
args->colony_setting = Filenames__from_text(arg); break;
case MEMBER_CLSW:
args->member_setting = Str__duplicate(arg); break;
/* Tangle-related */
case TANGLE_CLSW:
Configuration__set_fundamental_mode(args, TANGLE_MODE); break;
case TANGLE_TO_CLSW:
args->tangle_setting = Filenames__from_text(arg);
Configuration__set_fundamental_mode(args, TANGLE_MODE); break;
default: internal_error("unimplemented switch");
}
}
#line 388 "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_101, 6))
args->chosen_file = Filenames__from_text(opt);
else
args->chosen_web = Pathnames__from_text(opt);
} else Configuration__set_range(args, opt);
}
#line 403 "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_102);
} 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 435 "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 34 "inweb/Chapter 1/Patterns.w"
#line 38 "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 48 "inweb/Chapter 1/Patterns.w"
wp->pattern_name = Str__duplicate(name);
wp->pattern_location = NULL;
wp->plugins = NEW_LINKED_LIST(weave_plugin);
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_103);
wp->tex_command = Str__duplicate(TL_IS_104);
wp->pdftex_command = Str__duplicate(TL_IS_105);
wp->open_command = Str__duplicate(TL_IS_106);
}
#line 41 "inweb/Chapter 1/Patterns.w"
;
{
#line 65 "inweb/Chapter 1/Patterns.w"
wp->pattern_location =
Pathnames__subfolder(
Pathnames__subfolder(W->md->path_to_web, TL_IS_107),
name);
pattern_file = Filenames__in_folder(wp->pattern_location, TL_IS_108);
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_109);
if (TextFiles__exists(pattern_file) == FALSE)
Errors__fatal_with_text("no such weave pattern as '%S'", name);
}
}
#line 42 "inweb/Chapter 1/Patterns.w"
;
{
#line 78 "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 43 "inweb/Chapter 1/Patterns.w"
;
return wp;
}
#line 89 "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 105 "inweb/Chapter 1/Patterns.w"
wp->based_on = Patterns__find(wp->patterned_for, mr.exp[0]);
Regexp__dispose_of(&mr);
return;
}
#line 92 "inweb/Chapter 1/Patterns.w"
;
if (Regexp__match(&mr, line, L" *(%c+?) = (%c+)"))
{
#line 110 "inweb/Chapter 1/Patterns.w"
if (Str__eq(mr.exp[0], TL_IS_110)) {
wp->pattern_format = Formats__find_by_name(mr.exp[1]);
} else if (Str__eq(mr.exp[0], TL_IS_111)) {
wp->show_abbrevs = Patterns__yes_or_no(mr.exp[1], tfp);
} else if (Str__eq(mr.exp[0], TL_IS_112)) {
wp->number_sections = Patterns__yes_or_no(mr.exp[1], tfp);
} else if (Str__eq(mr.exp[0], TL_IS_113)) {
wp->default_range = Str__duplicate(mr.exp[1]);
} else if (Str__eq(mr.exp[0], TL_IS_114)) {
wp->tex_command = Str__duplicate(mr.exp[1]);
} else if (Str__eq(mr.exp[0], TL_IS_115)) {
wp->pdftex_command = Str__duplicate(mr.exp[1]);
} else if (Str__eq(mr.exp[0], TL_IS_116)) {
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_117))) {
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 93 "inweb/Chapter 1/Patterns.w"
;
if (Regexp__match(&mr, line, L" *embed css *"))
{
#line 135 "inweb/Chapter 1/Patterns.w"
wp->embed_CSS = TRUE;
Regexp__dispose_of(&mr);
return;
}
#line 94 "inweb/Chapter 1/Patterns.w"
;
if (Regexp__match(&mr, line, L" *hierarchical *"))
{
#line 140 "inweb/Chapter 1/Patterns.w"
wp->hierarchical = TRUE;
Regexp__dispose_of(&mr);
return;
}
#line 95 "inweb/Chapter 1/Patterns.w"
;
if (Regexp__match(&mr, line, L" *plugin (%c+)"))
{
#line 147 "inweb/Chapter 1/Patterns.w"
text_stream *leafname = Str__duplicate(mr.exp[0]);
ADD_TO_LINKED_LIST(leafname, text_stream, wp->plugins);
Regexp__dispose_of(&mr);
return;
}
#line 96 "inweb/Chapter 1/Patterns.w"
;
if (Regexp__match(&mr, line, L" *use (%c+)"))
{
#line 157 "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 97 "inweb/Chapter 1/Patterns.w"
;
if (Regexp__match(&mr, line, L" *use-up (%c+)"))
{
#line 163 "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 98 "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 169 "inweb/Chapter 1/Patterns.w"
int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) {
if (Str__eq(arg, TL_IS_118)) return TRUE;
if (Str__eq(arg, TL_IS_119)) return FALSE;
Errors__in_text_file("setting must be 'yes' or 'no'", tfp);
return FALSE;
}
#line 187 "inweb/Chapter 1/Patterns.w"
filename *Patterns__obtain_filename(weave_pattern *pattern, text_stream *leafname) {
if (Str__prefix_eq(leafname, TL_IS_120, 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 203 "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 224 "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 92 "inweb/Chapter 2/The Reader.w"
#line 97 "inweb/Chapter 2/The Reader.w"
web_md *Reader__load_web_md(pathname *P, filename *alt_F, module_search *I, int 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 134 "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_121, IB);
bd->declaration_permitted = FALSE;
DISCARD_TEXT(IB);
}
#line 110 "inweb/Chapter 2/The Reader.w"
;
{
#line 141 "inweb/Chapter 2/The Reader.w"
W->chapters = NEW_LINKED_LIST(chapter);
W->headers = NEW_LINKED_LIST(filename);
W->language_types = NEW_LINKED_LIST(language_type);
W->tangle_targets = NEW_LINKED_LIST(tangle_target);
W->analysed = FALSE;
W->as_ebook = NULL;
W->redirect_weaves_to = NULL;
W->main_language = Languages__default(W);
W->web_extent = 0; W->no_paragraphs = 0;
text_stream *language_name = Bibliographic__get_datum(W->md, TL_IS_122);
if (Str__len(language_name) > 0)
W->main_language = Languages__find_by_name(language_name, W);
main_target = Reader__add_tangle_target(W, W->main_language);
}
#line 111 "inweb/Chapter 2/The Reader.w"
;
chapter_md *Cm;
LOOP_OVER_LINKED_LIST(Cm, chapter_md, W->md->chapters_md) {
chapter *C = CREATE(chapter);
C->md = Cm;
C->owning_web = W;
{
#line 156 "inweb/Chapter 2/The Reader.w"
C->ch_weave = NULL;
C->titling_line_inserted = FALSE;
C->sections = NEW_LINKED_LIST(section);
C->ch_language = W->main_language;
if (Str__len(Cm->ch_language_name) > 0)
C->ch_language = Languages__find_by_name(Cm->ch_language_name, W);
}
#line 117 "inweb/Chapter 2/The Reader.w"
;
ADD_TO_LINKED_LIST(C, chapter, W->chapters);
section_md *Sm;
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) {
section *S = CREATE(section);
S->md = Sm;
S->owning_chapter = C;
S->owning_web = W;
{
#line 164 "inweb/Chapter 2/The Reader.w"
S->sect_extent = 0;
S->first_line = NULL; S->last_line = NULL;
S->sect_paragraphs = 0;
S->paragraphs = NEW_LINKED_LIST(paragraph);
S->macros = NEW_LINKED_LIST(para_macro);
S->scratch_flag = FALSE;
S->barred = FALSE;
S->printed_number = -1;
S->sect_weave = NULL;
S->sect_namespace = Str__new();
S->owning_web = W;
S->sect_language = C->ch_language;
if (Str__len(S->md->sect_language_name) > 0)
S->sect_language = Languages__find_by_name(S->md->sect_language_name, W);
if (Str__len(S->md->sect_independent_language) > 0) {
programming_language *pl =
Languages__find_by_name(S->md->sect_independent_language, W);
S->sect_language = pl;
S->sect_target = Reader__add_tangle_target(W, pl);
} else {
S->sect_target = main_target;
}
S->tag_with = NULL;
if (Str__len(Sm->tag_name) > 0)
S->tag_with = Tags__add_by_name(NULL, Sm->tag_name);
}
#line 125 "inweb/Chapter 2/The Reader.w"
;
ADD_TO_LINKED_LIST(S, section, C->sections);
}
}
{
#line 192 "inweb/Chapter 2/The Reader.w"
filename *HF;
LOOP_OVER_LINKED_LIST(HF, filename, W->md->header_filenames)
Reader__add_imported_header(W, HF);
}
#line 129 "inweb/Chapter 2/The Reader.w"
;
return W;
}
#line 205 "inweb/Chapter 2/The Reader.w"
void Reader__read_web(web *W, 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 219 "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 241 "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 275 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 245 "inweb/Chapter 2/The Reader.w"
;
DISCARD_TEXT(line);
}
#line 229 "inweb/Chapter 2/The Reader.w"
;
if (disregard_top)
{
#line 249 "inweb/Chapter 2/The Reader.w"
TEMPORARY_TEXT(line);
text_file_position *tfp = NULL;
WRITE_TO(line, "Main.");
{
#line 275 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 252 "inweb/Chapter 2/The Reader.w"
;
Str__clear(line);
{
#line 275 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 254 "inweb/Chapter 2/The Reader.w"
;
DISCARD_TEXT(line);
}
#line 232 "inweb/Chapter 2/The Reader.w"
;
int cl = TextFiles__read(F, FALSE, "can't open section file", TRUE,
Reader__scan_source_line, NULL, (void *) S);
if (verbosely)
PRINT("Read section: '%S' (%d lines)\n", S->md->sect_title, cl);
}
#line 262 "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 275 "inweb/Chapter 2/The Reader.w"
source_line *sl = Lines__new_source_line_in(line, tfp, S);
/* enter this in its section's linked list of lines: */
if (S->first_line == NULL) S->first_line = sl;
else S->last_line->next_line = sl;
S->last_line = sl;
/* we haven't detected paragraph boundaries yet, so: */
sl->owning_paragraph = NULL;
}
#line 271 "inweb/Chapter 2/The Reader.w"
;
}
#line 289 "inweb/Chapter 2/The Reader.w"
pathname *Reader__woven_folder(web *W) {
pathname *P = Pathnames__subfolder(W->md->path_to_web, TL_IS_123);
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_124);
if (Pathnames__create_in_file_system(P) == FALSE)
Errors__fatal_with_path("unable to create Tangled subdirectory", P);
return P;
}
#line 310 "inweb/Chapter 2/The Reader.w"
chapter *Reader__get_chapter_for_range(web *W, text_stream *range) {
chapter *C;
if (W)
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
if (Str__eq(C->md->ch_range, range))
return C;
return NULL;
}
section *Reader__get_section_for_range(web *W, text_stream *range) {
chapter *C;
section *S;
if (W)
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Str__eq(S->md->sect_range, range))
return S;
return NULL;
}
#line 333 "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 355 "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 382 "inweb/Chapter 2/The Reader.w"
#line 384 "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 408 "inweb/Chapter 2/The Reader.w"
void Reader__add_imported_header(web *W, filename *HF) {
ADD_TO_LINKED_LIST(HF, filename, W->headers);
}
#line 415 "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 423 "inweb/Chapter 2/The Reader.w"
void Reader__print_web_statistics(web *W) {
PRINT("web \"%S\": ", Bibliographic__get_datum(W->md, TL_IS_125));
int c = WebMetadata__chapter_count(W->md);
int s = WebMetadata__section_count(W->md);
if (W->md->chaptered) PRINT("%d chapter%s : ",
c, (c == 1)?"":"s");
PRINT("%d section%s : %d paragraph%s : %d line%s\n",
s, (s == 1)?"":"s",
W->no_paragraphs, (W->no_paragraphs == 1)?"":"s",
W->web_extent, (W->web_extent == 1)?"":"s");
}
#line 43 "inweb/Chapter 2/Line Categories.w"
#line 45 "inweb/Chapter 2/Line Categories.w"
source_line *Lines__new_source_line_in(text_stream *line, text_file_position *tfp,
section *S) {
source_line *sl = CREATE(source_line);
sl->text = Str__duplicate(line);
sl->text_operand = Str__new();
sl->text_operand2 = Str__new();
sl->category = NO_LCAT; /* that is, unknown category as yet */
sl->command_code = NO_CMD;
sl->default_defn = FALSE;
sl->plainer = FALSE;
sl->enable_hyperlinks = FALSE;
sl->colour_as = NULL;
sl->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 = S;
sl->owning_section->sect_extent++;
sl->owning_section->owning_chapter->owning_web->web_extent++;
sl->next_line = NULL;
sl->owning_paragraph = NULL;
return sl;
}
#line 83 "inweb/Chapter 2/Line Categories.w"
#line 108 "inweb/Chapter 2/Line Categories.w"
#line 113 "inweb/Chapter 2/Line Categories.w"
char *Lines__category_name(int cat) {
switch (cat) {
case NO_LCAT: return "(uncategorised)";
case BAR_LCAT: return "BAR";
case BEGIN_CODE_LCAT: return "BEGIN_CODE";
case BEGIN_DEFINITION_LCAT: return "BEGIN_DEFINITION";
case C_LIBRARY_INCLUDE_LCAT: return "C_LIBRARY_INCLUDE";
case CHAPTER_HEADING_LCAT: return "CHAPTER_HEADING";
case CODE_BODY_LCAT: return "CODE_BODY";
case COMMAND_LCAT: return "COMMAND";
case COMMENT_BODY_LCAT: return "COMMENT_BODY";
case CONT_DEFINITION_LCAT: return "CONT_DEFINITION";
case DEFINITIONS_LCAT: return "DEFINITIONS";
case END_EXTRACT_LCAT: return "END_EXTRACT";
case 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 155 "inweb/Chapter 2/Line Categories.w"
#line 17 "inweb/Chapter 2/The Parser.w"
void Parser__parse_web(web *W, int inweb_mode) {
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
{
#line 34 "inweb/Chapter 2/The Parser.w"
int comment_mode = TRUE, extract_mode = FALSE;
int code_lcat_for_body = NO_LCAT,
code_plainness_for_body = FALSE,
hyperlink_body = FALSE;
programming_language *code_pl_for_body = NULL;
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_in(TL_IS_128, &(L->source), S);
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_127);
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_in(TL_IS_128, &(L->source), S);
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 168 "inweb/Chapter 2/The Parser.w"
if (Str__eq_wide_string(L->text, L"Chapter Heading")) {
comment_mode = TRUE;
extract_mode = FALSE;
L->is_commentary = TRUE;
L->category = CHAPTER_HEADING_LCAT;
}
}
#line 145 "inweb/Chapter 2/The Parser.w"
;
if (L->source.line_count <= 1)
{
#line 179 "inweb/Chapter 2/The Parser.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"%[(%C+)%] (%C+/%C+): (%c+).")) {
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L,
"section range in header line", V1_SYNTAX);
S->sect_namespace = Str__duplicate(mr.exp[0]);
S->md->sect_range = Str__duplicate(mr.exp[1]);
S->md->sect_title = Str__duplicate(mr.exp[2]);
L->text_operand = Str__duplicate(mr.exp[2]);
L->category = SECTION_HEADING_LCAT;
} else if (Regexp__match(&mr, L->text, L"(%C+/%C+): (%c+).")) {
if (S->md->using_syntax >= V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L,
"section range in header line", V1_SYNTAX);
S->md->sect_range = Str__duplicate(mr.exp[0]);
S->md->sect_title = Str__duplicate(mr.exp[1]);
L->text_operand = Str__duplicate(mr.exp[1]);
L->category = SECTION_HEADING_LCAT;
} else if (Regexp__match(&mr, L->text, L"%[(%C+::)%] (%c+).")) {
S->sect_namespace = Str__duplicate(mr.exp[0]);
S->md->sect_title = Str__duplicate(mr.exp[1]);
L->text_operand = Str__duplicate(mr.exp[1]);
L->category = SECTION_HEADING_LCAT;
} else if (Regexp__match(&mr, L->text, L"(%c+).")) {
S->md->sect_title = Str__duplicate(mr.exp[0]);
L->text_operand = Str__duplicate(mr.exp[0]);
L->category = SECTION_HEADING_LCAT;
}
Regexp__dispose_of(&mr);
}
#line 146 "inweb/Chapter 2/The Parser.w"
;
if (extract_mode == FALSE) {
{
#line 214 "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_129);
L->command_code = FIGURE_CMD;
} else {
Main__error_in_web(TL_IS_130, L);
}
L->is_commentary = TRUE;
DISCARD_TEXT(command_text);
DISCARD_TEXT(full_command);
}
Regexp__dispose_of(&mr);
}
#line 148 "inweb/Chapter 2/The Parser.w"
;
{
#line 254 "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_131, L);
else Macros__create(S, current_paragraph, L, para_macro_name);
comment_mode = FALSE; extract_mode = FALSE;
L->is_commentary = FALSE;
code_lcat_for_body = CODE_BODY_LCAT; /* code follows on subsequent lines */
code_pl_for_body = NULL;
code_plainness_for_body = FALSE;
hyperlink_body = FALSE;
DISCARD_TEXT(para_macro_name);
continue;
}
Regexp__dispose_of(&mr);
}
#line 149 "inweb/Chapter 2/The Parser.w"
;
}
if (Str__get_first_char(L->text) == '=') {
if (S->md->using_syntax < V2_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "column-1 '=' as code divider", V2_SYNTAX);
if (extract_mode)
{
#line 296 "inweb/Chapter 2/The Parser.w"
L->category = END_EXTRACT_LCAT;
comment_mode = TRUE;
extract_mode = FALSE;
}
#line 154 "inweb/Chapter 2/The Parser.w"
else
{
#line 303 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
L->plainer = FALSE;
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_132))) {
current_paragraph->placed_very_early = TRUE;
} else if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_133))) {
current_paragraph->placed_early = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text%)"))) {
{
#line 379 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_138)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_139)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_140, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 317 "inweb/Chapter 2/The Parser.w"
;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
code_pl_for_body = NULL;
extract_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text as code%)"))) {
{
#line 379 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_138)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_139)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_140, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 323 "inweb/Chapter 2/The Parser.w"
;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
code_pl_for_body = S->sect_language;
extract_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text as (%c+)%)"))) {
{
#line 379 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_138)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_139)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_140, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 329 "inweb/Chapter 2/The Parser.w"
;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
code_pl_for_body = Languages__find_by_name(mr2.exp[1], W);
extract_mode = TRUE;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text from (%c+) as code%)"))) {
{
#line 379 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_138)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_139)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_140, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 335 "inweb/Chapter 2/The Parser.w"
;
code_pl_for_body = S->sect_language;
{
#line 395 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
pathname *P = W->md->path_to_web;
filename *F = Filenames__from_text_relative(P, mr2.exp[1]);
linked_list *lines = Painter__lines(F);
text_stream *T;
source_line *latest = L;
LOOP_OVER_LINKED_LIST(T, text_stream, lines) {
source_line *TL = Lines__new_source_line_in(T, &(L->source), S);
TL->next_line = latest->next_line;
TL->plainer = L->plainer;
latest->next_line = TL;
latest = TL;
}
source_line *EEL = Lines__new_source_line_in(TL_IS_141, &(L->source), S);
EEL->next_line = latest->next_line;
latest->next_line = EEL;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
extract_mode = TRUE;
}
#line 337 "inweb/Chapter 2/The Parser.w"
;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text from (%c+) as (%c+)%)"))) {
{
#line 379 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_138)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_139)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_140, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 340 "inweb/Chapter 2/The Parser.w"
;
code_pl_for_body = Languages__find_by_name(mr2.exp[2], W);
{
#line 395 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
pathname *P = W->md->path_to_web;
filename *F = Filenames__from_text_relative(P, mr2.exp[1]);
linked_list *lines = Painter__lines(F);
text_stream *T;
source_line *latest = L;
LOOP_OVER_LINKED_LIST(T, text_stream, lines) {
source_line *TL = Lines__new_source_line_in(T, &(L->source), S);
TL->next_line = latest->next_line;
TL->plainer = L->plainer;
latest->next_line = TL;
latest = TL;
}
source_line *EEL = Lines__new_source_line_in(TL_IS_141, &(L->source), S);
EEL->next_line = latest->next_line;
latest->next_line = EEL;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
extract_mode = TRUE;
}
#line 342 "inweb/Chapter 2/The Parser.w"
;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%((%c*?) *text from (%c+)%)"))) {
{
#line 379 "inweb/Chapter 2/The Parser.w"
match_results mr3 = Regexp__create_mr();
while (TRUE) {
if (Regexp__match(&mr3, mr2.exp[0], L" *(%C+) *(%c*?)")) {
if (Str__eq(mr3.exp[0], TL_IS_138)) L->plainer = TRUE;
else if (Str__eq(mr3.exp[0], TL_IS_139)) L->enable_hyperlinks = TRUE;
else {
Main__error_in_web(
TL_IS_140, L);
}
} else break;
Str__clear(mr2.exp[0]);
Str__copy(mr2.exp[0], mr3.exp[1]);
}
Regexp__dispose_of(&mr3);
}
#line 345 "inweb/Chapter 2/The Parser.w"
;
code_pl_for_body = NULL;
{
#line 395 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_CODE_LCAT;
pathname *P = W->md->path_to_web;
filename *F = Filenames__from_text_relative(P, mr2.exp[1]);
linked_list *lines = Painter__lines(F);
text_stream *T;
source_line *latest = L;
LOOP_OVER_LINKED_LIST(T, text_stream, lines) {
source_line *TL = Lines__new_source_line_in(T, &(L->source), S);
TL->next_line = latest->next_line;
TL->plainer = L->plainer;
latest->next_line = TL;
latest = TL;
}
source_line *EEL = Lines__new_source_line_in(TL_IS_141, &(L->source), S);
EEL->next_line = latest->next_line;
latest->next_line = EEL;
code_lcat_for_body = TEXT_EXTRACT_LCAT;
extract_mode = TRUE;
}
#line 347 "inweb/Chapter 2/The Parser.w"
;
} else if ((current_paragraph) &&
(Regexp__match(&mr2, mr.exp[0], L"%(figure (%c+)%)"))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_134);
L->command_code = FIGURE_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
comment_mode = TRUE;
} else if ((current_paragraph) &&
((Regexp__match(&mr2, mr.exp[0], L"%(embedded (%C+) video (%c+)%)")) ||
(Regexp__match(&mr2, mr.exp[0], L"%(embedded (%C+) audio (%c+)%)")))) {
Tags__add_by_name(L->owning_paragraph, TL_IS_135);
L->command_code = EMBED_CMD;
L->category = COMMAND_LCAT;
code_lcat_for_body = COMMENT_BODY_LCAT;
L->text_operand = Str__duplicate(mr2.exp[0]);
L->text_operand2 = Str__duplicate(mr2.exp[1]);
comment_mode = TRUE;
} else {
Main__error_in_web(TL_IS_136, L);
}
} else if (Regexp__match(&mr, L->text, L"= *%C%c*")) {
Main__error_in_web(TL_IS_137, L);
}
code_plainness_for_body = L->plainer;
hyperlink_body = L->enable_hyperlinks;
Regexp__dispose_of(&mr);
Regexp__dispose_of(&mr2);
continue;
}
#line 155 "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 278 "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 421 "inweb/Chapter 2/The Parser.w"
extract_mode = FALSE;
if (Str__eq_wide_string(command_text, L"Purpose:"))
{
#line 469 "inweb/Chapter 2/The Parser.w"
if (before_bar == FALSE) Main__error_in_web(TL_IS_143, 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 422 "inweb/Chapter 2/The Parser.w"
else if (Str__eq_wide_string(command_text, L"Interface:"))
{
#line 478 "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_144, 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 423 "inweb/Chapter 2/The Parser.w"
else if (Str__eq_wide_string(command_text, L"Definitions:"))
{
#line 492 "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_145, L);
L->category = DEFINITIONS_LCAT;
L->is_commentary = TRUE;
before_bar = TRUE;
next_par_number = 1;
}
#line 424 "inweb/Chapter 2/The Parser.w"
else if (Regexp__match(&mr, command_text, L"----+"))
{
#line 504 "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_146, L);
L->category = BAR_LCAT;
L->is_commentary = TRUE;
comment_mode = TRUE;
S->barred = TRUE;
before_bar = FALSE;
next_par_number = 1;
}
#line 425 "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 521 "inweb/Chapter 2/The Parser.w"
if (S->md->using_syntax > V1_SYNTAX)
Parser__wrong_version(S->md->using_syntax, L, "'@c' and '@x'", V1_SYNTAX);
L->category = BEGIN_CODE_LCAT;
if ((Str__eq_wide_string(command_text, L"e")) && (current_paragraph))
current_paragraph->placed_early = TRUE;
if (Str__eq_wide_string(command_text, L"x")) code_lcat_for_body = TEXT_EXTRACT_LCAT;
else code_lcat_for_body = CODE_BODY_LCAT;
code_pl_for_body = NULL;
comment_mode = FALSE;
code_plainness_for_body = FALSE;
hyperlink_body = FALSE;
}
#line 429 "inweb/Chapter 2/The Parser.w"
else if (Str__eq_wide_string(command_text, L"d"))
{
#line 537 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
code_lcat_for_body = CONT_DEFINITION_LCAT;
code_pl_for_body = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
} else {
L->text_operand = Str__duplicate(remainder); /* name of term defined */
L->text_operand2 = Str__new(); /* no value given */
}
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 430 "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 537 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
code_lcat_for_body = CONT_DEFINITION_LCAT;
code_pl_for_body = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
} else {
L->text_operand = Str__duplicate(remainder); /* name of term defined */
L->text_operand2 = Str__new(); /* no value given */
}
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 434 "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 537 "inweb/Chapter 2/The Parser.w"
L->category = BEGIN_DEFINITION_LCAT;
code_lcat_for_body = CONT_DEFINITION_LCAT;
code_pl_for_body = NULL;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
} else {
L->text_operand = Str__duplicate(remainder); /* name of term defined */
L->text_operand2 = Str__new(); /* no value given */
}
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 439 "inweb/Chapter 2/The Parser.w"
;
} else if (Str__eq_wide_string(command_text, L"enum"))
{
#line 557 "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_147, L);
}
L->text_operand2 = Str__new();
if (inweb_mode == TANGLE_MODE)
Enumerations__define(L->text_operand2, L->text_operand, from, L);
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 440 "inweb/Chapter 2/The Parser.w"
else if ((Str__eq_wide_string(command_text, L"e")) && (S->md->using_syntax >= V2_SYNTAX))
{
#line 557 "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_147, L);
}
L->text_operand2 = Str__new();
if (inweb_mode == TANGLE_MODE)
Enumerations__define(L->text_operand2, L->text_operand, from, L);
Analyser__mark_reserved_word_at_line(L, L->text_operand, CONSTANT_COLOUR);
comment_mode = FALSE;
L->is_commentary = FALSE;
Regexp__dispose_of(&mr);
}
#line 442 "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 609 "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 656 "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_148);
else
P->ornament = Str__duplicate(TL_IS_149);
WRITE_TO(P->paragraph_number, "%d", next_par_number++);
P->parent_paragraph = NULL;
P->next_child_number = 1;
P->starts_on_new_page = FALSE;
P->weight = weight;
P->first_line_in_paragraph = L;
P->defines_macro = NULL;
P->functions = NEW_LINKED_LIST(function);
P->structures = NEW_LINKED_LIST(language_type);
P->taggings = NEW_LINKED_LIST(paragraph_tagging);
P->under_section = S;
S->sect_paragraphs++;
ADD_TO_LINKED_LIST(P, paragraph, S->paragraphs);
current_paragraph = P;
}
#line 625 "inweb/Chapter 2/The Parser.w"
;
L->owning_paragraph = current_paragraph;
W->no_paragraphs++;
Regexp__dispose_of(&mr);
}
#line 461 "inweb/Chapter 2/The Parser.w"
else Main__error_in_web(TL_IS_142, L);
}
}
#line 287 "inweb/Chapter 2/The Parser.w"
;
DISCARD_TEXT(remainder);
DISCARD_TEXT(command_text);
Regexp__dispose_of(&mr);
continue;
}
#line 160 "inweb/Chapter 2/The Parser.w"
;
if (comment_mode)
{
#line 690 "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 161 "inweb/Chapter 2/The Parser.w"
;
if (comment_mode == FALSE)
{
#line 702 "inweb/Chapter 2/The Parser.w"
if ((L->category != BEGIN_DEFINITION_LCAT) && (L->category != COMMAND_LCAT)) {
L->category = code_lcat_for_body;
L->plainer = code_plainness_for_body;
L->enable_hyperlinks = hyperlink_body;
if (L->category == TEXT_EXTRACT_LCAT) L->colour_as = code_pl_for_body;
}
if ((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 162 "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_126, 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 22 "inweb/Chapter 2/The Parser.w"
;
LanguageMethods__parse_types(W, W->main_language);
LanguageMethods__parse_functions(W, W->main_language);
LanguageMethods__further_parsing(W, W->main_language);
}
#line 654 "inweb/Chapter 2/The Parser.w"
#line 723 "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 744 "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 755 "inweb/Chapter 2/The Parser.w"
int Parser__detect_footnote(web *W, text_stream *matter, text_stream *before,
text_stream *cue, text_stream *after) {
text_stream *fn_on_notation =
Bibliographic__get_datum(W->md, TL_IS_150);
text_stream *fn_off_notation =
Bibliographic__get_datum(W->md, TL_IS_151);
if (Str__ne(fn_on_notation, TL_IS_152)) {
int N1 = Str__len(fn_on_notation);
int N2 = Str__len(fn_off_notation);
if ((N1 > 0) && (N2 > 0))
for (int i=0; i < Str__len(matter); i++) {
if (Str__includes_at(matter, i, fn_on_notation)) {
int j = i + N1 + 1;
while (j < Str__len(matter)) {
if (Str__includes_at(matter, j, fn_off_notation)) {
TEMPORARY_TEXT(b);
TEMPORARY_TEXT(c);
TEMPORARY_TEXT(a);
Str__substr(b, Str__start(matter), Str__at(matter, i));
Str__substr(c, Str__at(matter, i + N1), Str__at(matter, j));
Str__substr(a, Str__at(matter, j + N2), Str__end(matter));
int allow = TRUE;
LOOP_THROUGH_TEXT(pos, c)
if (Characters__isdigit(Str__get(pos)) == FALSE)
allow = FALSE;
if (allow) {
Str__clear(before); Str__copy(before, b);
Str__clear(cue); Str__copy(cue, c);
Str__clear(after); Str__copy(after, a);
}
DISCARD_TEXT(b);
DISCARD_TEXT(c);
DISCARD_TEXT(a);
if (allow) return TRUE;
}
j++;
}
}
}
}
return FALSE;
}
#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_153, 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_154, 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_156);
} else {
Formats__text(OUT, wv, TL_IS_157);
}
} else {
Formats__text(OUT, wv, TL_IS_158);
}
Formats__text(OUT, wv, pt->the_tag->ifdef_symbol);
}
if (c > 0) {
if (c == 1) Formats__text(OUT, wv, TL_IS_159);
else Formats__text(OUT, wv, TL_IS_160);
if (sense) Formats__text(OUT, wv, TL_IS_161);
else Formats__text(OUT, wv, TL_IS_162);
}
}
#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_156);
} else {
Formats__text(OUT, wv, TL_IS_157);
}
} else {
Formats__text(OUT, wv, TL_IS_158);
}
Formats__text(OUT, wv, pt->the_tag->ifdef_symbol);
}
if (c > 0) {
if (c == 1) Formats__text(OUT, wv, TL_IS_159);
else Formats__text(OUT, wv, TL_IS_160);
if (sense) Formats__text(OUT, wv, TL_IS_161);
else Formats__text(OUT, wv, TL_IS_162);
}
}
#line 139 "inweb/Chapter 2/Tags.w"
;
if (d > 0) {
Formats__text(OUT, wv, TL_IS_155);
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_163, 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_164, 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_165, 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->md->sect_range)) max_range_width = Str__len(S->md->sect_range);
TEMPORARY_TEXT(main_title);
WRITE_TO(main_title, "%S/%S", C->md->ch_basic_title, S->md->sect_title);
if (max_width < Str__len(main_title)) max_width = Str__len(main_title);
DISCARD_TEXT(main_title);
}
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
if ((Str__eq_wide_string(range, L"0")) || (Str__eq(range, C->md->ch_range))) {
PRINT(" -----\n");
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
TEMPORARY_TEXT(main_title);
WRITE_TO(main_title, "%S/%S", C->md->ch_basic_title, S->md->sect_title);
PRINT("%4d %S", S->sect_extent, S->md->sect_range);
for (int i = Str__len(S->md->sect_range); i<max_range_width+2; i++) PRINT(" ");
PRINT("%S", main_title);
for (int i = Str__len(main_title); i<max_width+2; i++) PRINT(" ");
if (form != BASIC_SECTIONCAT)
Functions__catalogue(S, (form == FUNCTIONS_SECTIONCAT)?TRUE:FALSE);
PRINT("\n");
DISCARD_TEXT(main_title);
}
}
}
#line 106 "inweb/Chapter 3/The Analyser.w"
void Analyser__analyse_code(web *W) {
if (W->analysed) return;
{
#line 141 "inweb/Chapter 3/The Analyser.w"
LanguageMethods__early_preweave_analysis(W->main_language, W);
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if ((L->category == INTERFACE_BODY_LCAT) &&
(L->interface_line_identified == FALSE) &&
(Regexp__string_is_white_space(L->text) == FALSE))
Main__error_in_web(TL_IS_166, L);
}
#line 109 "inweb/Chapter 3/The Analyser.w"
;
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
switch (L->category) {
case BEGIN_DEFINITION_LCAT:
{
#line 155 "inweb/Chapter 3/The Analyser.w"
Analyser__analyse_as_code(W, L, L->text_operand2, ANY_USAGE, 0);
while ((L->next_line) && (L->next_line->category == CONT_DEFINITION_LCAT)) {
L = L->next_line;
Analyser__analyse_as_code(W, L, L->text, ANY_USAGE, 0);
}
}
#line 116 "inweb/Chapter 3/The Analyser.w"
;
break;
case CODE_BODY_LCAT:
{
#line 152 "inweb/Chapter 3/The Analyser.w"
Analyser__analyse_as_code(W, L, L->text, ANY_USAGE, 0);
}
#line 119 "inweb/Chapter 3/The Analyser.w"
;
break;
case PREFORM_GRAMMAR_LCAT:
{
#line 167 "inweb/Chapter 3/The Analyser.w"
Analyser__analyse_as_code(W, L, L->text_operand2, ANY_USAGE, 0);
Analyser__analyse_as_code(W, L, L->text_operand, PREFORM_IN_CODE_USAGE, PREFORM_IN_GRAMMAR_USAGE);
}
#line 122 "inweb/Chapter 3/The Analyser.w"
;
break;
}
LanguageMethods__late_preweave_analysis(W->main_language, W);
W->analysed = TRUE;
}
#line 183 "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 225 "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 252 "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; i<HASH_TAB_SIZE; i++) HT->analysis_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"
hash_table_entry *Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(HT, p, TRUE);
hte->reserved_word |= (1 << e);
hte->definition_line = NULL;
hte->as_function = NULL;
return hte;
}
void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) {
Analyser__mark_reserved_word(&(S->sect_target->symbols), p, e);
}
hash_table_entry *Analyser__mark_reserved_word_at_line(source_line *L, text_stream *p, int e) {
if (L == NULL) internal_error("no line for rw");
hash_table_entry *hte =
Analyser__mark_reserved_word(&(L->owning_section->sect_target->symbols), p, e);
hte->definition_line = L;
return hte;
}
int Analyser__is_reserved_word(hash_table *HT, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(HT, p, FALSE);
if ((hte) && (hte->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);
}
source_line *Analyser__get_defn_line(section *S, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(&(S->sect_target->symbols), p, FALSE);
if ((hte) && (hte->reserved_word & (1 << e))) return hte->definition_line;
return NULL;
}
language_function *Analyser__get_function(section *S, text_stream *p, int e) {
hash_table_entry *hte = Analyser__find_hash_entry(&(S->sect_target->symbols), p, FALSE);
if ((hte) && (hte->reserved_word & (1 << e))) return hte->as_function;
return NULL;
}
#line 359 "inweb/Chapter 3/The Analyser.w"
#line 363 "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 385 "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_167);
if (!(TextFiles__exists(prototype)))
prototype = Filenames__in_folder(path_to_inweb_materials, TL_IS_168);
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_169);
if (!(TextFiles__exists(prototype)))
prototype = Filenames__in_folder(path_to_inweb_materials, TL_IS_170);
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,
linked_list *breadcrumbs, filename *navigation) {
swarm_leader = NULL;
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
if (C->md->imported == FALSE) {
if (swarm_mode == SWARM_CHAPTERS_SWM)
if ((W->md->chaptered == TRUE) && (Reader__range_within(C->md->ch_range, range))) {
C->ch_weave = Swarm__weave_subset(W,
C->md->ch_range, FALSE, tag, pattern, to, into,
breadcrumbs, navigation);
if (Str__len(range) > 0) swarm_leader = C->ch_weave;
}
if (swarm_mode == SWARM_SECTIONS_SWM)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Reader__range_within(S->md->sect_range, range))
S->sect_weave = Swarm__weave_subset(W,
S->md->sect_range, FALSE, tag, pattern, to, into,
breadcrumbs, navigation);
}
Swarm__weave_index_templates(W, range, pattern, (to)?TRUE:FALSE, into, navigation,
breadcrumbs);
}
#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,
linked_list *breadcrumbs, filename *navigation) {
weave_target *wt = NULL;
if (no_inweb_errors == 0) {
Analyser__analyse_code(W);
{
#line 94 "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->navigation = navigation;
wt->breadcrumbs = breadcrumbs;
wt->plugins = NEW_LINKED_LIST(weave_plugin);
if (Reader__web_has_one_section(W)) wt->self_contained = TRUE;
Str__copy(wt->cover_sheet_to_use, TL_IS_171);
wt->current_weave_line = NULL;
wt->footnotes_cued = NEW_LINKED_LIST(text_stream);
wt->footnotes_written = NEW_LINKED_LIST(text_stream);
wt->current_footnote = Str__new();
int has_content = FALSE;
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Reader__range_within(S->md->sect_range, wt->weave_range))
has_content = TRUE;
if (has_content == FALSE)
Errors__fatal("no sections match that range");
TEMPORARY_TEXT(leafname);
{
#line 145 "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 183 "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 153 "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 if (Str__eq_wide_string(range, L"M")) {
wt->booklet_title = Str__new_from_wide_string(L"Manual");
Str__copy(leafname, wt->booklet_title);
} else {
section *S = Reader__get_section_for_range(W, range);
if (S) Str__copy(wt->booklet_title, S->md->sect_title);
else Str__copy(wt->booklet_title, range);
Str__copy(leafname, range);
Str__clear(wt->cover_sheet_to_use);
}
Bibliographic__set_datum(W->md, TL_IS_172, wt->booklet_title);
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 126 "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 190 "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 92 "inweb/Chapter 3/The Swarm.w"
#line 195 "inweb/Chapter 3/The Swarm.w"
void Swarm__ensure_plugin(weave_target *wt, text_stream *name) {
weave_plugin *existing;
LOOP_OVER_LINKED_LIST(existing, weave_plugin, wt->plugins)
if (Str__eq_insensitive(name, existing->plugin_name))
return;
weave_plugin *wp = WeavePlugins__new(name);
ADD_TO_LINKED_LIST(wp, weave_plugin, wt->plugins);
}
#line 209 "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) {
if (!(Bibliographic__data_exists(W->md, TL_IS_173)))
Bibliographic__set_datum(W->md, TL_IS_174, TL_IS_175);
text_stream *index_leaf = NULL;
if (W->md->chaptered) index_leaf = TL_IS_176;
else index_leaf = TL_IS_177;
filename *OUT = Patterns__obtain_filename(pattern, index_leaf);
if (OUT == NULL) OUT = Patterns__obtain_filename(pattern, TL_IS_178);
if (OUT) Indexer__run(W, range, OUT, TL_IS_179, NULL, pattern, into, F, crumbs, TRUE);
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" *%<link href=%\"(%c+?)\"%c*"))) {
filename *CSS_file = Patterns__obtain_filename(state->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"Plugins")) {
weave_plugin *wp;
LOOP_OVER_LINKED_LIST(wp, weave_plugin, state->target->plugins)
WeavePlugins__include(OUT, state->target->weave_web, wp,
state->target->pattern);
} else if (Str__eq_wide_string(command, L"Cover Sheet")) {
if (include)
{
#line 104 "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_180, 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 91 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr2, command, L"Navigation")) {
if (include)
{
#line 116 "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,
Filenames__get_leafname(state->target->weave_to));
}
#line 93 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr2, command, L"Template (%c*?)")) {
if (include)
{
#line 122 "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 95 "inweb/Chapter 3/The Indexer.w"
;
} else if (Bibliographic__data_exists(state->target->weave_web->md, command)) {
if (include)
{
#line 132 "inweb/Chapter 3/The Indexer.w"
WRITE("%S", Bibliographic__get_datum(state->target->weave_web->md, command));
}
#line 97 "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 137 "inweb/Chapter 3/The Indexer.w"
void Indexer__nav_column(OUTPUT_STREAM, pathname *P, web *W, text_stream *range,
weave_pattern *pattern, filename *nav, text_stream *leafname) {
if (nav) {
if (TextFiles__exists(nav))
Indexer__nav_run(W, range, nav, leafname, OUT, pattern, P);
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_181);
if (TextFiles__exists(F))
Indexer__nav_run(W, range, F, leafname, OUT, pattern, P);
}
filename *F = Filenames__in_folder(P, TL_IS_182);
if (TextFiles__exists(F))
Indexer__nav_run(W, range, F, leafname, OUT, pattern, P);
}
}
void Indexer__nav_run(web *W, text_stream *range, filename *F, text_stream *leafname,
text_stream *OUT, weave_pattern *pattern, pathname *P) {
Indexer__run(W, range, F, leafname, OUT, pattern, P, NULL, NULL, TRUE);
}
#line 192 "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;
cp.leafname = Str__new();
cp.inside_navigation_submenu = FALSE;
return cp;
}
#line 208 "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 unlink_selflinks) {
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.leafname = Str__duplicate(contents_page_leafname);
contents_processor *cp = &actual_cp;
text_stream TO_struct; text_stream *OUT = &TO_struct;
filename *save_cf = Indexer__current_file();
{
#line 276 "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 222 "inweb/Chapter 3/The Indexer.w"
;
{
#line 291 "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_183, TL_IS_184);
Indexer__set_current_file(Contents);
PRINT("[Index file: %f]\n", Contents);
}
}
#line 223 "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 242 "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 308 "inweb/Chapter 3/The Indexer.w"
PRINT("%04d: %S\nStack:", lpos-1, tl);
for (int j=0; j<cp->stack_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))->md->sect_range,
((section *) CONTENT_IN_ITEM(cp->repeat_stack_threshold[j], section))->md->sect_range);
}
PRINT("\n");
}
#line 244 "inweb/Chapter 3/The Indexer.w"
;
if ((pattern->embed_CSS) &&
(Regexp__match(&mr, tl, L" *%<link href=%\"(%c+?)\"%c*"))) {
filename *CSS_file = Patterns__obtain_filename(pattern, mr.exp[0]);
Indexer__transcribe_CSS(OUT, CSS_file);
Str__clear(tl);
}
if ((unlink_selflinks) &&
(Regexp__match(&mr, tl, L"(%c+?)<a href=\"(%c+?)\">(%c+?)</a>(%c*)")) &&
(Str__eq_insensitive(mr.exp[1], contents_page_leafname))) {
TEMPORARY_TEXT(unlinked);
WRITE_TO(unlinked, "%S<span class=\"unlink\">%S</span>%S",
mr.exp[0], mr.exp[2], mr.exp[3]);
Str__clear(tl);
Str__copy(tl, unlinked);
DISCARD_TEXT(unlinked);
}
if ((Regexp__match(&mr, tl, L"%[%[(%c+)%]%]")) ||
(Regexp__match(&mr, tl, L" %[%[(%c+)%]%]"))) {
TEMPORARY_TEXT(command);
Str__copy(command, mr.exp[0]);
{
#line 326 "inweb/Chapter 3/The Indexer.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, command, L"Select (%c*)")) {
chapter *C;
section *S;
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
LOOP_OVER_LINKED_LIST(S, section, C->sections)
if (Str__eq(S->md->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 265 "inweb/Chapter 3/The Indexer.w"
;
{
#line 352 "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 266 "inweb/Chapter 3/The Indexer.w"
;
{
#line 395 "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 267 "inweb/Chapter 3/The Indexer.w"
;
DISCARD_TEXT(command);
}
{
#line 426 "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 270 "inweb/Chapter 3/The Indexer.w"
;
{
#line 472 "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 537 "inweb/Chapter 3/The Indexer.w"
Str__copy(substituted, Bibliographic__get_datum(W->md, varname));
}
#line 485 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Navigation")) {
{
#line 543 "inweb/Chapter 3/The Indexer.w"
Indexer__nav_column(substituted, cp->nav_path, cp->nav_web,
cp->restrict_to_range, cp->nav_pattern, cp->nav_file, cp->leafname);
}
#line 487 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Breadcrumbs")) {
{
#line 549 "inweb/Chapter 3/The Indexer.w"
Colonies__drop_initial_breadcrumbs(substituted, Indexer__current_file(),
cp->crumbs);
}
#line 489 "inweb/Chapter 3/The Indexer.w"
;
} else if (Str__eq_wide_string(varname, L"Plugins")) {
{
#line 559 "inweb/Chapter 3/The Indexer.w"
weave_plugin *wp;
LOOP_OVER_LINKED_LIST(wp, weave_plugin, cp->nav_pattern->plugins)
WeavePlugins__include(OUT, cp->nav_web, wp, cp->nav_pattern);
}
#line 491 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Modules")) {
{
#line 566 "inweb/Chapter 3/The Indexer.w"
module *M = W->md->as_module;
int L = LinkedLists__len(M->dependencies);
if (L > 0) {
WRITE_TO(substituted,
"<p class=\"purpose\">Together with the following imported module%s:\n",
(L==1)?"":"s");
WRITE_TO(substituted, "<ul class=\"chapterlist\">\n");
Indexer__list_module(substituted, W->md->as_module, FALSE);
WRITE_TO(substituted, "</ul>\n");
}
}
#line 493 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Complete (%c+)")) {
text_stream *detail = mr.exp[0];
{
#line 580 "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 496 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Chapter (%c+)")) {
text_stream *detail = mr.exp[0];
{
#line 588 "inweb/Chapter 3/The Indexer.w"
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 596 "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 593 "inweb/Chapter 3/The Indexer.w"
;
}
#line 499 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Section (%c+)")) {
text_stream *detail = mr.exp[0];
{
#line 612 "inweb/Chapter 3/The Indexer.w"
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 620 "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->md->sect_range);
} else if (Str__eq_wide_string(detail, L"Lines")) {
WRITE_TO(substituted, "%d", S->sect_extent);
} else if (Str__eq_wide_string(detail, L"Source")) {
WRITE_TO(substituted, "%f", S->md->source_file_for_section);
} else if (Str__eq_wide_string(detail, L"Page")) {
TEMPORARY_TEXT(linkto);
Str__copy(linkto, S->md->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 617 "inweb/Chapter 3/The Indexer.w"
;
}
#line 502 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"URL \"(%c+)\"")) {
text_stream *link_text = mr.exp[0];
{
#line 656 "inweb/Chapter 3/The Indexer.w"
Pathnames__relative_URL(substituted,
Filenames__get_path_to(Indexer__current_file()),
Pathnames__from_text(link_text));
}
#line 505 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Link \"(%c+)\"")) {
text_stream *link_text = mr.exp[0];
{
#line 661 "inweb/Chapter 3/The Indexer.w"
WRITE_TO(substituted, "<a href=\"");
Colonies__reference_URL(substituted, link_text, Indexer__current_file());
WRITE_TO(substituted, "\">");
}
#line 508 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Menu \"(%c+)\"")) {
text_stream *menu_name = mr.exp[0];
{
#line 666 "inweb/Chapter 3/The Indexer.w"
if (cp->inside_navigation_submenu) WRITE_TO(substituted, "</ul>");
WRITE_TO(substituted, "<h2>%S</h2><ul>", menu_name);
cp->inside_navigation_submenu = TRUE;
}
#line 511 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Item \"(%c+)\"")) {
text_stream *item_name = mr.exp[0];
text_stream *link_text = item_name;
{
#line 671 "inweb/Chapter 3/The Indexer.w"
TEMPORARY_TEXT(url);
Colonies__reference_URL(url, link_text, Indexer__current_file());
{
#line 683 "inweb/Chapter 3/The Indexer.w"
if (cp->inside_navigation_submenu == FALSE) WRITE_TO(substituted, "<ul>");
cp->inside_navigation_submenu = TRUE;
WRITE_TO(substituted, "<li>");
if (Str__eq(url, Filenames__get_leafname(Indexer__current_file()))) {
WRITE_TO(substituted, "<span class=\"unlink\">");
WRITE_TO(substituted, "%S", item_name);
WRITE_TO(substituted, "</span>");
} else if (Str__eq(url, TL_IS_185)) {
WRITE_TO(substituted, "<a href=\"%S\">", url);
WRITE_TO(substituted, "<span class=\"selectedlink\">");
WRITE_TO(substituted, "%S", item_name);
WRITE_TO(substituted, "</span>");
WRITE_TO(substituted, "</a>");
} else {
WRITE_TO(substituted, "<a href=\"%S\">", url);
WRITE_TO(substituted, "%S", item_name);
WRITE_TO(substituted, "</a>");
}
WRITE_TO(substituted, "</li>");
}
#line 673 "inweb/Chapter 3/The Indexer.w"
;
DISCARD_TEXT(url);
}
#line 515 "inweb/Chapter 3/The Indexer.w"
;
} else if (Regexp__match(&mr, varname, L"Item \"(%c+)\" -> (%c+)")) {
text_stream *item_name = mr.exp[0];
text_stream *link_text = mr.exp[1];
{
#line 677 "inweb/Chapter 3/The Indexer.w"
TEMPORARY_TEXT(url);
Colonies__link_URL(url, link_text, Indexer__current_file());
{
#line 683 "inweb/Chapter 3/The Indexer.w"
if (cp->inside_navigation_submenu == FALSE) WRITE_TO(substituted, "<ul>");
cp->inside_navigation_submenu = TRUE;
WRITE_TO(substituted, "<li>");
if (Str__eq(url, Filenames__get_leafname(Indexer__current_file()))) {
WRITE_TO(substituted, "<span class=\"unlink\">");
WRITE_TO(substituted, "%S", item_name);
WRITE_TO(substituted, "</span>");
} else if (Str__eq(url, TL_IS_185)) {
WRITE_TO(substituted, "<a href=\"%S\">", url);
WRITE_TO(substituted, "<span class=\"selectedlink\">");
WRITE_TO(substituted, "%S", item_name);
WRITE_TO(substituted, "</span>");
WRITE_TO(substituted, "</a>");
} else {
WRITE_TO(substituted, "<a href=\"%S\">", url);
WRITE_TO(substituted, "%S", item_name);
WRITE_TO(substituted, "</a>");
}
WRITE_TO(substituted, "</li>");
}
#line 679 "inweb/Chapter 3/The Indexer.w"
;
DISCARD_TEXT(url);
}
#line 519 "inweb/Chapter 3/The Indexer.w"
;
} else {
WRITE_TO(substituted, "%S", varname);
if (Regexp__match(&mr, varname, L"%i+%c*"))
PRINT("Warning: unable to resolve command '%S'\n", 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 271 "inweb/Chapter 3/The Indexer.w"
;
}
#line 230 "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 (actual_cp.inside_navigation_submenu) WRITE("</ul>");
if (write_to == NULL) STREAM_CLOSE(OUT);
Indexer__set_current_file(save_cf);
}
#line 284 "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 441 "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 452 "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 704 "inweb/Chapter 3/The Indexer.w"
void Indexer__list_module(OUTPUT_STREAM, module *M, int list_this) {
if (list_this) {
WRITE("<li><p>%S - ", M->module_name);
TEMPORARY_TEXT(url);
WRITE_TO(url, "%p", M->module_location);
Readme__write_var(OUT, url, TL_IS_186);
DISCARD_TEXT(url);
WRITE("</p></li>");
}
module *N;
LOOP_OVER_LINKED_LIST(N, module, M->dependencies)
Indexer__list_module(OUT, N, TRUE);
}
#line 721 "inweb/Chapter 3/The Indexer.w"
void Indexer__transcribe_CSS(OUTPUT_STREAM, filename *CSS_file) {
WRITE("<style type=\"text/css\">\n");
TextFiles__read(CSS_file, FALSE, "can't open CSS file",
TRUE, Indexer__copy_CSS, NULL, OUT);
WRITE("\n</style>\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 736 "inweb/Chapter 3/The Indexer.w"
filename *file_being_woven = NULL;
filename *Indexer__current_file(void) {
return file_being_woven;
}
void Indexer__set_current_file(filename *F) {
file_being_woven = F;
}
#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);
Indexer__set_current_file(wv->weave_to);
{
#line 39 "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 23 "inweb/Chapter 3/The Weaver.w"
;
if ((Str__len(wv->cover_sheet_to_use) > 0) && (Reader__web_has_one_section(W) == FALSE))
{
#line 45 "inweb/Chapter 3/The Weaver.w"
if (!(Bibliographic__data_exists(W->md, TL_IS_187)))
Bibliographic__set_datum(W->md, TL_IS_188, wv->booklet_title);
Indexer__cover_sheet_maker(OUT, W, wv->cover_sheet_to_use, wv, WEAVE_FIRST_HALF);
}
#line 25 "inweb/Chapter 3/The Weaver.w"
;
int lines_woven = 0;
section *latest_section = NULL;
{
#line 50 "inweb/Chapter 3/The Weaver.w"
weaver_state state_at; weaver_state *state = &state_at;
{
#line 102 "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 51 "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->md->sect_range, wv->weave_range)) {
latest_section = S;
{
#line 115 "inweb/Chapter 3/The Weaver.w"
wv->footnotes_cued = NEW_LINKED_LIST(text_stream);
wv->footnotes_written = NEW_LINKED_LIST(text_stream);
wv->current_footnote = Str__new();
}
#line 60 "inweb/Chapter 3/The Weaver.w"
;
LanguageMethods__begin_weave(S, wv);
Str__clear(state->sectionmark);
{
#line 122 "inweb/Chapter 3/The Weaver.w"
paragraph *current_paragraph = NULL;
for (source_line *L = S->first_line; L; L = L->next_line) {
wv->current_weave_line = L;
if ((Tags__tagged_with(L->owning_paragraph, wv->theme_match)) &&
(LanguageMethods__skip_in_weaving(S->sect_language, wv, L) == FALSE)) {
lines_woven++;
{
#line 135 "inweb/Chapter 3/The Weaver.w"
/* In principle, all of these source lines should be woven, but... */
{
#line 159 "inweb/Chapter 3/The Weaver.w"
if (L->category == INTERFACE_BODY_LCAT) continue;
if (L->category == PURPOSE_BODY_LCAT) continue;
if (L->category == END_EXTRACT_LCAT) {
Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL,
TRUE, FALSE);
state->kind_of_material = REGULAR_MATERIAL;
continue;
}
if (L->category == BEGIN_CODE_LCAT) {
state->line_break_pending = FALSE;
LanguageMethods__reset_syntax_colouring(S->sect_language);
continue;
}
}
#line 136 "inweb/Chapter 3/The Weaver.w"
;
{
#line 177 "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 187 "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+) 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], W);
Formats__figure(OUT, wv, mr.exp[0], -1, -1, pl);
} else {
Formats__figure(OUT, wv, figname, -1, -1, NULL);
}
Regexp__dispose_of(&mr);
}
#line 180 "inweb/Chapter 3/The Weaver.w"
;
if (L->command_code == EMBED_CMD)
{
#line 212 "inweb/Chapter 3/The Weaver.w"
Formats__embed(OUT, wv, L->text_operand, L->text_operand2);
}
#line 181 "inweb/Chapter 3/The Weaver.w"
;
/* Otherwise assume it was a tangler command, and ignore it here */
continue;
}
}
#line 137 "inweb/Chapter 3/The Weaver.w"
;
/* Some of the more baroque front matter of a section... */
{
#line 220 "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 140 "inweb/Chapter 3/The Weaver.w"
;
{
#line 229 "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 141 "inweb/Chapter 3/The Weaver.w"
;
{
#line 241 "inweb/Chapter 3/The Weaver.w"
if (L->category == INTERFACE_LCAT) {
state->horizontal_rule_just_drawn = FALSE;
continue;
}
}
#line 142 "inweb/Chapter 3/The Weaver.w"
;
{
#line 249 "inweb/Chapter 3/The Weaver.w"
if (L->category == DEFINITIONS_LCAT) {
Formats__subheading(OUT, wv, 2, TL_IS_191, NULL);
state->next_heading_without_vertical_skip = TRUE;
state->horizontal_rule_just_drawn = FALSE;
continue;
}
}
#line 143 "inweb/Chapter 3/The Weaver.w"
;
{
#line 261 "inweb/Chapter 3/The Weaver.w"
if (L->category == BAR_LCAT) {
{
#line 723 "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, L?(L->plainer):FALSE);
}
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 402 "inweb/Chapter 3/The Weaver.w"
if (Str__len(wv->current_footnote) > 0) {
Formats__end_footnote_text(OUT, wv, wv->current_footnote);
Str__clear(wv->current_footnote);
}
}
#line 734 "inweb/Chapter 3/The Weaver.w"
;
}
#line 262 "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 144 "inweb/Chapter 3/The Weaver.w"
;
/* The crucial junction point between modes... */
{
#line 572 "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 723 "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, L?(L->plainer):FALSE);
}
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 402 "inweb/Chapter 3/The Weaver.w"
if (Str__len(wv->current_footnote) > 0) {
Formats__end_footnote_text(OUT, wv, wv->current_footnote);
Str__clear(wv->current_footnote);
}
}
#line 734 "inweb/Chapter 3/The Weaver.w"
;
}
#line 577 "inweb/Chapter 3/The Weaver.w"
;
if (wv->theme_match)
{
#line 607 "inweb/Chapter 3/The Weaver.w"
if ((L->owning_paragraph) &&
(L->owning_paragraph->starts_on_new_page)) Formats__pagebreak(OUT, wv);
}
#line 579 "inweb/Chapter 3/The Weaver.w"
;
LanguageMethods__reset_syntax_colouring(S->sect_language);
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 620 "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->md->sect_range) > 0) Str__copy(state->chaptermark, S->md->sect_range);
if (Str__len(state->chaptermark) > 0) {
Str__clear(state->sectionmark);
WRITE_TO(state->sectionmark, " - %S", L->text_operand);
}
}
}
#line 586 "inweb/Chapter 3/The Weaver.w"
;
text_stream *TeX_macro = NULL;
{
#line 650 "inweb/Chapter 3/The Weaver.w"
switch (weight) {
case 0: TeX_macro = TL_IS_201; break;
case 1: TeX_macro = TL_IS_202; break;
case 2: TeX_macro = TL_IS_203; break;
default: TeX_macro = TL_IS_204; break;
}
if (wv->theme_match)
{
#line 669 "inweb/Chapter 3/The Weaver.w"
switch (weight) {
case 0: TeX_macro = TL_IS_207; break;
case 1: TeX_macro = TL_IS_208; break;
case 2: TeX_macro = TL_IS_209; break;
default: TeX_macro = TL_IS_210; 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 656 "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_205; break;
case 1: TeX_macro = TL_IS_206; break;
}
}
}
#line 589 "inweb/Chapter 3/The Weaver.w"
;
TEMPORARY_TEXT(heading_text);
{
#line 689 "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_211));
} 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 592 "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 711 "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 600 "inweb/Chapter 3/The Weaver.w"
;
if (weight == 3) Formats__chapter_title_page(OUT, wv, C);
continue;
}
}
#line 147 "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 274 "inweb/Chapter 3/The Weaver.w"
{
#line 287 "inweb/Chapter 3/The Weaver.w"
if (L->category == SOURCE_DISPLAY_LCAT) {
Formats__display_line(OUT, wv, L->text_operand);
continue;
}
}
#line 274 "inweb/Chapter 3/The Weaver.w"
;
{
#line 296 "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 275 "inweb/Chapter 3/The Weaver.w"
;
{
#line 312 "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, FALSE);
state->kind_of_material = REGULAR_MATERIAL;
Formats__item(OUT, wv, 1, TL_IS_192);
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, FALSE);
state->kind_of_material = REGULAR_MATERIAL;
Formats__item(OUT, wv, 2, TL_IS_193);
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, FALSE);
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, FALSE);
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 276 "inweb/Chapter 3/The Weaver.w"
;
{
#line 344 "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, L->plainer);
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; i<Str__len(original); i++) PUT_TO(colouring, PLAIN_COLOUR);
Formats__source_code(OUT, wv, 1, TL_IS_194, original, colouring, TL_IS_195, TRUE, TRUE,
FALSE, L->enable_hyperlinks);
Formats__text(OUT, wv, matter);
DISCARD_TEXT(colouring);
DISCARD_TEXT(original);
continue;
} else if (state->kind_of_material != REGULAR_MATERIAL) {
Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL,
TRUE, FALSE);
state->kind_of_material = REGULAR_MATERIAL;
}
Regexp__dispose_of(&mr);
}
#line 277 "inweb/Chapter 3/The Weaver.w"
;
{
#line 370 "inweb/Chapter 3/The Weaver.w"
TEMPORARY_TEXT(before);
TEMPORARY_TEXT(cue);
TEMPORARY_TEXT(after);
int this_is_a_cue = FALSE;
if (Parser__detect_footnote(wv->weave_web, matter, before, cue, after)) {
LOOP_THROUGH_TEXT(pos, before)
if (Characters__is_whitespace(Str__get(pos)) == FALSE)
this_is_a_cue = TRUE;
if (this_is_a_cue) {
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, wv->footnotes_cued)
if (Str__eq(T, cue))
Main__error_in_web(TL_IS_196, L);
ADD_TO_LINKED_LIST(T, text_stream, wv->footnotes_cued);
if (Str__len(wv->current_footnote) > 0)
Main__error_in_web(TL_IS_197, L);
} else {
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, wv->footnotes_written)
if (Str__eq(T, cue))
Main__error_in_web(TL_IS_198, L);
ADD_TO_LINKED_LIST(T, text_stream, wv->footnotes_written);
{
#line 402 "inweb/Chapter 3/The Weaver.w"
if (Str__len(wv->current_footnote) > 0) {
Formats__end_footnote_text(OUT, wv, wv->current_footnote);
Str__clear(wv->current_footnote);
}
}
#line 392 "inweb/Chapter 3/The Weaver.w"
;
Str__copy(wv->current_footnote, cue);
Formats__begin_footnote_text(OUT, wv, cue);
}
}
DISCARD_TEXT(before);
DISCARD_TEXT(cue);
DISCARD_TEXT(after);
}
#line 278 "inweb/Chapter 3/The Weaver.w"
;
state->substantive_comment = TRUE;
WRITE_TO(matter, "\n");
Formats__text(OUT, wv, matter);
continue;
}
#line 151 "inweb/Chapter 3/The Weaver.w"
else
{
#line 413 "inweb/Chapter 3/The Weaver.w"
{
#line 451 "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, L->plainer);
state->line_break_pending = FALSE;
}
}
#line 413 "inweb/Chapter 3/The Weaver.w"
;
{
#line 473 "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 414 "inweb/Chapter 3/The Weaver.w"
;
int tab_stops_of_indentation = 0;
{
#line 486 "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);
}
if (spaces_in > 0) {
TEMPORARY_TEXT(respaced);
while (spaces_in > 0) { PUT_TO(respaced, ' '); spaces_in--; }
WRITE_TO(respaced, "%S", matter);
Str__clear(matter);
Str__copy(matter, respaced);
DISCARD_TEXT(respaced);
}
}
#line 417 "inweb/Chapter 3/The Weaver.w"
;
TEMPORARY_TEXT(prefatory);
TEMPORARY_TEXT(concluding_comment);
{
#line 514 "inweb/Chapter 3/The Weaver.w"
TEMPORARY_TEXT(part_before_comment);
TEMPORARY_TEXT(part_within_comment);
programming_language *pl = S->sect_language;
if (L->category == TEXT_EXTRACT_LCAT) pl = L->colour_as;
if ((pl) && (LanguageMethods__parse_comment(pl,
matter, part_before_comment, part_within_comment))) {
Str__copy(matter, part_before_comment);
Str__copy(concluding_comment, part_within_comment);
}
DISCARD_TEXT(part_before_comment);
DISCARD_TEXT(part_within_comment);
}
#line 421 "inweb/Chapter 3/The Weaver.w"
;
{
#line 529 "inweb/Chapter 3/The Weaver.w"
if (L->category == BEGIN_DEFINITION_LCAT) {
match_results mr = Regexp__create_mr();
if ((Regexp__match(&mr, matter, L"@d (%c*)")) ||
(Regexp__match(&mr, matter, L"@define (%c*)"))) {
Str__copy(prefatory, TL_IS_199);
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_200);
Str__copy(matter, mr.exp[0]);
}
Regexp__dispose_of(&mr);
}
}
#line 422 "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, L, matter, colouring);
int found = 0;
{
#line 544 "inweb/Chapter 3/The Weaver.w"
match_results mr = Regexp__create_mr();
while (Regexp__match(&mr, matter, L"(%c*?)%@%<(%c*?)%@%>(%c*)")) {
para_macro *pmac = Macros__find_by_name(mr.exp[1], S);
if (pmac) {
Str__copy(matter, mr.exp[2]);
Formats__source_code(OUT, wv, tab_stops_of_indentation, prefatory,
mr.exp[0], colouring, concluding_comment, (found == 0)?TRUE:FALSE,
FALSE, TRUE, L->enable_hyperlinks);
LanguageMethods__reset_syntax_colouring(S->sect_language);
found++;
int defn = FALSE;
if (pmac) defn = (L->owning_paragraph == pmac->defining_paragraph)?TRUE:FALSE;
if (defn) state->in_run_of_definitions = FALSE;
if (pmac) 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);
} else break;
}
Regexp__dispose_of(&mr);
}
#line 431 "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, L->enable_hyperlinks);
DISCARD_TEXT(colouring);
DISCARD_TEXT(concluding_comment);
DISCARD_TEXT(prefatory);
continue;
}
#line 152 "inweb/Chapter 3/The Weaver.w"
;
DISCARD_TEXT(matter);
}
#line 128 "inweb/Chapter 3/The Weaver.w"
;
}
}
source_line *L = NULL;
{
#line 723 "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, L?(L->plainer):FALSE);
}
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 402 "inweb/Chapter 3/The Weaver.w"
if (Str__len(wv->current_footnote) > 0) {
Formats__end_footnote_text(OUT, wv, wv->current_footnote);
Str__clear(wv->current_footnote);
}
}
#line 734 "inweb/Chapter 3/The Weaver.w"
;
}
#line 132 "inweb/Chapter 3/The Weaver.w"
;
}
#line 63 "inweb/Chapter 3/The Weaver.w"
;
}
}
}
#line 28 "inweb/Chapter 3/The Weaver.w"
;
if ((Str__len(wv->cover_sheet_to_use) > 0) && (Reader__web_has_one_section(W) == FALSE))
{
#line 68 "inweb/Chapter 3/The Weaver.w"
if (!(Bibliographic__data_exists(W->md, TL_IS_189)))
Bibliographic__set_datum(W->md, TL_IS_190, wv->booklet_title);
Indexer__cover_sheet_maker(OUT, W, wv->cover_sheet_to_use, wv, WEAVE_SECOND_HALF);
}
#line 30 "inweb/Chapter 3/The Weaver.w"
;
{
#line 73 "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 31 "inweb/Chapter 3/The Weaver.w"
;
STREAM_CLOSE(OUT);
Indexer__set_current_file(NULL);
return lines_woven;
}
#line 85 "inweb/Chapter 3/The Weaver.w"
#line 100 "inweb/Chapter 3/The Weaver.w"
#line 741 "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 755 "inweb/Chapter 3/The Weaver.w"
Formats__endnote(OUT, wv, 1);
Formats__text(OUT, wv, TL_IS_212);
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_213);
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_214);
else Formats__text(OUT, wv, TL_IS_215);
} else {
Formats__text(OUT, wv, TL_IS_216);
}
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_217); break;
case 3: Formats__text(OUT, wv, TL_IS_218); break;
case 4: Formats__text(OUT, wv, TL_IS_219); break;
case 5: Formats__text(OUT, wv, TL_IS_220); 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_221);
Formats__endnote(OUT, wv, 2);
}
#line 745 "inweb/Chapter 3/The Weaver.w"
;
language_function *fn;
LOOP_OVER_LINKED_LIST(fn, language_function, P->functions)
{
#line 794 "inweb/Chapter 3/The Weaver.w"
if (fn->usage_described == FALSE) {
Formats__endnote(OUT, wv, 1);
Weaver__show_function_usage(OUT, wv, P, fn, FALSE);
Formats__endnote(OUT, wv, 2);
}
}
#line 748 "inweb/Chapter 3/The Weaver.w"
;
language_type *st;
LOOP_OVER_LINKED_LIST(st, language_type, P->structures)
{
#line 801 "inweb/Chapter 3/The Weaver.w"
Formats__endnote(OUT, wv, 1);
Formats__text(OUT, wv, TL_IS_222);
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_223);
else {
Formats__text(OUT, wv, TL_IS_224);
int c = 0;
LOOP_OVER(S, section)
if ((S->scratch_flag) && (S != P->under_section)) {
if (c++ > 0) Formats__text(OUT, wv, TL_IS_225);
Formats__text(OUT, wv, S->md->sect_range);
}
if (P->under_section->scratch_flag) Formats__text(OUT, wv, TL_IS_226);
}
Formats__text(OUT, wv, TL_IS_227);
Formats__endnote(OUT, wv, 2);
}
#line 751 "inweb/Chapter 3/The Weaver.w"
;
}
#line 841 "inweb/Chapter 3/The Weaver.w"
void Weaver__show_function_usage(OUTPUT_STREAM, weave_target *wv, paragraph *P,
language_function *fn, int as_list) {
fn->usage_described = TRUE;
hash_table_entry *hte =
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
fn->function_name, FALSE);
if (as_list == FALSE) {
Formats__text(OUT, wv, TL_IS_228);
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 877 "inweb/Chapter 3/The Weaver.w"
if (as_list == FALSE) {
if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_233);
}
used_flag = TRUE;
section *S = hteu->usage_recorded_at->under_section;
if ((S != last_cited_in) && (S != P->under_section)) {
count_under = 0;
if (last_cited_in) {
if (as_list == FALSE) {
if (last_cited_in != P->under_section) Formats__text(OUT, wv, TL_IS_234);
else Formats__text(OUT, wv, TL_IS_235);
} else {
if (last_cited_in != P->under_section) WRITE("<br>");
else Formats__text(OUT, wv, TL_IS_236);
}
}
Formats__text(OUT, wv, hteu->usage_recorded_at->under_section->md->sect_title);
if (as_list == FALSE) Formats__text(OUT, wv, TL_IS_237);
else WRITE(" - ");
}
if (count_under++ > 0) Formats__text(OUT, wv, TL_IS_238);
Formats__locale(OUT, wv, hteu->usage_recorded_at, NULL);
last_cited_in = hteu->usage_recorded_at->under_section;
}
#line 858 "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 877 "inweb/Chapter 3/The Weaver.w"
if (as_list == FALSE) {
if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_233);
}
used_flag = TRUE;
section *S = hteu->usage_recorded_at->under_section;
if ((S != last_cited_in) && (S != P->under_section)) {
count_under = 0;
if (last_cited_in) {
if (as_list == FALSE) {
if (last_cited_in != P->under_section) Formats__text(OUT, wv, TL_IS_234);
else Formats__text(OUT, wv, TL_IS_235);
} else {
if (last_cited_in != P->under_section) WRITE("<br>");
else Formats__text(OUT, wv, TL_IS_236);
}
}
Formats__text(OUT, wv, hteu->usage_recorded_at->under_section->md->sect_title);
if (as_list == FALSE) Formats__text(OUT, wv, TL_IS_237);
else WRITE(" - ");
}
if (count_under++ > 0) Formats__text(OUT, wv, TL_IS_238);
Formats__locale(OUT, wv, hteu->usage_recorded_at, NULL);
last_cited_in = hteu->usage_recorded_at->under_section;
}
#line 861 "inweb/Chapter 3/The Weaver.w"
;
if (used_flag == FALSE) {
if (as_list == FALSE) {
Formats__text(OUT, wv, TL_IS_229);
} else {
Formats__text(OUT, wv, TL_IS_230);
}
}
if (as_list == FALSE) {
if ((last_cited_in != P->under_section) && (last_cited_in))
Formats__text(OUT, wv, TL_IS_231);
Formats__text(OUT, wv, TL_IS_232);
}
}
#line 906 "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->md->sect_range, TL_IS_239, 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_240, TL_IS_241, 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_242, TL_IS_243, 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_244, 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_244, 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; i<mlen-4; i++) Str__put_at(temp, i, Str__get_at(original, mpos+2+i));
Str__truncate(temp, mlen-4);
para_macro *pmac = Macros__find_by_name(temp, S);
if (pmac) {
LanguageMethods__before_macro_expansion(OUT, lang, pmac);
Tangler__tangle_paragraph(OUT, pmac->defining_paragraph);
LanguageMethods__after_macro_expansion(OUT, lang, pmac);
LanguageMethods__insert_line_marker(OUT, lang, L);
} else {
Main__error_in_web(TL_IS_245, 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; i<spos; i++) PUT_TO(temp, Str__get_at(original, i));
LanguageMethods__tangle_code(OUT, S->sect_language, temp);
for (int i=0; i<slen-4; i++) Str__put_at(temp, i, Str__get_at(original, spos+2+i));
Str__truncate(temp, slen-4);
if (LanguageMethods__special_tangle_command(OUT, S->sect_language, temp) == FALSE) {
if (Bibliographic__look_up_datum(W->md, temp))
WRITE("%S", Bibliographic__get_datum(W->md, temp));
else
WRITE("[[%S]]", temp);
}
TEMPORARY_TEXT(rest);
Str__substr(rest, Str__at(original, spos + slen), Str__end(original));
Tangler__tangle_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, web *W) {
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"
filename *F = NULL;
if (W) {
pathname *P = Pathnames__subfolder(W->md->path_to_web, TL_IS_246);
{
#line 39 "inweb/Chapter 4/Programming Languages.w"
if (F == NULL) {
TEMPORARY_TEXT(leaf);
WRITE_TO(leaf, "%S.ildf", lname);
F = Filenames__in_folder(P, leaf);
DISCARD_TEXT(leaf);
if (TextFiles__exists(F) == FALSE) F = NULL;
}
}
#line 29 "inweb/Chapter 4/Programming Languages.w"
;
}
pathname *P = Languages__default_directory();
{
#line 39 "inweb/Chapter 4/Programming Languages.w"
if (F == NULL) {
TEMPORARY_TEXT(leaf);
WRITE_TO(leaf, "%S.ildf", lname);
F = Filenames__in_folder(P, leaf);
DISCARD_TEXT(leaf);
if (TextFiles__exists(F) == FALSE) F = NULL;
}
}
#line 32 "inweb/Chapter 4/Programming Languages.w"
;
if (F == NULL)
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 50 "inweb/Chapter 4/Programming Languages.w"
programming_language *Languages__default(web *W) {
return Languages__find_by_name(TL_IS_247, W);
}
void Languages__show(OUTPUT_STREAM) {
WRITE("Inweb can see the following programming language definitions:\n\n");
int N = NUMBER_CREATED(programming_language);
programming_language **sorted_table =
Memory__I7_calloc(N, (int) sizeof(programming_language *), CLS_SORTING_MREASON);
int i=0; programming_language *pl;
LOOP_OVER(pl, programming_language) sorted_table[i++] = pl;
qsort(sorted_table, (size_t) N, sizeof(programming_language *), Languages__compare_names);
for (int i=0; i<N; i++) {
programming_language *pl = sorted_table[i];
WRITE("%S: %S\n", pl->language_name, pl->language_details);
}
Memory__I7_free(sorted_table, CLS_SORTING_MREASON, N*((int) sizeof(programming_language *)));
}
#line 71 "inweb/Chapter 4/Programming Languages.w"
int Languages__compare_names(const void *ent1, const void *ent2) {
text_stream *tx1 = (*((const programming_language **) ent1))->language_name;
text_stream *tx2 = (*((const programming_language **) ent2))->language_name;
return Str__cmp_insensitive(tx1, tx2);
}
#line 80 "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_248);
}
#line 144 "inweb/Chapter 4/Programming Languages.w"
#line 156 "inweb/Chapter 4/Programming Languages.w"
programming_language *Languages__read_definition(filename *F) {
programming_language *pl = CREATE(programming_language);
{
#line 170 "inweb/Chapter 4/Programming Languages.w"
pl->language_name = NULL;
pl->file_extension = NULL;
pl->supports_namespaces = FALSE;
pl->line_comment = NULL;
pl->whole_line_comment = NULL;
pl->multiline_comment_open = NULL;
pl->multiline_comment_close = NULL;
pl->string_literal = NULL;
pl->string_literal_escape = NULL;
pl->character_literal = NULL;
pl->character_literal_escape = NULL;
pl->binary_literal_prefix = NULL;
pl->octal_literal_prefix = NULL;
pl->hexadecimal_literal_prefix = NULL;
pl->negative_literal_prefix = NULL;
pl->shebang = NULL;
pl->line_marker = NULL;
pl->before_macro_expansion = NULL;
pl->after_macro_expansion = NULL;
pl->start_definition = NULL;
pl->prolong_definition = NULL;
pl->end_definition = NULL;
pl->start_ifdef = NULL;
pl->end_ifdef = NULL;
pl->start_ifndef = NULL;
pl->end_ifndef = NULL;
pl->C_like = FALSE;
pl->suppress_disclaimer = FALSE;
pl->type_notation[0] = 0;
pl->function_notation[0] = 0;
pl->reserved_words = NEW_LINKED_LIST(reserved_word);
pl->built_in_keywords.analysis_hash_initialised = FALSE;
pl->program = NULL;
pl->methods = Methods__new_set();
}
#line 159 "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 215 "inweb/Chapter 4/Programming Languages.w"
if (pl->C_like) CLike__make_c_like(pl);
if (Str__eq(pl->language_name, TL_IS_249)) InCSupport__add_features(pl);
ACMESupport__add_fallbacks(pl);
}
#line 165 "inweb/Chapter 4/Programming Languages.w"
;
return pl;
}
#line 222 "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 323 "inweb/Chapter 4/Programming Languages.w"
if (Str__eq(line, TL_IS_281)) {
state->current_block = state->current_block->parent;
} else if (Regexp__match(&mr, line, L"characters {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block =
Languages__new_block(state->current_block, CHARACTERS_CRULE_RUN);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"characters in (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block =
Languages__new_block(state->current_block, CHARACTERS_IN_CRULE_RUN);
rule->execute_block->char_set = Languages__text(mr.exp[0], tfp, FALSE);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"runs of (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
int r = UNQUOTED_COLOUR;
if (Str__ne(mr.exp[0], TL_IS_282)) 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, FALSE);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"matches of (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block = Languages__new_block(state->current_block, MATCHES_CRULE_RUN);
Languages__regexp(rule->execute_block->match_regexp_text, mr.exp[0], tfp);
state->current_block = rule->execute_block;
} else if (Regexp__match(&mr, line, L"brackets in (%c+) {")) {
colouring_rule *rule = Languages__new_rule(state->current_block);
rule->execute_block = Languages__new_block(state->current_block, BRACKETS_CRULE_RUN);
Languages__regexp(rule->execute_block->match_regexp_text, mr.exp[0], tfp);
state->current_block = rule->execute_block;
} else {
int at = -1, quoted = FALSE;
for (int i=0; i<Str__len(line)-1; i++) {
if (Str__get_at(line, i) == '"') quoted = quoted?FALSE:TRUE;
if ((quoted) && (Str__get_at(line, i) == '\\')) i++;
if ((quoted == FALSE) &&
(Str__get_at(line, i) == '=') && (Str__get_at(line, i+1) == '>')) at = i;
}
if (at >= 0) {
TEMPORARY_TEXT(premiss);
TEMPORARY_TEXT(conclusion);
Str__substr(premiss, Str__start(line), Str__at(line, at));
Str__substr(conclusion, Str__at(line, at+2), Str__end(line));
Languages__parse_rule(state, premiss, conclusion, tfp);
DISCARD_TEXT(conclusion);
DISCARD_TEXT(premiss);
} else {
Errors__in_text_file("line in colouring block illegible", tfp);
}
}
}
#line 231 "inweb/Chapter 4/Programming Languages.w"
else
{
#line 240 "inweb/Chapter 4/Programming Languages.w"
if (Regexp__match(&mr, line, L"colouring {")) {
if (pl->program) Errors__in_text_file("duplicate colouring program", tfp);
pl->program = Languages__new_block(NULL, WHOLE_LINE_CRULE_RUN);
state->current_block = pl->program;
} else if (Regexp__match(&mr, line, L"keyword (%C+) of (%c+?)")) {
Languages__reserved(pl, Languages__text(mr.exp[0], tfp, FALSE), Languages__colour(mr.exp[1], tfp), tfp);
} else if (Regexp__match(&mr, line, L"keyword (%C+)")) {
Languages__reserved(pl, Languages__text(mr.exp[0], tfp, FALSE), RESERVED_COLOUR, tfp);
} else if (Regexp__match(&mr, line, L"(%c+) *: *(%c+?)")) {
text_stream *key = mr.exp[0], *value = Str__duplicate(mr.exp[1]);
if (Str__eq(key, TL_IS_250)) pl->language_name = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_251))
pl->language_details = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_252))
pl->file_extension = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_253))
pl->line_comment = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_254))
pl->whole_line_comment = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_255))
pl->multiline_comment_open = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_256))
pl->multiline_comment_close = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_257))
pl->string_literal = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_258))
pl->string_literal_escape = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_259))
pl->character_literal = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_260))
pl->character_literal_escape = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_261))
pl->binary_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_262))
pl->octal_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_263))
pl->hexadecimal_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_264))
pl->negative_literal_prefix = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_265))
pl->shebang = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_266))
pl->line_marker = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_267))
pl->before_macro_expansion = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_268))
pl->after_macro_expansion = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_269))
pl->start_definition = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_270))
pl->prolong_definition = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_271))
pl->end_definition = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_272))
pl->start_ifdef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_273))
pl->start_ifndef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_274))
pl->end_ifdef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_275))
pl->end_ifndef = Languages__text(value, tfp, TRUE);
else if (Str__eq(key, TL_IS_276))
pl->C_like = Languages__boolean(value, tfp);
else if (Str__eq(key, TL_IS_277))
pl->suppress_disclaimer = Languages__boolean(value, tfp);
else if (Str__eq(key, TL_IS_278))
pl->supports_namespaces = Languages__boolean(value, tfp);
else if (Str__eq(key, TL_IS_279))
Languages__regexp(pl->function_notation, value, tfp);
else if (Str__eq(key, TL_IS_280))
Languages__regexp(pl->type_notation, value, tfp);
else {
Errors__in_text_file("unknown property name before ':'", tfp);
}
} else {
Errors__in_text_file("line in language definition illegible", tfp);
}
}
#line 232 "inweb/Chapter 4/Programming Languages.w"
;
Regexp__dispose_of(&mr);
}
#line 402 "inweb/Chapter 4/Programming Languages.w"
#line 404 "inweb/Chapter 4/Programming Languages.w"
colouring_language_block *Languages__new_block(colouring_language_block *within, int r) {
colouring_language_block *block = CREATE(colouring_language_block);
block->rules = NEW_LINKED_LIST(colouring_rule);
block->parent = within;
block->run = r;
block->run_instance = NULL;
block->char_set = NULL;
block->match_regexp_text[0] = 0;
block->mr = Regexp__create_mr();
return block;
}
#line 456 "inweb/Chapter 4/Programming Languages.w"
#line 458 "inweb/Chapter 4/Programming Languages.w"
colouring_rule *Languages__new_rule(colouring_language_block *within) {
if (within == NULL) internal_error("rule outside block");
colouring_rule *rule = CREATE(colouring_rule);
ADD_TO_LINKED_LIST(rule, colouring_rule, within->rules);
rule->sense = TRUE;
rule->match_colour = NOT_A_COLOUR;
rule->match_text = NULL;
rule->match_prefix = NOT_A_RULE_PREFIX;
rule->match_keyword_of_colour = NOT_A_COLOUR;
rule->match_regexp_text[0] = 0;
rule->number = 0;
rule->number_of = 0;
rule->set_to_colour = NOT_A_COLOUR;
rule->set_prefix_to_colour = NOT_A_COLOUR;
rule->execute_block = NULL;
rule->debug = FALSE;
rule->fix_position = 0;
rule->mr = Regexp__create_mr();
return rule;
}
#line 482 "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 493 "inweb/Chapter 4/Programming Languages.w"
while (Regexp__match(&mr, premiss, L"not (%c+)")) {
rule->sense = (rule->sense)?FALSE:TRUE;
Str__clear(premiss); Str__copy(premiss, mr.exp[0]);
}
if (Regexp__match(&mr, premiss, L"number (%d+)")) {
rule->number = Str__atoi(mr.exp[0], 0);
} else if (Regexp__match(&mr, premiss, L"number (%d+) of (%d+)")) {
rule->number = Str__atoi(mr.exp[0], 0);
rule->number_of = Str__atoi(mr.exp[1], 0);
} else if (Regexp__match(&mr, premiss, L"keyword of (%c+)")) {
rule->match_keyword_of_colour = Languages__colour(mr.exp[0], tfp);
} else if (Regexp__match(&mr, premiss, L"keyword")) {
Errors__in_text_file("ambiguous: make it keyword of !reserved or \"keyword\"", tfp);
} else if (Regexp__match(&mr, premiss, L"prefix (%c+)")) {
rule->match_prefix = UNSPACED_RULE_PREFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"matching (%c+)")) {
Languages__regexp(rule->match_regexp_text, mr.exp[0], tfp);
} else if (Regexp__match(&mr, premiss, L"spaced prefix (%c+)")) {
rule->match_prefix = SPACED_RULE_PREFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"optionally spaced prefix (%c+)")) {
rule->match_prefix = OPTIONALLY_SPACED_RULE_PREFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"suffix (%c+)")) {
rule->match_prefix = UNSPACED_RULE_SUFFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"spaced suffix (%c+)")) {
rule->match_prefix = SPACED_RULE_SUFFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"optionally spaced suffix (%c+)")) {
rule->match_prefix = OPTIONALLY_SPACED_RULE_SUFFIX;
rule->match_text = Languages__text(mr.exp[0], tfp, FALSE);
} else if (Regexp__match(&mr, premiss, L"coloured (%c+)")) {
rule->match_colour = Languages__colour(mr.exp[0], tfp);
} else if (Str__len(premiss) > 0) {
rule->match_text = Languages__text(premiss, tfp, FALSE);
}
}
#line 487 "inweb/Chapter 4/Programming Languages.w"
;
{
#line 533 "inweb/Chapter 4/Programming Languages.w"
if (Str__eq(action, TL_IS_283)) {
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_284)) {
rule->debug = TRUE;
} else {
Errors__in_text_file("action after '=>' illegible", tfp);
}
}
#line 488 "inweb/Chapter 4/Programming Languages.w"
;
Regexp__dispose_of(&mr);
}
#line 561 "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 599 "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_285)) return STRING_COLOUR;
else if (Str__eq(T, TL_IS_286)) return FUNCTION_COLOUR;
else if (Str__eq(T, TL_IS_287)) return DEFINITION_COLOUR;
else if (Str__eq(T, TL_IS_288)) return RESERVED_COLOUR;
else if (Str__eq(T, TL_IS_289)) return ELEMENT_COLOUR;
else if (Str__eq(T, TL_IS_290)) return IDENTIFIER_COLOUR;
else if (Str__eq(T, TL_IS_291)) return CHAR_LITERAL_COLOUR;
else if (Str__eq(T, TL_IS_292)) return CONSTANT_COLOUR;
else if (Str__eq(T, TL_IS_293)) return PLAIN_COLOUR;
else if (Str__eq(T, TL_IS_294)) return EXTRACT_COLOUR;
else if (Str__eq(T, TL_IS_295)) return COMMENT_COLOUR;
else {
Errors__in_text_file("no such !colour", tfp);
return PLAIN_COLOUR;
}
}
#line 624 "inweb/Chapter 4/Programming Languages.w"
int Languages__boolean(text_stream *T, text_file_position *tfp) {
if (Str__eq(T, TL_IS_296)) return TRUE;
else if (Str__eq(T, TL_IS_297)) return FALSE;
else {
Errors__in_text_file("must be true or false", tfp);
return FALSE;
}
}
#line 638 "inweb/Chapter 4/Programming Languages.w"
text_stream *Languages__text(text_stream *T, text_file_position *tfp, int allow) {
text_stream *V = Str__new();
if (Str__len(T) > 0) {
int bareword = TRUE, spaced = FALSE, from = 0, to = Str__len(T)-1;
if ((to > from) &&
(Str__get_at(T, from) == '"') && (Str__get_at(T, to) == '"')) {
bareword = FALSE; from++; to--;
}
for (int i=from; i<=to; i++) {
wchar_t c = Str__get_at(T, i);
if (c == ' ') spaced = TRUE;
if ((c == '\\') && (Str__get_at(T, i+1) == 'n')) {
PUT_TO(V, '\n');
i++;
} else if ((c == '\\') && (Str__get_at(T, i+1) == 's')) {
PUT_TO(V, ' ');
i++;
} else if ((c == '\\') && (Str__get_at(T, i+1) == 't')) {
PUT_TO(V, '\t');
i++;
} else if ((c == '\\') && (Str__get_at(T, i+1) == '\\')) {
PUT_TO(V, '\\');
i++;
} else if ((bareword == FALSE) && (c == '\\') && (Str__get_at(T, i+1) == '"')) {
PUT_TO(V, '"');
i++;
} else if ((bareword == FALSE) && (c == '"')) {
Errors__in_text_file(
"backslash needed before internal double-quotation mark", tfp);
} else if ((bareword) && (c == '!') && (i == from)) {
Errors__in_text_file(
"a literal starting with ! must be in double-quotation marks", tfp);
} else if ((bareword) && (c == '/')) {
Errors__in_text_file(
"forward slashes can only be used in quoted strings", tfp);
} else if ((bareword) && (c == '"')) {
Errors__in_text_file(
"double-quotation marks can only be used in quoted strings", tfp);
} else {
PUT_TO(V, c);
}
}
if ((bareword) && (spaced) && (allow == FALSE)) {
TEMPORARY_TEXT(err);
WRITE_TO(err, "'%S' seems to be literal text, but if so it needs double-quotation marks", T);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err);
}
if (bareword) {
int rw = FALSE;
if (Str__eq(V, TL_IS_298)) rw = TRUE;
if (Str__eq(V, TL_IS_299)) rw = TRUE;
if (Str__eq(V, TL_IS_300)) rw = TRUE;
if (Str__eq(V, TL_IS_301)) rw = TRUE;
if (Str__eq(V, TL_IS_302)) rw = TRUE;
if (Str__eq(V, TL_IS_303)) rw = TRUE;
if (Str__eq(V, TL_IS_304)) rw = TRUE;
if (Str__eq(V, TL_IS_305)) rw = TRUE;
if (Str__eq(V, TL_IS_306)) rw = TRUE;
if (Str__eq(V, TL_IS_307)) rw = TRUE;
if (Str__eq(V, TL_IS_308)) rw = TRUE;
if (Str__eq(V, TL_IS_309)) rw = TRUE;
if (Str__eq(V, TL_IS_310)) rw = TRUE;
if (Str__eq(V, TL_IS_311)) rw = TRUE;
if (Str__eq(V, TL_IS_312)) rw = TRUE;
if (Str__eq(V, TL_IS_313)) rw = TRUE;
if (Str__eq(V, TL_IS_314)) rw = TRUE;
if (Str__eq(V, TL_IS_315)) rw = TRUE;
if (Str__eq(V, TL_IS_316)) rw = TRUE;
if (Str__eq(V, TL_IS_317)) rw = TRUE;
if (Str__eq(V, TL_IS_318)) rw = TRUE;
if (Str__eq(V, TL_IS_319)) rw = TRUE;
if (rw) {
TEMPORARY_TEXT(err);
WRITE_TO(err, "'%S' is a reserved word, so you should put it in double-quotation marks", V);
Errors__in_text_file_S(err, tfp);
DISCARD_TEXT(err);
}
}
}
return V;
}
#line 725 "inweb/Chapter 4/Programming Languages.w"
void Languages__regexp(wchar_t *write_to, text_stream *T, text_file_position *tfp) {
if (write_to == NULL) internal_error("no buffer");
write_to[0] = 0;
if (Str__len(T) > 0) {
int from = 0, to = Str__len(T)-1, x = 0;
if ((to > from) &&
(Str__get_at(T, from) == '/') && (Str__get_at(T, to) == '/')) {
from++; to--;
for (int i=from; i<=to; i++) {
wchar_t c = Str__get_at(T, i);
if (c == '\\') {
wchar_t w = Str__get_at(T, i+1);
if (w == '\\') {
x = Languages__add_to_regexp(write_to, x, w);
} else if (w == 'd') {
x = Languages__add_escape_to_regexp(write_to, x, 'd');
} else if (w == 't') {
x = Languages__add_escape_to_regexp(write_to, x, 't');
} else if (w == 's') {
x = Languages__add_to_regexp(write_to, x, ' ');
} else if (w == 'S') {
x = Languages__add_escape_to_regexp(write_to, x, 'C');
} else if (w == '"') {
x = Languages__add_escape_to_regexp(write_to, x, 'q');
} else {
x = Languages__add_escape_to_regexp(write_to, x, w);
}
i++;
continue;
}
if (c == '.') {
x = Languages__add_escape_to_regexp(write_to, x, 'c');
continue;
}
if (c == '%') {
x = Languages__add_escape_to_regexp(write_to, x, '%');
continue;
}
x = Languages__add_to_regexp(write_to, x, c);
}
} else {
Errors__in_text_file(
"the expression to match must be in slashes '/'", tfp);
}
if (x >= MAX_ILDF_REGEXP_LENGTH)
Errors__in_text_file(
"the expression to match is too long", tfp);
}
}
int Languages__add_to_regexp(wchar_t *write_to, int i, wchar_t c) {
if (i < MAX_ILDF_REGEXP_LENGTH) write_to[i++] = c;
return i;
}
int Languages__add_escape_to_regexp(wchar_t *write_to, int i, wchar_t c) {
i = Languages__add_to_regexp(write_to, i, '%');
i = Languages__add_to_regexp(write_to, i, c);
return i;
}
#line 18 "inweb/Chapter 4/Types and Functions.w"
#line 20 "inweb/Chapter 4/Types and Functions.w"
language_type *first_cst_alphabetically = NULL;
language_type *Functions__new_struct(web *W, text_stream *name, source_line *L) {
language_type *str = CREATE(language_type);
{
#line 32 "inweb/Chapter 4/Types and Functions.w"
str->structure_name = Str__duplicate(name);
str->structure_header_at = L;
str->tangled = FALSE;
str->typedef_ends = NULL;
str->incorporates = NEW_LINKED_LIST(language_type);
str->elements = NEW_LINKED_LIST(structure_element);
}
#line 24 "inweb/Chapter 4/Types and Functions.w"
;
Analyser__mark_reserved_word_at_line(L, str->structure_name, RESERVED_COLOUR);
{
#line 40 "inweb/Chapter 4/Types and Functions.w"
Tags__add_by_name(L->owning_paragraph, TL_IS_320);
ADD_TO_LINKED_LIST(str, language_type, W->language_types);
ADD_TO_LINKED_LIST(str, language_type, L->owning_paragraph->structures);
}
#line 26 "inweb/Chapter 4/Types and Functions.w"
;
{
#line 45 "inweb/Chapter 4/Types and Functions.w"
str->next_cst_alphabetically = NULL;
if (first_cst_alphabetically == NULL) first_cst_alphabetically = str;
else {
int placed = FALSE;
language_type *last = NULL;
for (language_type *seq = first_cst_alphabetically; seq;
seq = seq->next_cst_alphabetically) {
if (Str__cmp(str->structure_name, seq->structure_name) < 0) {
if (seq == first_cst_alphabetically) {
str->next_cst_alphabetically = first_cst_alphabetically;
first_cst_alphabetically = str;
} else {
last->next_cst_alphabetically = str;
str->next_cst_alphabetically = seq;
}
placed = TRUE;
break;
}
last = seq;
}
if (placed == FALSE) last->next_cst_alphabetically = str;
}
}
#line 27 "inweb/Chapter 4/Types and Functions.w"
;
return str;
}
#line 84 "inweb/Chapter 4/Types and Functions.w"
#line 86 "inweb/Chapter 4/Types and Functions.w"
structure_element *Functions__new_element(language_type *str, text_stream *elname,
source_line *L) {
Analyser__mark_reserved_word_at_line(L, elname, ELEMENT_COLOUR);
structure_element *elt = CREATE(structure_element);
elt->element_name = Str__duplicate(elname);
elt->allow_sharing = FALSE;
elt->element_created_at = L;
if (LanguageMethods__share_element(L->owning_section->sect_language, elname))
elt->allow_sharing = TRUE;
ADD_TO_LINKED_LIST(elt, structure_element, str->elements);
return elt;
}
#line 100 "inweb/Chapter 4/Types and Functions.w"
language_type *Functions__find_structure(web *W, text_stream *name) {
language_type *str;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
if (Str__eq(name, str->structure_name))
return str;
return NULL;
}
#line 125 "inweb/Chapter 4/Types and Functions.w"
#line 127 "inweb/Chapter 4/Types and Functions.w"
language_function *Functions__new_function(text_stream *fname, source_line *L) {
hash_table_entry *hte =
Analyser__mark_reserved_word_at_line(L, fname, FUNCTION_COLOUR);
language_function *fn = CREATE(language_function);
hte->as_function = fn;
{
#line 143 "inweb/Chapter 4/Types and Functions.w"
fn->function_name = Str__duplicate(fname);
fn->function_arguments = Str__new();
fn->function_type = Str__new();
fn->within_namespace = FALSE;
fn->called_from_other_sections = FALSE;
fn->call_freely = FALSE;
fn->function_header_at = L;
fn->usage_described = FALSE;
if ((Str__eq_wide_string(fname, L"main")) &&
(L->owning_section->sect_language->C_like))
fn->usage_described = TRUE;
fn->no_conditionals = 0;
}
#line 132 "inweb/Chapter 4/Types and Functions.w"
;
{
#line 157 "inweb/Chapter 4/Types and Functions.w"
paragraph *P = L->owning_paragraph;
if (P) ADD_TO_LINKED_LIST(fn, language_function, P->functions);
L->function_defined = fn;
}
#line 133 "inweb/Chapter 4/Types and Functions.w"
;
if (L->owning_section->sect_language->supports_namespaces)
{
#line 162 "inweb/Chapter 4/Types and Functions.w"
text_stream *declared_namespace = NULL;
text_stream *ambient_namespace = L->owning_section->sect_namespace;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, fname, L"(%c+::)%c*")) {
declared_namespace = mr.exp[0];
fn->within_namespace = TRUE;
} else if ((Str__eq_wide_string(fname, L"main")) &&
(Str__eq_wide_string(ambient_namespace, L"Main::")))
declared_namespace = TL_IS_321;
if ((Str__ne(declared_namespace, ambient_namespace)) &&
(L->owning_paragraph->placed_very_early == FALSE)) {
TEMPORARY_TEXT(err_mess);
if (Str__len(declared_namespace) == 0)
WRITE_TO(err_mess, "Function '%S' should have namespace prefix '%S'",
fname, ambient_namespace);
else if (Str__len(ambient_namespace) == 0)
WRITE_TO(err_mess, "Function '%S' declared in a section with no namespace",
fname);
else
WRITE_TO(err_mess, "Function '%S' declared in a section with the wrong namespace '%S'",
fname, ambient_namespace);
Main__error_in_web(err_mess, L);
DISCARD_TEXT(err_mess);
}
Regexp__dispose_of(&mr);
}
#line 135 "inweb/Chapter 4/Types and Functions.w"
;
return fn;
}
#line 193 "inweb/Chapter 4/Types and Functions.w"
void Functions__catalogue(section *S, int functions_too) {
language_type *str;
LOOP_OVER(str, language_type)
if (str->structure_header_at->owning_section == S)
PRINT(" %S ", str->structure_name);
if (functions_too) {
language_function *fn;
LOOP_OVER(fn, language_function)
if (fn->function_header_at->owning_section == S)
PRINT("\n %S", fn->function_name);
}
}
#line 36 "inweb/Chapter 4/Language Methods.w"
VMETHOD_TYPE(PARSE_TYPES_PAR_MTID, programming_language *pl, web *W)
void LanguageMethods__parse_types(web *W, programming_language *pl) {
VMETHOD_CALL(pl, PARSE_TYPES_PAR_MTID, W);
}
#line 44 "inweb/Chapter 4/Language Methods.w"
#line 46 "inweb/Chapter 4/Language Methods.w"
VMETHOD_TYPE(PARSE_FUNCTIONS_PAR_MTID, programming_language *pl, web *W)
void LanguageMethods__parse_functions(web *W, programming_language *pl) {
VMETHOD_CALL(pl, PARSE_FUNCTIONS_PAR_MTID, W);
}
#line 56 "inweb/Chapter 4/Language Methods.w"
#line 58 "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 69 "inweb/Chapter 4/Language Methods.w"
#line 71 "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 82 "inweb/Chapter 4/Language Methods.w"
#line 84 "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 102 "inweb/Chapter 4/Language Methods.w"
#line 104 "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 113 "inweb/Chapter 4/Language Methods.w"
#line 115 "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_322);
}
#line 127 "inweb/Chapter 4/Language Methods.w"
#line 129 "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 143 "inweb/Chapter 4/Language Methods.w"
#line 145 "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_323, 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_324, 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 175 "inweb/Chapter 4/Language Methods.w"
#line 177 "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 188 "inweb/Chapter 4/Language Methods.w"
#line 190 "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 202 "inweb/Chapter 4/Language Methods.w"
#line 204 "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 219 "inweb/Chapter 4/Language Methods.w"
#line 221 "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 238 "inweb/Chapter 4/Language Methods.w"
#line 240 "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 251 "inweb/Chapter 4/Language Methods.w"
#line 253 "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 268 "inweb/Chapter 4/Language Methods.w"
#line 270 "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 282 "inweb/Chapter 4/Language Methods.w"
#line 284 "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 294 "inweb/Chapter 4/Language Methods.w"
#line 296 "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 306 "inweb/Chapter 4/Language Methods.w"
#line 308 "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 318 "inweb/Chapter 4/Language Methods.w"
#line 320 "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 330 "inweb/Chapter 4/Language Methods.w"
#line 332 "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 340 "inweb/Chapter 4/Language Methods.w"
#line 342 "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 355 "inweb/Chapter 4/Language Methods.w"
#line 357 "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 365 "inweb/Chapter 4/Language Methods.w"
#line 367 "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, source_line *L, text_stream *matter, text_stream *colouring)
int LanguageMethods__syntax_colour(OUTPUT_STREAM, programming_language *pl,
weave_target *wv, source_line *L, text_stream *matter, text_stream *colouring) {
for (int i=0; i < Str__len(matter); i++) Str__put_at(colouring, i, PLAIN_COLOUR);
int rv = FALSE;
programming_language *colour_as = pl;
if (L->category == TEXT_EXTRACT_LCAT) colour_as = L->colour_as;
if (colour_as)
IMETHOD_CALL(rv, colour_as, SYNTAX_COLOUR_WEA_MTID, OUT, wv, L,
matter, colouring);
return rv;
}
#line 388 "inweb/Chapter 4/Language Methods.w"
#line 390 "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 402 "inweb/Chapter 4/Language Methods.w"
#line 404 "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 424 "inweb/Chapter 4/Language Methods.w"
#line 426 "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 439 "inweb/Chapter 4/Language Methods.w"
#line 441 "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 451 "inweb/Chapter 4/Language Methods.w"
int LanguageMethods__supports_definitions(programming_language *pl) {
if (Str__len(pl->start_definition) > 0) return TRUE;
if (Str__len(pl->prolong_definition) > 0) return TRUE;
if (Str__len(pl->end_definition) > 0) return TRUE;
return FALSE;
}
#line 16 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__add_fallbacks(programming_language *pl) {
if (Methods__provided(pl->methods, PARSE_TYPES_PAR_MTID) == FALSE)
METHOD_ADD(pl, PARSE_TYPES_PAR_MTID, ACMESupport__parse_types);
if (Methods__provided(pl->methods, PARSE_FUNCTIONS_PAR_MTID) == FALSE)
METHOD_ADD(pl, PARSE_FUNCTIONS_PAR_MTID, ACMESupport__parse_functions);
if (Methods__provided(pl->methods, 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 58 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__expand(OUTPUT_STREAM, text_stream *prototype, text_stream *S,
int N, filename *F) {
if (Str__len(prototype) > 0) {
for (int i=0; i<Str__len(prototype); i++) {
wchar_t c = Str__get_at(prototype, i);
if ((c == '%') && (Str__get_at(prototype, i+1) == 'S') && (S)) {
WRITE("%S", S);
i++;
} else if ((c == '%') && (Str__get_at(prototype, i+1) == 'd') && (N >= 0)) {
WRITE("%d", N);
i++;
} else if ((c == '%') && (Str__get_at(prototype, i+1) == 'f') && (F)) {
WRITE("%/f", F);
i++;
} else {
PUT(c);
}
}
}
}
#line 82 "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 = 0, non_white_space = FALSE, c_position = -1, c_end = -1;
for (int i=0; i<Str__len(line); i++) {
wchar_t c = Str__get_at(line, i);
if (c_mode == 2) {
if (Str__includes_at(line, i, pl->multiline_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 (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 (Str__includes_at(line, i, pl->multiline_comment_open)) {
c_mode = 2; c_position = i; non_white_space = FALSE;
i += Str__len(pl->multiline_comment_open) - 1;
}
if (c_mode == 0) {
if (Str__includes_at(line, i, pl->line_comment)) {
c_mode = 1; c_position = i; c_end = Str__len(line); non_white_space = FALSE;
i += Str__len(pl->line_comment) - 1;
}
if (Str__includes_at(line, i, pl->whole_line_comment)) {
int material_exists = FALSE;
for (int j=0; j<i; j++)
if (!(Characters__is_whitespace(Str__get_at(line, j))))
material_exists = TRUE;
if (material_exists == FALSE) {
c_mode = 1; c_position = i; c_end = Str__len(line);
non_white_space = FALSE;
i += Str__len(pl->whole_line_comment) - 1;
}
}
}
}
}
}
if ((c_position >= 0) && (non_white_space == FALSE)) {
Str__clear(part_before_comment);
for (int i=0; i<c_position; i++)
PUT_TO(part_before_comment, Str__get_at(line, i));
Str__clear(part_within_comment);
for (int i=c_position + 2; i<c_end; i++)
PUT_TO(part_within_comment, Str__get_at(line, i));
Str__trim_white_space_at_end(part_within_comment);
return TRUE;
}
return FALSE;
}
#line 219 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_types(programming_language *self, web *W) {
if (W->main_language->type_notation[0]) {
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
if (S->sect_language == W->main_language) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, W->main_language->type_notation)) {
Functions__new_function(mr.exp[0], L);
}
Regexp__dispose_of(&mr);
}
}
}
}
#line 238 "inweb/Chapter 4/ACME Support.w"
void ACMESupport__parse_functions(programming_language *self, web *W) {
if (W->main_language->function_notation[0]) {
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
if (S->sect_language == W->main_language) {
match_results mr = Regexp__create_mr();
if ((L->category != TEXT_EXTRACT_LCAT) &&
(Regexp__match(&mr, L->text, W->main_language->function_notation))) {
Functions__new_function(mr.exp[0], L);
}
Regexp__dispose_of(&mr);
}
}
}
}
#line 259 "inweb/Chapter 4/ACME Support.w"
int ACMESupport__suppress_disclaimer(programming_language *pl) {
return pl->suppress_disclaimer;
}
#line 266 "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 275 "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, source_line *L, text_stream *matter, text_stream *colouring) {
section *S = L->owning_section;
hash_table *ht = &(S->sect_target->symbols);
if ((L->category == TEXT_EXTRACT_LCAT) && (pl != S->sect_language))
ht = &(pl->built_in_keywords);
return Painter__syntax_colour(pl, ht, matter, colouring, FALSE);
}
#line 16 "inweb/Chapter 4/The Painter.w"
int painter_count = 1;
void Painter__reset_syntax_colouring(programming_language *pl) {
colouring_state = PLAIN_COLOUR;
painter_count = 1;
}
#line 38 "inweb/Chapter 4/The Painter.w"
int Painter__syntax_colour(programming_language *pl,
hash_table *HT, text_stream *matter, text_stream *colouring, int with_comments) {
int from = 0, to = Str__len(matter) - 1;
if (with_comments) {
TEMPORARY_TEXT(part_before_comment);
TEMPORARY_TEXT(part_within_comment);
if (LanguageMethods__parse_comment(pl,
matter, part_before_comment, part_within_comment)) {
int N = Str__len(matter);
for (int i=Str__len(part_before_comment); i<N; i++)
Str__put_at(colouring, i, COMMENT_COLOUR);
from = 0; to = Str__len(part_before_comment);
}
DISCARD_TEXT(part_before_comment);
DISCARD_TEXT(part_within_comment);
}
Painter__syntax_colour_inner(pl, HT, matter, colouring, from, to);
return FALSE;
}
void Painter__syntax_colour_inner(programming_language *pl,
hash_table *HT, text_stream *matter, text_stream *colouring, int from, int to) {
{
#line 66 "inweb/Chapter 4/The Painter.w"
int squote = Str__get_first_char(pl->character_literal);
int squote_escape = Str__get_first_char(pl->character_literal_escape);
int dquote = Str__get_first_char(pl->string_literal);
int dquote_escape = Str__get_first_char(pl->string_literal_escape);
for (int i=from; i <= to; i++) {
int skip = NOT_A_COLOUR, 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 = CHAR_LITERAL_COLOUR;
break;
}
case STRING_COLOUR: {
wchar_t c = Str__get_at(matter, i);
if (c == dquote) will_be = PLAIN_COLOUR;
if (c == dquote_escape) skip = STRING_COLOUR;
break;
}
}
if (one_off >= 0) Str__put_at(colouring, i, (char) one_off);
else Str__put_at(colouring, i, (char) colouring_state);
if (will_be >= 0) colouring_state = (char) will_be;
if ((skip != NOT_A_COLOUR) && (i<to)) {
i++; Str__put_at(colouring, i, skip);
}
}
}
#line 60 "inweb/Chapter 4/The Painter.w"
;
{
#line 109 "inweb/Chapter 4/The Painter.w"
int base = -1, dec_possible = TRUE;
for (int i=from; i <= to; i++) {
if ((Str__get_at(colouring, i) == PLAIN_COLOUR) ||
(Str__get_at(colouring, i) == IDENTIFIER_COLOUR)) {
wchar_t c = Str__get_at(matter, i);
if (Str__includes_at(matter, i, pl->binary_literal_prefix)) {
base = 2;
for (int j=0; j<Str__len(pl->binary_literal_prefix); j++)
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
dec_possible = TRUE;
continue;
} else if (Str__includes_at(matter, i, pl->octal_literal_prefix)) {
base = 8;
for (int j=0; j<Str__len(pl->octal_literal_prefix); j++)
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
dec_possible = TRUE;
continue;
} else if (Str__includes_at(matter, i, pl->hexadecimal_literal_prefix)) {
base = 16;
for (int j=0; j<Str__len(pl->hexadecimal_literal_prefix); j++)
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
dec_possible = TRUE;
continue;
}
if ((Str__includes_at(matter, i, pl->negative_literal_prefix)) &&
(dec_possible) && (base == 0)) {
base = 10;
Str__put_at(colouring, i, (char) CONSTANT_COLOUR);
continue;
}
int pass = FALSE;
switch (base) {
case -1:
if ((dec_possible) && (Characters__isdigit(c))) {
base = 10; pass = TRUE;
}
break;
case 2: if ((c == '0') || (c == '1')) pass = TRUE; break;
case 10: if (Characters__isdigit(c)) pass = TRUE; break;
case 16: if (Characters__isdigit(c)) pass = TRUE;
int d = Characters__tolower(c);
if ((d == 'a') || (d == 'b') || (d == 'c') ||
(d == 'd') || (d == 'e') || (d == 'f')) pass = TRUE;
break;
}
if (pass) {
Str__put_at(colouring, i, (char) CONSTANT_COLOUR);
} else {
if (Characters__is_whitespace(c)) dec_possible = TRUE;
else dec_possible = FALSE;
base = -1;
}
}
}
}
#line 61 "inweb/Chapter 4/The Painter.w"
;
{
#line 194 "inweb/Chapter 4/The Painter.w"
if (pl->program)
Painter__execute(HT, pl->program, matter, colouring, from, to, painter_count++);
}
#line 62 "inweb/Chapter 4/The Painter.w"
;
}
#line 170 "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 203 "inweb/Chapter 4/The Painter.w"
void Painter__execute(hash_table *HT, colouring_language_block *block, text_stream *matter,
text_stream *colouring, int from, int to, int N) {
if (block == NULL) internal_error("no block");
TEMPORARY_TEXT(colouring_at_start);
Str__copy(colouring_at_start, colouring);
colouring_rule *rule;
LOOP_OVER_LINKED_LIST(rule, colouring_rule, block->rules) {
switch (block->run) {
case WHOLE_LINE_CRULE_RUN:
Painter__execute_rule(HT, rule, matter, colouring, from, to,
(N == 0)?1:N);
break;
case CHARACTERS_CRULE_RUN:
for (int i=from; i<=to; i++)
Painter__execute_rule(HT, rule, matter, colouring, i, i, i-from+1);
break;
case CHARACTERS_IN_CRULE_RUN:
for (int count=1, i=from; i<=to; i++)
for (int j=0; j<Str__len(block->char_set); j++)
if (Str__get_at(matter, i) == Str__get_at(block->char_set, j) ) {
Painter__execute_rule(HT, rule, matter, colouring, i, i, count++);
break;
}
break;
case INSTANCES_CRULE_RUN: {
int L = Str__len(block->run_instance) - 1;
if (L >= 0)
for (int count=1, i=from; i<=to - L; i++)
if (Str__includes_at(matter, i, block->run_instance)) {
Painter__execute_rule(HT, rule, matter, colouring, i, i+L, count++);
i += L;
}
break;
}
case MATCHES_CRULE_RUN:
for (int count=1, i=from; i<=to; i++) {
int L = Regexp__match_from(&(block->mr), matter, block->match_regexp_text, i, TRUE);
if (L > 0) {
Painter__execute_rule(HT, rule, matter, colouring, i, i+L-1, count++);
i += L-1;
}
}
break;
case BRACKETS_CRULE_RUN:
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
if (block->mr.exp[i])
Str__clear(block->mr.exp[i]);
if (Regexp__match(&(block->mr), matter, block->match_regexp_text))
for (int count=1, i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
if (block->mr.exp_at[i] >= 0)
Painter__execute_rule(HT, rule, matter, colouring,
block->mr.exp_at[i],
block->mr.exp_at[i] + Str__len(block->mr.exp[i])-1,
count++);
break;
default: {
int ident_from = -1, count = 1;
for (int i=from; i<=to; i++) {
int col = Str__get_at(colouring_at_start, i);
if ((col == block->run) ||
((block->run == UNQUOTED_COLOUR) &&
((col != STRING_COLOUR) && (col != 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, count++);
ident_from = -1;
}
}
if (ident_from >= 0)
Painter__execute_rule(HT, rule, matter, colouring, ident_from, to, count++);
break;
}
}
}
DISCARD_TEXT(colouring_at_start);
}
#line 284 "inweb/Chapter 4/The Painter.w"
void Painter__execute_rule(hash_table *HT, colouring_rule *rule, text_stream *matter,
text_stream *colouring, int from, int to, int N) {
if (Painter__satisfies(HT, rule, matter, colouring, from, to, N) == rule->sense)
Painter__follow(HT, rule, matter, colouring, from, to);
}
#line 300 "inweb/Chapter 4/The Painter.w"
int Painter__satisfies(hash_table *HT, colouring_rule *rule, text_stream *matter,
text_stream *colouring, int from, int to, int N) {
if (rule->number > 0) {
if (rule->number_of > 0) {
if (rule->number != ((N-1)%(rule->number_of)) + 1) return FALSE;
} else {
if (rule->number != N) return FALSE;
}
} else if (rule->match_regexp_text[0]) {
TEMPORARY_TEXT(T);
for (int j=from; j<=to; j++) PUT_TO(T, Str__get_at(matter, j));
int rv = Regexp__match(&(rule->mr), T, rule->match_regexp_text);
DISCARD_TEXT(T);
if (rv == FALSE) return FALSE;
} else if (Str__len(rule->match_text) > 0) {
if ((rule->match_prefix == UNSPACED_RULE_PREFIX) ||
(rule->match_prefix == SPACED_RULE_PREFIX) ||
(rule->match_prefix == OPTIONALLY_SPACED_RULE_PREFIX)) {
int pos = from;
if (rule->match_prefix != UNSPACED_RULE_PREFIX) {
while ((pos > 0) && (Characters__is_whitespace(pos-1))) pos--;
if ((rule->match_prefix == SPACED_RULE_PREFIX) && (pos == from))
return FALSE;
}
if (Str__includes_at(matter,
pos-Str__len(rule->match_text), rule->match_text) == FALSE)
return FALSE;
rule->fix_position = pos-Str__len(rule->match_text);
} else if ((rule->match_prefix == UNSPACED_RULE_SUFFIX) ||
(rule->match_prefix == SPACED_RULE_SUFFIX) ||
(rule->match_prefix == OPTIONALLY_SPACED_RULE_SUFFIX)) {
int pos = to + 1;
if (rule->match_prefix != UNSPACED_RULE_SUFFIX) {
while ((pos < Str__len(rule->match_text)) && (Characters__is_whitespace(pos))) pos++;
if ((rule->match_prefix == SPACED_RULE_SUFFIX) && (pos == from))
return FALSE;
}
if (Str__includes_at(matter, pos, rule->match_text) == FALSE)
return FALSE;
rule->fix_position = pos;
} else {
if (Str__len(rule->match_text) != to-from+1)
return FALSE;
for (int i=from; i<=to; i++)
if (Str__get_at(matter, i) != Str__get_at(rule->match_text, i-from))
return FALSE;
}
} else if (rule->match_keyword_of_colour != NOT_A_COLOUR) {
TEMPORARY_TEXT(id);
Str__substr(id, Str__at(matter, from), Str__at(matter, to+1));
int rw = Analyser__is_reserved_word(HT, id, 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 364 "inweb/Chapter 4/The Painter.w"
void Painter__follow(hash_table *HT, colouring_rule *rule, text_stream *matter,
text_stream *colouring, int from, int to) {
if (rule->execute_block)
Painter__execute(HT, rule->execute_block, matter, colouring, from, to, 0);
else if (rule->debug)
{
#line 380 "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 368 "inweb/Chapter 4/The Painter.w"
else {
if (rule->set_to_colour != NOT_A_COLOUR)
for (int i=from; i<=to; i++)
Str__put_at(colouring, i, rule->set_to_colour);
if (rule->set_prefix_to_colour != NOT_A_COLOUR)
for (int i=rule->fix_position; i<rule->fix_position+Str__len(rule->match_text); i++)
Str__put_at(colouring, i, rule->set_prefix_to_colour);
}
}
#line 391 "inweb/Chapter 4/The Painter.w"
linked_list *Painter__lines(filename *F) {
linked_list *L = NEW_LINKED_LIST(text_stream);
TextFiles__read(F, FALSE, "unable to read file of textual extract", TRUE,
&Painter__text_file_helper, NULL, L);
int n = -1, c = 0;
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, L) {
c++;
if (Str__is_whitespace(T) == FALSE)
n = c;
}
if (n >= 0) {
linked_list *R = NEW_LINKED_LIST(text_stream);
c = 0;
LOOP_OVER_LINKED_LIST(T, text_stream, L)
if (++c <= n)
ADD_TO_LINKED_LIST(T, text_stream, R);
return R;
}
return L;
}
void Painter__text_file_helper(text_stream *text, text_file_position *tfp, void *state) {
linked_list *L = (linked_list *) state;
ADD_TO_LINKED_LIST(Str__duplicate(text), text_stream, L);
}
void Painter__colour_file(programming_language *pl, filename *F, text_stream *to, text_stream *coloured) {
linked_list *L = Painter__lines(F);
if (pl) Painter__reset_syntax_colouring(pl);
int c = 1;
text_stream *T;
LOOP_OVER_LINKED_LIST(T, text_stream, L) {
if (c++ > 1) { PUT_TO(to, '\n'); PUT_TO(coloured, NEWLINE_COLOUR); }
Str__trim_white_space_at_end(T);
TEMPORARY_TEXT(ST);
TEMPORARY_TEXT(SC);
LOOP_THROUGH_TEXT(pos, T)
if (Str__get(pos) == '\t')
WRITE_TO(ST, " ");
else
PUT_TO(ST, Str__get(pos));
if (pl) {
Painter__syntax_colour(pl, (pl)?(&(pl->built_in_keywords)):NULL, ST, SC, TRUE);
} else {
LOOP_THROUGH_TEXT(pos, ST)
PUT_TO(SC, PLAIN_COLOUR);
}
WRITE_TO(to, "%S", ST);
WRITE_TO(coloured, "%S", SC);
}
if (c > 0) { PUT_TO(to, '\n'); PUT_TO(coloured, NEWLINE_COLOUR); }
}
#line 9 "inweb/Chapter 4/C-Like Languages.w"
void CLike__make_c_like(programming_language *pl) {
METHOD_ADD(pl, PARSE_TYPES_PAR_MTID, CLike__parse_types);
METHOD_ADD(pl, PARSE_FUNCTIONS_PAR_MTID, CLike__parse_functions);
METHOD_ADD(pl, SUBCATEGORISE_LINE_PAR_MTID, CLike__subcategorise_code);
METHOD_ADD(pl, ADDITIONAL_EARLY_MATTER_TAN_MTID, CLike__additional_early_matter);
METHOD_ADD(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, CLike__additional_predeclarations);
METHOD_ADD(pl, EARLY_PREWEAVE_ANALYSIS_ANA_MTID, CLike__analyse_code);
METHOD_ADD(pl, LATE_PREWEAVE_ANALYSIS_ANA_MTID, CLike__post_analysis);
}
#line 27 "inweb/Chapter 4/C-Like Languages.w"
void CLike__parse_types(programming_language *self, web *W) {
{
#line 53 "inweb/Chapter 4/C-Like Languages.w"
language_type *current_str = NULL;
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L"typedef struct (%i+) %c*{%c*")) {
current_str = Functions__new_struct(W, mr.exp[0], L);
Tags__add_by_name(L->owning_paragraph, TL_IS_325);
} 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 83 "inweb/Chapter 4/C-Like Languages.w"
TEMPORARY_TEXT(p);
Str__copy(p, L->text);
Str__trim_white_space(p);
{
#line 105 "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 86 "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 123 "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 89 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 129 "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 90 "inweb/Chapter 4/C-Like Languages.w"
;
if (Str__in_range(pos)) {
match_results mr = Regexp__create_mr();
TEMPORARY_TEXT(elname);
{
#line 136 "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 94 "inweb/Chapter 4/C-Like Languages.w"
;
Functions__new_element(current_str, elname, L);
DISCARD_TEXT(elname);
Regexp__dispose_of(&mr);
}
}
DISCARD_TEXT(p);
}
#line 66 "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 28 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 153 "inweb/Chapter 4/C-Like Languages.w"
language_type *current_str;
LOOP_OVER(current_str, language_type) {
for (source_line *L = current_str->structure_header_at;
((L) && (L != current_str->typedef_ends));
L = L->next_line) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, L->text, L" struct (%i+) %i%c*"))
{
#line 166 "inweb/Chapter 4/C-Like Languages.w"
text_stream *used_structure = mr.exp[0];
language_type *str;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
if ((str != current_str) &&
(Str__eq(used_structure, str->structure_name)))
ADD_TO_LINKED_LIST(str, language_type, current_str->incorporates);
}
#line 160 "inweb/Chapter 4/C-Like Languages.w"
;
Regexp__dispose_of(&mr);
}
}
}
#line 29 "inweb/Chapter 4/C-Like Languages.w"
;
}
#line 185 "inweb/Chapter 4/C-Like Languages.w"
int cc_sp = 0;
source_line *cc_stack[MAX_CONDITIONAL_COMPILATION_STACK];
void CLike__parse_functions(programming_language *self, web *W) {
cc_sp = 0;
chapter *C;
section *S;
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
if ((L->category == CODE_BODY_LCAT) ||
(L->category == BEGIN_DEFINITION_LCAT) ||
(L->category == CONT_DEFINITION_LCAT)) {
{
#line 204 "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_327, 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_328, L);
else
cc_sp--;
}
}
#line 196 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 230 "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 257 "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 234 "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 274 "inweb/Chapter 4/C-Like Languages.w"
{
#line 294 "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 274 "inweb/Chapter 4/C-Like Languages.w"
;
language_function *fn = Functions__new_function(fname, L);
fn->function_arguments = Str__duplicate(arguments);
WRITE_TO(fn->function_type, "%S%S %S", qualifiers, ftype, asts);
if (Str__eq_wide_string(fn->function_name, L"isdigit")) fn->call_freely = TRUE;
fn->no_conditionals = cc_sp;
for (int i=0; i<cc_sp; i++) fn->within_conditionals[i] = cc_stack[i];
}
#line 241 "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 197 "inweb/Chapter 4/C-Like Languages.w"
;
}
if (cc_sp > 0)
Main__error_in_web(TL_IS_326, NULL);
}
#line 317 "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 346 "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 365 "inweb/Chapter 4/C-Like Languages.w"
void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) {
{
#line 394 "inweb/Chapter 4/C-Like Languages.w"
language_type *str;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
str->tangled = FALSE;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
CLike__tangle_structure(OUT, self, str);
}
#line 366 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 375 "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 367 "inweb/Chapter 4/C-Like Languages.w"
;
{
#line 436 "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)) {
language_function *fn = L->function_defined;
int to_close = 0;
for (int i=0; i<fn->no_conditionals; i++) {
match_results mr = Regexp__create_mr();
if (!(Regexp__match(&mr, fn->within_conditionals[i]->text,
L"%c*inweb: always predeclare%c*"))) {
WRITE("%S\n", fn->within_conditionals[i]->text);
to_close++;
}
}
Tags__open_ifdefs(OUT, L->owning_paragraph);
LanguageMethods__insert_line_marker(OUT, W->main_language, L);
WRITE("%S ", fn->function_type);
LanguageMethods__tangle_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; i<to_close; i++) {
WRITE("#endif\n");
}
}
}
#line 368 "inweb/Chapter 4/C-Like Languages.w"
;
}
#line 403 "inweb/Chapter 4/C-Like Languages.w"
void CLike__tangle_structure(OUTPUT_STREAM, programming_language *self, language_type *str) {
if (str->tangled != FALSE) return;
str->tangled = NOT_APPLICABLE;
language_type *embodied = NULL;
LOOP_OVER_LINKED_LIST(embodied, language_type, str->incorporates)
CLike__tangle_structure(OUT, self, embodied);
str->tangled = TRUE;
Tags__open_ifdefs(OUT, str->structure_header_at->owning_paragraph);
LanguageMethods__insert_line_marker(OUT, self, str->structure_header_at);
for (source_line *L = str->structure_header_at; L; L = L->next_line) {
WRITE("%S\n", L->text);
L->suppress_tangling = TRUE;
if (L == str->typedef_ends) break;
}
Tags__close_ifdefs(OUT, str->structure_header_at->owning_paragraph);
}
#line 470 "inweb/Chapter 4/C-Like Languages.w"
void CLike__analyse_code(programming_language *self, web *W) {
language_function *fn;
LOOP_OVER(fn, language_function)
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
fn->function_name, TRUE);
language_type *str;
structure_element *elt;
LOOP_OVER_LINKED_LIST(str, language_type, W->language_types)
LOOP_OVER_LINKED_LIST(elt, structure_element, str->elements)
if (elt->allow_sharing == FALSE)
Analyser__find_hash_entry_for_section(elt->element_created_at->owning_section,
elt->element_name, TRUE);
}
#line 492 "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_329), L"On")) check_namespaces = TRUE;
language_function *fn;
LOOP_OVER(fn, language_function) {
hash_table_entry *hte =
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
fn->function_name, FALSE);
if (hte) {
hash_table_entry_usage *hteu;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages) {
if ((hteu->form_of_usage & FCALL_USAGE) || (fn->within_namespace))
if (hteu->usage_recorded_at->under_section != fn->function_header_at->owning_section)
fn->called_from_other_sections = TRUE;
}
}
if ((fn->within_namespace != fn->called_from_other_sections)
&& (check_namespaces)
&& (fn->call_freely == FALSE)) {
if (fn->within_namespace)
Main__error_in_web(
TL_IS_330,
fn->function_header_at);
else
Main__error_in_web(
TL_IS_331,
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"<k-%c+")) pnt->takes_pointer_result = TRUE;
if (Regexp__match(&mr, pnt->nt_name, L"<s-%c+")) pnt->takes_pointer_result = TRUE;
Regexp__dispose_of(&mr);
int min = 1, max = form;
if (form < 0) max = INFINITE_WORD_COUNT;
if (max == 0) min = 0;
else if (max != INFINITE_WORD_COUNT) min = max;
pnt->min_word_count = min;
pnt->max_word_count = max;
}
#line 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 672 "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 684 "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 716 "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 750 "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 764 "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_336;
if (Str__eq_wide_string(name, L"rp")) return TL_IS_337;
nonterminal_variable *ntv;
LOOP_OVER(ntv, nonterminal_variable)
if (Str__eq(ntv->ntv_name, name))
return ntv->ntv_identifier;
return NULL;
}
#line 785 "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_338);
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_339))
WRITE("language %S\n", Bibliographic__get_datum(W->md, TL_IS_340));
{
#line 820 "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 802 "inweb/Chapter 4/InC Support.w"
;
STREAM_CLOSE(OUT);
}
}
#line 847 "inweb/Chapter 4/InC Support.w"
void InCSupport__weave_grammar_index(OUTPUT_STREAM) {
WRITE("\\raggedright\\tolerance=10000");
preform_nonterminal *pnt;
for (pnt = alphabetical_list_of_nonterminals; pnt;
pnt = pnt->next_pnt_alphabetically) {
WRITE("\\line{\\nonterminal{%S}%s"
"\\leaders\\hbox to 1em{\\hss.\\hss}\\hfill {\\xreffont %S}}\n",
pnt->unangled_name,
(pnt->as_function)?" (internal)":"",
pnt->where_defined->owning_section->md->sect_range);
int said_something = FALSE;
{
#line 894 "inweb/Chapter 4/InC Support.w"
section *S;
LOOP_OVER(S, section) S->scratch_flag = FALSE;
hash_table_entry *hte = Analyser__find_hash_entry_for_section(
pnt->where_defined->owning_section, pnt->unangled_name, FALSE);
hash_table_entry_usage *hteu;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if (hteu->form_of_usage & PREFORM_IN_GRAMMAR_USAGE)
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
int use_count = 0;
LOOP_OVER(S, section)
if (S->scratch_flag)
use_count++;
if (use_count > 0) {
said_something = TRUE;
WRITE("\\par\\hangindent=3em{\\it used by other nonterminals in} ");
int c = 0;
LOOP_OVER(S, section)
if (S->scratch_flag) {
if (c++ > 0) WRITE(", ");
WRITE("{\\xreffont %S}", S->md->sect_range);
}
WRITE("\n\n");
}
}
#line 858 "inweb/Chapter 4/InC Support.w"
;
{
#line 869 "inweb/Chapter 4/InC Support.w"
section *S;
LOOP_OVER(S, section) S->scratch_flag = FALSE;
hash_table_entry *hte = Analyser__find_hash_entry_for_section(
pnt->where_defined->owning_section, pnt->unangled_name, FALSE);
hash_table_entry_usage *hteu;
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
if (hteu->form_of_usage & PREFORM_IN_CODE_USAGE)
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
int use_count = 0;
LOOP_OVER(S, section)
if (S->scratch_flag)
use_count++;
if (use_count > 0) {
said_something = TRUE;
WRITE("\\par\\hangindent=3em{\\it called from} ");
int c = 0;
LOOP_OVER(S, section)
if (S->scratch_flag) {
if (c++ > 0) WRITE(", ");
WRITE("{\\xreffont %S}", S->md->sect_range);
}
WRITE("\n\n");
}
}
#line 859 "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 923 "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 940 "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 954 "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 961 "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/Format Methods.w"
weave_format *Formats__create_weave_format(text_stream *name, text_stream *ext) {
weave_format *wf = CREATE(weave_format);
wf->format_name = Str__duplicate(name);
wf->woven_extension = Str__duplicate(ext);
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/Format Methods.w"
text_stream *Formats__file_extension(weave_format *wf) {
return wf->woven_extension;
}
#line 48 "inweb/Chapter 5/Format Methods.w"
void Formats__create_weave_formats(void) {
TeX__create();
PlainText__create();
HTMLFormat__create();
}
#line 67 "inweb/Chapter 5/Format Methods.w"
#line 69 "inweb/Chapter 5/Format Methods.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/Format Methods.w"
#line 91 "inweb/Chapter 5/Format Methods.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/Format Methods.w"
#line 108 "inweb/Chapter 5/Format Methods.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/Format Methods.w"
#line 123 "inweb/Chapter 5/Format Methods.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/Format Methods.w"
#line 143 "inweb/Chapter 5/Format Methods.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/Format Methods.w"
#line 167 "inweb/Chapter 5/Format Methods.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 184 "inweb/Chapter 5/Format Methods.w"
#line 186 "inweb/Chapter 5/Format Methods.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, int linked)
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, int linked) {
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, linked);
}
#line 204 "inweb/Chapter 5/Format Methods.w"
#line 206 "inweb/Chapter 5/Format Methods.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_341, fragment, colouring, TL_IS_342, FALSE, FALSE, TRUE, FALSE);
DISCARD_TEXT(colouring);
VMETHOD_CALL(wf, INLINE_CODE_FOR_MTID, OUT, wv, FALSE);
}
#line 220 "inweb/Chapter 5/Format Methods.w"
#line 222 "inweb/Chapter 5/Format Methods.w"
VMETHOD_TYPE(URL_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
text_stream *url, text_stream *content, int external)
void Formats__url(OUTPUT_STREAM, weave_target *wv, text_stream *url,
text_stream *content, int external) {
weave_format *wf = wv->format;
if (Methods__provided(wf->methods, URL_FOR_MTID)) {
VMETHOD_CALL(wf, URL_FOR_MTID, OUT, wv, url, content, external);
} else {
WRITE("%S", content);
}
}
#line 237 "inweb/Chapter 5/Format Methods.w"
#line 239 "inweb/Chapter 5/Format Methods.w"
VMETHOD_TYPE(FOOTNOTE_CUE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
text_stream *cue)
void Formats__footnote_cue(OUTPUT_STREAM, weave_target *wv, text_stream *cue) {
weave_format *wf = wv->format;
if (Methods__provided(wf->methods, FOOTNOTE_CUE_FOR_MTID)) {
VMETHOD_CALL(wf, FOOTNOTE_CUE_FOR_MTID, OUT, wv, cue);
} else {
WRITE("[%S]", cue);
}
}
#line 253 "inweb/Chapter 5/Format Methods.w"
#line 255 "inweb/Chapter 5/Format Methods.w"
VMETHOD_TYPE(BEGIN_FOOTNOTE_TEXT_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
text_stream *cue)
void Formats__begin_footnote_text(OUTPUT_STREAM, weave_target *wv, text_stream *cue) {
weave_format *wf = wv->format;
if (Methods__provided(wf->methods, BEGIN_FOOTNOTE_TEXT_FOR_MTID)) {
VMETHOD_CALL(wf, BEGIN_FOOTNOTE_TEXT_FOR_MTID, OUT, wv, cue);
} else {
WRITE("[%S]. ", cue);
}
}
#line 270 "inweb/Chapter 5/Format Methods.w"
#line 272 "inweb/Chapter 5/Format Methods.w"
VMETHOD_TYPE(END_FOOTNOTE_TEXT_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
text_stream *cue)
void Formats__end_footnote_text(OUTPUT_STREAM, weave_target *wv, text_stream *cue) {
weave_format *wf = wv->format;
if (Methods__provided(wf->methods, END_FOOTNOTE_TEXT_FOR_MTID)) {
VMETHOD_CALL(wf, END_FOOTNOTE_TEXT_FOR_MTID, OUT, wv, cue);
} else {
WRITE("\n");
}
}
#line 287 "inweb/Chapter 5/Format Methods.w"
#line 289 "inweb/Chapter 5/Format Methods.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 309 "inweb/Chapter 5/Format Methods.w"
#line 311 "inweb/Chapter 5/Format Methods.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 322 "inweb/Chapter 5/Format Methods.w"
#line 324 "inweb/Chapter 5/Format Methods.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 335 "inweb/Chapter 5/Format Methods.w"
#line 337 "inweb/Chapter 5/Format Methods.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 350 "inweb/Chapter 5/Format Methods.w"
#line 352 "inweb/Chapter 5/Format Methods.w"
VMETHOD_TYPE(EMBED_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
text_stream *service, text_stream *ID)
void Formats__embed(OUTPUT_STREAM, weave_target *wv, text_stream *service,
text_stream *ID) {
weave_format *wf = wv->format;
VMETHOD_CALL(wf, EMBED_FOR_MTID, OUT, wv, service, ID);
}
#line 365 "inweb/Chapter 5/Format Methods.w"
#line 367 "inweb/Chapter 5/Format Methods.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 379 "inweb/Chapter 5/Format Methods.w"
#line 381 "inweb/Chapter 5/Format Methods.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 393 "inweb/Chapter 5/Format Methods.w"
#line 395 "inweb/Chapter 5/Format Methods.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 408 "inweb/Chapter 5/Format Methods.w"
#line 410 "inweb/Chapter 5/Format Methods.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 423 "inweb/Chapter 5/Format Methods.w"
#line 425 "inweb/Chapter 5/Format Methods.w"
VMETHOD_TYPE(CHANGE_MATERIAL_FOR_MTID, weave_format *wf, text_stream *OUT,
weave_target *wv, int old_material, int new_material, int content, int plainly)
void Formats__change_material(OUTPUT_STREAM, weave_target *wv,
int old_material, int new_material, int content, int plainly) {
weave_format *wf = wv->format;
VMETHOD_CALL(wf, CHANGE_MATERIAL_FOR_MTID, OUT, wv, old_material, new_material,
content, plainly);
}
#line 440 "inweb/Chapter 5/Format Methods.w"
#line 442 "inweb/Chapter 5/Format Methods.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 455 "inweb/Chapter 5/Format Methods.w"
void Formats__text(OUTPUT_STREAM, weave_target *wv, text_stream *id) {
Formats__text_r(OUT, wv, id, FALSE, FALSE);
}
void Formats__text_comment(OUTPUT_STREAM, weave_target *wv, text_stream *id) {
Formats__text_r(OUT, wv, id, FALSE, TRUE);
}
void Formats__text_r(OUTPUT_STREAM, weave_target *wv, text_stream *id,
int within, int comments) {
text_stream *code_in_comments_notation =
Bibliographic__get_datum(wv->weave_web->md,
(comments)?(TL_IS_343):(TL_IS_344));
if (Str__ne(code_in_comments_notation, TL_IS_345))
{
#line 484 "inweb/Chapter 5/Format Methods.w"
for (int i=0; i < Str__len(id); i++) {
if (Str__get_at(id, i) == '\\') i += Str__len(code_in_comments_notation) - 1;
else if (Str__includes_at(id, i, code_in_comments_notation)) {
TEMPORARY_TEXT(before);
Str__copy(before, id); Str__truncate(before, i);
TEMPORARY_TEXT(after);
Str__substr(after, Str__at(id,
i + Str__len(code_in_comments_notation)), Str__end(id));
Formats__text_r(OUT, wv, before, within, comments);
Formats__text_r(OUT, wv, after, (within)?FALSE:TRUE, comments);
DISCARD_TEXT(before);
DISCARD_TEXT(after);
return;
}
}
}
#line 467 "inweb/Chapter 5/Format Methods.w"
;
if (within == FALSE)
{
#line 501 "inweb/Chapter 5/Format Methods.w"
for (int i=0; i < Str__len(id); i++) {
if ((Str__includes_at(id, i, TL_IS_348)) ||
(Str__includes_at(id, i, TL_IS_349))) {
TEMPORARY_TEXT(before);
Str__copy(before, id); Str__truncate(before, i);
TEMPORARY_TEXT(after);
Str__substr(after, Str__at(id, i), Str__end(id));
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, after, L"(https*://%C+)(%c*)")) {
Formats__text_r(OUT, wv, before, within, comments);
Formats__url(OUT, wv, mr.exp[0], mr.exp[0], TRUE);
Formats__text_r(OUT, wv, mr.exp[1], within, comments);
Regexp__dispose_of(&mr);
return;
}
Regexp__dispose_of(&mr);
DISCARD_TEXT(before);
DISCARD_TEXT(after);
}
}
}
#line 469 "inweb/Chapter 5/Format Methods.w"
;
text_stream *xref_notation = Bibliographic__get_datum(wv->weave_web->md,
TL_IS_346);
if (Str__ne(xref_notation, TL_IS_347))
{
#line 539 "inweb/Chapter 5/Format Methods.w"
int N = Str__len(xref_notation);
for (int i=0; i < Str__len(id); i++) {
if ((within == FALSE) && (Str__includes_at(id, i, xref_notation))) {
int j = i + N+1;
while (j < Str__len(id)) {
if (Str__includes_at(id, j, xref_notation)) {
int allow = FALSE;
TEMPORARY_TEXT(before);
TEMPORARY_TEXT(reference);
TEMPORARY_TEXT(after);
Str__substr(before, Str__start(id), Str__at(id, i));
Str__substr(reference, Str__at(id, i + N), Str__at(id, j));
Str__substr(after, Str__at(id, j + N), Str__end(id));
{
#line 564 "inweb/Chapter 5/Format Methods.w"
TEMPORARY_TEXT(url);
TEMPORARY_TEXT(title);
if (Colonies__resolve_reference_in_weave(url, title, wv->weave_to, reference,
wv->weave_web->md, wv->current_weave_line)) {
Formats__text_r(OUT, wv, before, within, comments);
Formats__url(OUT, wv, url, title, FALSE);
Formats__text_r(OUT, wv, after, within, comments);
allow = TRUE;
}
DISCARD_TEXT(url);
DISCARD_TEXT(title);
}
#line 552 "inweb/Chapter 5/Format Methods.w"
;
DISCARD_TEXT(before);
DISCARD_TEXT(reference);
DISCARD_TEXT(after);
if (allow) return;
}
j++;
}
}
}
}
#line 473 "inweb/Chapter 5/Format Methods.w"
;
if (within) {
Formats__source_fragment(OUT, wv, id);
} else {
{
#line 523 "inweb/Chapter 5/Format Methods.w"
TEMPORARY_TEXT(before);
TEMPORARY_TEXT(cue);
TEMPORARY_TEXT(after);
int allow = FALSE;
if (Parser__detect_footnote(wv->weave_web, id, before, cue, after)) {
allow = TRUE;
Formats__text_r(OUT, wv, before, within, comments);
Formats__footnote_cue(OUT, wv, cue);
Formats__text_r(OUT, wv, after, within, comments);
}
DISCARD_TEXT(before);
DISCARD_TEXT(cue);
DISCARD_TEXT(after);
if (allow) return;
}
#line 478 "inweb/Chapter 5/Format Methods.w"
;
Formats__text_fragment(OUT, wv, id);
}
}
#line 584 "inweb/Chapter 5/Format Methods.w"
#line 586 "inweb/Chapter 5/Format Methods.w"
IMETHOD_TYPE(PRESERVE_MATH_MODE_FOR_MTID, weave_format *wf, weave_target *wv,
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 = TRUE;
if (Str__eq_wide_string(
Bibliographic__get_datum(wv->weave_web->md, TL_IS_350), L"On")) {
rv = FALSE;
IMETHOD_CALL(rv, wf, PRESERVE_MATH_MODE_FOR_MTID, wv, matter, fragment);
}
if (rv == FALSE) TeX__remove_math_mode(matter, fragment);
else if (Str__len(matter) == 0) Str__copy(matter, fragment);
VMETHOD_CALL(wf, COMMENTARY_TEXT_FOR_MTID, OUT, wv, matter);
DISCARD_TEXT(matter);
}
#line 611 "inweb/Chapter 5/Format Methods.w"
#line 613 "inweb/Chapter 5/Format Methods.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 631 "inweb/Chapter 5/Format Methods.w"
#line 633 "inweb/Chapter 5/Format Methods.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 645 "inweb/Chapter 5/Format Methods.w"
#line 647 "inweb/Chapter 5/Format Methods.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 658 "inweb/Chapter 5/Format Methods.w"
#line 660 "inweb/Chapter 5/Format Methods.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 675 "inweb/Chapter 5/Format Methods.w"
#line 677 "inweb/Chapter 5/Format Methods.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 686 "inweb/Chapter 5/Format Methods.w"
#line 688 "inweb/Chapter 5/Format Methods.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 698 "inweb/Chapter 5/Format Methods.w"
#line 700 "inweb/Chapter 5/Format Methods.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 713 "inweb/Chapter 5/Format Methods.w"
#line 715 "inweb/Chapter 5/Format Methods.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_351, TL_IS_352);
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->md->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, int linked) {
if (starts) {
for (int i=0; i<tab_stops_of_indentation; i++)
WRITE(" ");
if (Str__len(prefatory) > 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_353, TL_IS_354);
{
#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__preserve_math_mode);
}
#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_355, TL_IS_356);
{
#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__preserve_math_mode);
}
#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__preserve_math_mode);
}
#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_357, TL_IS_358);
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__preserve_math_mode);
}
#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__preserve_math_mode);
}
#line 12 "inweb/Chapter 5/TeX Format.w"
;
}
#line 67 "inweb/Chapter 5/TeX Format.w"
int TeX__preserve_math_mode(weave_format *self, weave_target *wv,
text_stream *matter, text_stream *id) {
return TRUE;
}
int TeX__yes(weave_format *self, weave_target *wv) {
return TRUE;
}
#line 77 "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 90 "inweb/Chapter 5/TeX Format.w"
filename *Macros = Patterns__obtain_filename(wv->pattern, TL_IS_359);
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 79 "inweb/Chapter 5/TeX Format.w"
;
}
#line 101 "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 117 "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 139 "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->md->sect_range);
WRITE("{\\it %S}\\qquad\n%S", S->md->sect_title, S->sect_purpose);
}
}
#line 152 "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->md->sect_range);
DISCARD_TEXT(mark);
DISCARD_TEXT(modified);
Regexp__dispose_of(&mr);
}
#line 185 "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, int linked) {
if (code_mode == FALSE) WRITE("\\smallskip\\par\\noindent");
if (starts) {
{
#line 217 "inweb/Chapter 5/TeX Format.w"
for (int i=0; i<tab_stops_of_indentation; i++)
WRITE("\\qquad");
}
#line 191 "inweb/Chapter 5/TeX Format.w"
;
if (Str__len(prefatory) > 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 221 "inweb/Chapter 5/TeX Format.w"
if (colour_wanted != current_colour) {
Formats__change_colour(OUT, wv, colour_wanted, TRUE);
current_colour = colour_wanted;
}
}
#line 197 "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 221 "inweb/Chapter 5/TeX Format.w"
if (colour_wanted != current_colour) {
Formats__change_colour(OUT, wv, colour_wanted, TRUE);
current_colour = colour_wanted;
}
}
#line 201 "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 227 "inweb/Chapter 5/TeX Format.w"
void TeX__inline_code(weave_format *self, text_stream *OUT, weave_target *wv,
int enter) {
WRITE("|");
}
#line 233 "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 250 "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 256 "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 268 "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 280 "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 302 "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 329 "inweb/Chapter 5/TeX Format.w"
void TeX__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) {
WRITE("\\vfill\\eject\n");
}
#line 334 "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 341 "inweb/Chapter 5/TeX Format.w"
void TeX__after_definitions(weave_format *self, text_stream *OUT, weave_target *wv) {
WRITE("\\smallskip\n");
}
#line 346 "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 356 "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 379 "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 386 "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, int change_material) {
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 412 "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 422 "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 439 "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 427 "inweb/Chapter 5/TeX Format.w"
;
return TRUE;
} else {
if (L->category == PREFORM_GRAMMAR_LCAT) {
{
#line 455 "inweb/Chapter 5/TeX Format.w"
TEMPORARY_TEXT(problem);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, matter, L"Issue (%c*?) problem")) Str__copy(problem, mr.exp[0]);
else if (Regexp__match(&mr, matter, L"FAIL_NONTERMINAL %+")) WRITE_TO(problem, "fail and skip");
else if (Regexp__match(&mr, matter, L"FAIL_NONTERMINAL")) WRITE_TO(problem, "fail");
preform_production_count++;
WRITE_TO(matter, "|%S|", L->text_operand);
while (Regexp__match(&mr, matter, L"(%c+?)|(%c+)")) {
Str__clear(matter);
WRITE_TO(matter, "%S___stroke___%S", mr.exp[0], mr.exp[1]);
}
while (Regexp__match(&mr, matter, L"(%c*?)___stroke___(%c*)")) {
Str__clear(matter);
WRITE_TO(matter, "%S|\\||%S", mr.exp[0], mr.exp[1]);
}
while (Regexp__match(&mr, matter, L"(%c*)<(%c*?)>(%c*)")) {
Str__clear(matter);
WRITE_TO(matter, "%S|\\nonterminal{%S}|%S",
mr.exp[0], mr.exp[1], mr.exp[2]);
}
TEMPORARY_TEXT(label);
int N = preform_production_count;
int L = ((N-1)%26) + 1;
if (N <= 26) WRITE_TO(label, "%c", 'a'+L-1);
else if (N <= 52) WRITE_TO(label, "%c%c", 'a'+L-1, 'a'+L-1);
else if (N <= 78) WRITE_TO(label, "%c%c%c", 'a'+L-1, 'a'+L-1, 'a'+L-1);
else {
int n = (N-1)/26;
WRITE_TO(label, "%c${}^{%d}$", 'a'+L-1, n);
}
WRITE("\\qquad {\\hbox to 0.4in{\\it %S\\hfil}}%S", label, matter);
if (Str__len(problem) > 0)
WRITE("\\hfill$\\longrightarrow$ {\\ttninepoint\\it %S}", problem);
else if (Str__len(concluding_comment) > 0) {
WRITE(" \\hfill{\\ttninepoint\\it ");
if (Str__len(concluding_comment) > 0)
Formats__text_comment(OUT, wv, concluding_comment);
WRITE("}");
}
WRITE("\n");
DISCARD_TEXT(label);
DISCARD_TEXT(problem);
Regexp__dispose_of(&mr);
}
#line 431 "inweb/Chapter 5/TeX Format.w"
;
return TRUE;
}
}
return FALSE;
}
#line 502 "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 510 "inweb/Chapter 5/TeX Format.w"
void TeX__post_process_report(weave_format *self, weave_target *wv) {
RunningTeX__report_on_post_processing(wv);
}
#line 515 "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 528 "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 559 "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 537 "inweb/Chapter 5/TeX Format.w"
;
}
for (int i=from; i <= to; i++) {
{
#line 595 "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 540 "inweb/Chapter 5/TeX Format.w"
;
{
#line 613 "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 541 "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 643 "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_360))
{
#line 766 "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_456)) PUT((wchar_t) 0x2204);
else if (Str__eq(macro, TL_IS_457)) { 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 647 "inweb/Chapter 5/TeX Format.w"
else
{
#line 653 "inweb/Chapter 5/TeX Format.w"
if (Str__eq(macro, TL_IS_361)) WRITE("<=");
else if (Str__eq(macro, TL_IS_362)) WRITE(">=");
else if (Str__eq(macro, TL_IS_363)) WRITE("~");
else if (Str__eq(macro, TL_IS_364)) WRITE("");
else if (Str__eq(macro, TL_IS_365)) WRITE("");
else if (Str__eq(macro, TL_IS_366)) WRITE("");
else if (Str__eq(macro, TL_IS_367)) WRITE("=>");
else if (Str__eq(macro, TL_IS_368)) WRITE("<=>");
else if (Str__eq(macro, TL_IS_369)) WRITE("-->");
else if (Str__eq(macro, TL_IS_370)) WRITE("-->");
else if (Str__eq(macro, TL_IS_371)) WRITE("-->");
else if (Str__eq(macro, TL_IS_372)) WRITE("<--");
else if (Str__eq(macro, TL_IS_373)) WRITE("<--");
else if (Str__eq(macro, TL_IS_374)) WRITE("{");
else if (Str__eq(macro, TL_IS_375)) WRITE("|");
else if (Str__eq(macro, TL_IS_376)) WRITE("}");
else if (Str__eq(macro, TL_IS_377)) WRITE(".");
else if (Str__eq(macro, TL_IS_378)) WRITE("...");
else if (Str__eq(macro, TL_IS_379)) WRITE("...");
else if (Str__eq(macro, TL_IS_380)) WRITE("*");
else if (Str__eq(macro, TL_IS_381)) WRITE(" ");
else if (Str__eq(macro, TL_IS_382)) WRITE(" ");
else if (Str__eq(macro, TL_IS_383)) WRITE("TeX");
else if (Str__eq(macro, TL_IS_384)) WRITE("!=");
else if (Str__eq(macro, TL_IS_385)) WRITE("!=");
else if (Str__eq(macro, TL_IS_386)) WRITE("l");
else if (Str__eq(macro, TL_IS_387)) WRITE("log");
else if (Str__eq(macro, TL_IS_388)) WRITE("exp");
else if (Str__eq(macro, TL_IS_389)) WRITE("sin");
else if (Str__eq(macro, TL_IS_390)) WRITE("cos");
else if (Str__eq(macro, TL_IS_391)) WRITE("tan");
else if (Str__eq(macro, TL_IS_392)) WRITE("T");
else if (Str__eq(macro, TL_IS_393)) PUT((wchar_t) 0x0391);
else if (Str__eq(macro, TL_IS_394)) PUT((wchar_t) 0x0392);
else if (Str__eq(macro, TL_IS_395)) PUT((wchar_t) 0x0393);
else if (Str__eq(macro, TL_IS_396)) PUT((wchar_t) 0x0394);
else if (Str__eq(macro, TL_IS_397)) PUT((wchar_t) 0x0395);
else if (Str__eq(macro, TL_IS_398)) PUT((wchar_t) 0x0396);
else if (Str__eq(macro, TL_IS_399)) PUT((wchar_t) 0x0397);
else if (Str__eq(macro, TL_IS_400)) PUT((wchar_t) 0x0398);
else if (Str__eq(macro, TL_IS_401)) PUT((wchar_t) 0x0399);
else if (Str__eq(macro, TL_IS_402)) PUT((wchar_t) 0x039A);
else if (Str__eq(macro, TL_IS_403)) PUT((wchar_t) 0x039B);
else if (Str__eq(macro, TL_IS_404)) PUT((wchar_t) 0x039C);
else if (Str__eq(macro, TL_IS_405)) PUT((wchar_t) 0x039D);
else if (Str__eq(macro, TL_IS_406)) PUT((wchar_t) 0x039E);
else if (Str__eq(macro, TL_IS_407)) PUT((wchar_t) 0x039F);
else if (Str__eq(macro, TL_IS_408)) PUT((wchar_t) 0x03A0);
else if (Str__eq(macro, TL_IS_409)) PUT((wchar_t) 0x03A1);
else if (Str__eq(macro, TL_IS_410)) PUT((wchar_t) 0x03A2);
else if (Str__eq(macro, TL_IS_411)) PUT((wchar_t) 0x03A3);
else if (Str__eq(macro, TL_IS_412)) PUT((wchar_t) 0x03A4);
else if (Str__eq(macro, TL_IS_413)) PUT((wchar_t) 0x03A5);
else if (Str__eq(macro, TL_IS_414)) PUT((wchar_t) 0x03A6);
else if (Str__eq(macro, TL_IS_415)) PUT((wchar_t) 0x03A7);
else if (Str__eq(macro, TL_IS_416)) PUT((wchar_t) 0x03A8);
else if (Str__eq(macro, TL_IS_417)) PUT((wchar_t) 0x03A9);
else if (Str__eq(macro, TL_IS_418)) PUT((wchar_t) 0x03B1);
else if (Str__eq(macro, TL_IS_419)) PUT((wchar_t) 0x03B2);
else if (Str__eq(macro, TL_IS_420)) PUT((wchar_t) 0x03B3);
else if (Str__eq(macro, TL_IS_421)) PUT((wchar_t) 0x03B4);
else if (Str__eq(macro, TL_IS_422)) PUT((wchar_t) 0x03B5);
else if (Str__eq(macro, TL_IS_423)) PUT((wchar_t) 0x03B6);
else if (Str__eq(macro, TL_IS_424)) PUT((wchar_t) 0x03B7);
else if (Str__eq(macro, TL_IS_425)) PUT((wchar_t) 0x03B8);
else if (Str__eq(macro, TL_IS_426)) PUT((wchar_t) 0x03B9);
else if (Str__eq(macro, TL_IS_427)) PUT((wchar_t) 0x03BA);
else if (Str__eq(macro, TL_IS_428)) PUT((wchar_t) 0x03BB);
else if (Str__eq(macro, TL_IS_429)) PUT((wchar_t) 0x03BC);
else if (Str__eq(macro, TL_IS_430)) PUT((wchar_t) 0x03BD);
else if (Str__eq(macro, TL_IS_431)) PUT((wchar_t) 0x03BE);
else if (Str__eq(macro, TL_IS_432)) PUT((wchar_t) 0x03BF);
else if (Str__eq(macro, TL_IS_433)) PUT((wchar_t) 0x03C0);
else if (Str__eq(macro, TL_IS_434)) PUT((wchar_t) 0x03C1);
else if (Str__eq(macro, TL_IS_435)) PUT((wchar_t) 0x03C2);
else if (Str__eq(macro, TL_IS_436)) PUT((wchar_t) 0x03C3);
else if (Str__eq(macro, TL_IS_437)) PUT((wchar_t) 0x03C4);
else if (Str__eq(macro, TL_IS_438)) PUT((wchar_t) 0x03C5);
else if (Str__eq(macro, TL_IS_439)) PUT((wchar_t) 0x03C6);
else if (Str__eq(macro, TL_IS_440)) PUT((wchar_t) 0x03C7);
else if (Str__eq(macro, TL_IS_441)) PUT((wchar_t) 0x03C8);
else if (Str__eq(macro, TL_IS_442)) PUT((wchar_t) 0x03C9);
else if (Str__eq(macro, TL_IS_443)) PUT((wchar_t) 0x2203);
else if (Str__eq(macro, TL_IS_444)) PUT((wchar_t) 0x2208);
else if (Str__eq(macro, TL_IS_445)) PUT((wchar_t) 0x2200);
else if (Str__eq(macro, TL_IS_446)) PUT((wchar_t) 0x2229);
else if (Str__eq(macro, TL_IS_447)) PUT((wchar_t) 0x2205);
else if (Str__eq(macro, TL_IS_448)) PUT((wchar_t) 0x2286);
else if (Str__eq(macro, TL_IS_449)) PUT((wchar_t) 0x2227);
else if (Str__eq(macro, TL_IS_450)) PUT((wchar_t) 0x2228);
else if (Str__eq(macro, TL_IS_451)) PUT((wchar_t) 0x00AC);
else if (Str__eq(macro, TL_IS_452)) PUT((wchar_t) 0x03A3);
else if (Str__eq(macro, TL_IS_453)) PUT((wchar_t) 0x03A0);
else {
if (Str__len(macro) > 0) {
int suspect = TRUE;
LOOP_THROUGH_TEXT(pos, macro) {
wchar_t c = Str__get(pos);
if ((c >= 'A') && (c <= 'Z')) continue;
if ((c >= 'a') && (c <= 'z')) continue;
suspect = FALSE;
}
if (Str__eq(macro, TL_IS_454)) suspect = FALSE;
if (Str__eq(macro, TL_IS_455)) suspect = FALSE;
if (suspect)
PRINT("[Passing through unknown TeX macro \\%S:\n %S\n", macro, text);
}
WRITE("\\%S", macro);
}
}
#line 648 "inweb/Chapter 5/TeX Format.w"
;
DISCARD_TEXT(macro);
i--;
}
#line 550 "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_458, TL_IS_459);
METHOD_ADD(wf, TOP_FOR_MTID, HTMLFormat__top);
METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, HTMLFormat__preserve_math_mode);
{
#line 25 "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, URL_FOR_MTID, HTMLFormat__url);
METHOD_ADD(wf, FOOTNOTE_CUE_FOR_MTID, HTMLFormat__footnote_cue);
METHOD_ADD(wf, BEGIN_FOOTNOTE_TEXT_FOR_MTID, HTMLFormat__begin_footnote_text);
METHOD_ADD(wf, END_FOOTNOTE_TEXT_FOR_MTID, HTMLFormat__end_footnote_text);
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, EMBED_FOR_MTID, HTMLFormat__embed);
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 15 "inweb/Chapter 5/HTML Formats.w"
;
}
#line 7 "inweb/Chapter 5/HTML Formats.w"
;
{
#line 18 "inweb/Chapter 5/HTML Formats.w"
weave_format *wf = Formats__create_weave_format(TL_IS_460, TL_IS_461);
METHOD_ADD(wf, TOP_FOR_MTID, HTMLFormat__top_EPUB);
{
#line 25 "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, URL_FOR_MTID, HTMLFormat__url);
METHOD_ADD(wf, FOOTNOTE_CUE_FOR_MTID, HTMLFormat__footnote_cue);
METHOD_ADD(wf, BEGIN_FOOTNOTE_TEXT_FOR_MTID, HTMLFormat__begin_footnote_text);
METHOD_ADD(wf, END_FOOTNOTE_TEXT_FOR_MTID, HTMLFormat__end_footnote_text);
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, EMBED_FOR_MTID, HTMLFormat__embed);
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 20 "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 61 "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 91 "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 116 "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 128 "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 148 "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_462, wv, WEAVE_FIRST_HALF);
if (wv->self_contained == FALSE) {
filename *CSS = Patterns__obtain_filename(wv->pattern, TL_IS_463);
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;
}
int HTMLFormat__preserve_math_mode(weave_format *self, weave_target *wv,
text_stream *matter, text_stream *text) {
text_stream *plugin_name =
Bibliographic__get_datum(wv->weave_web->md, TL_IS_464);
if (Str__eq_insensitive(plugin_name, TL_IS_465)) return FALSE;
int math_mode = FALSE, mode_exists = FALSE;
for (int i=0; i<Str__len(text); i++) {
switch (Str__get_at(text, i)) {
case '$':
mode_exists = TRUE;
if (Str__get_at(text, i+1) == '$') {
WRITE_TO(matter, "$$");
i++; continue;
}
math_mode = (math_mode)?FALSE:TRUE;
if (math_mode) WRITE_TO(matter, "\\(");
else WRITE_TO(matter, "\\)");
break;
default:
PUT_TO(matter, Str__get_at(text, i));
}
}
if (mode_exists) Swarm__ensure_plugin(wv, plugin_name);
return TRUE;
}
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_466);
Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_467, wv, WEAVE_FIRST_HALF);
HTML__comment(OUT, comment);
html_in_para = HTML_OUT;
}
#line 197 "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 214 "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)
Colonies__paragraph_URL(TEMP, P, NULL, TRUE);
HTML__begin_link(OUT, TEMP);
DISCARD_TEXT(TEMP)
WRITE("%s%S", (Str__get_first_char(P->ornament) == 'S')?"&#167;":"&para;",
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 246 "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)
Colonies__paragraph_URL(TEMP, P, NULL, FALSE);
HTML__anchor(OUT, TEMP);
DISCARD_TEXT(TEMP)
HTML_OPEN("b");
WRITE("%s%S", (Str__get_first_char(P->ornament) == 'S')?"&#167;":"&para;",
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_468);
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\"");
Colonies__drop_initial_breadcrumbs(OUT,
wv->weave_to, wv->breadcrumbs);
text_stream *bct = Bibliographic__get_datum(wv->weave_web->md, TL_IS_469);
if (Str__len(Bibliographic__get_datum(wv->weave_web->md, TL_IS_470)) > 0) {
bct = Bibliographic__get_datum(wv->weave_web->md, TL_IS_471);
}
HTMLFormat__breadcrumb(OUT, bct, TL_IS_472);
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");
}
}
}
#line 305 "inweb/Chapter 5/HTML Formats.w"
int popup_counter = 0;
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, int linked) {
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_473)) {
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, linked);
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, linked);
Regexp__dispose_of(&mr);
return;
}
Regexp__dispose_of(&mr);
}
} else
for (int i=0; i<tab_stops_of_indentation; i++)
WRITE(" ");
}
int current_colour = -1, colour_wanted = PLAIN_COLOUR;
for (int i=0; i < Str__len(matter); i++) {
colour_wanted = Str__get_at(colouring, i);
{
#line 407 "inweb/Chapter 5/HTML Formats.w"
if (colour_wanted != current_colour) {
if (current_colour >= 0) HTML_CLOSE("span");
Formats__change_colour(OUT, wv, colour_wanted, TRUE);
current_colour = colour_wanted;
if ((colour_wanted == FUNCTION_COLOUR) && (wv->current_weave_line) &&
(wv->current_weave_line->category != TEXT_EXTRACT_LCAT)) {
TEMPORARY_TEXT(fname);
int j = i;
while (Str__get_at(colouring, j) == FUNCTION_COLOUR)
PUT_TO(fname, Str__get_at(matter, j++));
if (Analyser__is_reserved_word_for_section(
wv->current_weave_line->owning_section, fname, FUNCTION_COLOUR)) {
source_line *defn_line = Analyser__get_defn_line(
wv->current_weave_line->owning_section, fname, FUNCTION_COLOUR);
if (wv->current_weave_line == defn_line) {
language_function *fn = Analyser__get_function(
wv->current_weave_line->owning_section, fname, FUNCTION_COLOUR);
if ((defn_line) && (fn) && (fn->usage_described == FALSE)) {
Swarm__ensure_plugin(wv, TL_IS_478);
WRITE("%S", fname);
WRITE("<button class=\"popup\" onclick=\"togglePopup('usagePopup%d')\">", popup_counter);
WRITE("...");
WRITE("<span class=\"popuptext\" id=\"usagePopup%d\">Usage of <b>%S</b>:<br>",
popup_counter, fname);
Weaver__show_function_usage(OUT, wv,
defn_line->owning_paragraph, fn, TRUE);
WRITE("</span>", popup_counter, fname);
WRITE("</button>");
i += Str__len(fname) - 1;
popup_counter++;
continue;
}
} else {
if ((defn_line) && (defn_line->owning_paragraph)) {
TEMPORARY_TEXT(TEMP)
Colonies__paragraph_URL(TEMP, defn_line->owning_paragraph,
wv->current_weave_line->owning_section, TRUE);
HTML__begin_link(OUT, TEMP);
DISCARD_TEXT(TEMP)
WRITE("%S", fname);
HTML__end_link(OUT);
i += Str__len(fname) - 1;
continue;
}
}
}
DISCARD_TEXT(fname);
}
}
}
#line 338 "inweb/Chapter 5/HTML Formats.w"
;
if (linked) {
{
#line 365 "inweb/Chapter 5/HTML Formats.w"
if ((Str__includes_at(matter, i, TL_IS_476)) ||
(Str__includes_at(matter, i, TL_IS_477))) {
TEMPORARY_TEXT(before);
Str__copy(before, matter); Str__truncate(before, i);
TEMPORARY_TEXT(after);
Str__substr(after, Str__at(matter, i), Str__end(matter));
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, after, L"(https*://%C+)(%c*)")) {
Formats__url(OUT, wv, mr.exp[0], mr.exp[0], TRUE);
i += Str__len(mr.exp[0]);
}
DISCARD_TEXT(before);
DISCARD_TEXT(after);
}
}
#line 340 "inweb/Chapter 5/HTML Formats.w"
;
text_stream *xref_notation = Bibliographic__get_datum(wv->weave_web->md,
TL_IS_474);
if (Str__ne(xref_notation, TL_IS_475))
{
#line 381 "inweb/Chapter 5/HTML Formats.w"
int N = Str__len(xref_notation);
if ((Str__includes_at(matter, i, xref_notation))) {
int j = i + N+1;
while (j < Str__len(matter)) {
if (Str__includes_at(matter, j, xref_notation)) {
TEMPORARY_TEXT(reference);
Str__substr(reference, Str__at(matter, i + N), Str__at(matter, j));
{
#line 396 "inweb/Chapter 5/HTML Formats.w"
TEMPORARY_TEXT(url);
TEMPORARY_TEXT(title);
if (Colonies__resolve_reference_in_weave(url, title, wv->weave_to, reference,
wv->weave_web->md, wv->current_weave_line)) {
Formats__url(OUT, wv, url, title, FALSE);
i = j + N;
}
DISCARD_TEXT(url);
DISCARD_TEXT(title);
}
#line 388 "inweb/Chapter 5/HTML Formats.w"
;
DISCARD_TEXT(reference);
}
j++;
}
}
}
#line 344 "inweb/Chapter 5/HTML Formats.w"
;
}
if (Str__get_at(matter, i) == '<') WRITE("&lt;");
else if (Str__get_at(matter, i) == '>') WRITE("&gt;");
else if (Str__get_at(matter, i) == '&') WRITE("&amp;");
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_comment(OUT, wv, concluding_comment);
HTML_CLOSE("span");
}
WRITE("\n");
}
}
#line 458 "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 469 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__url(weave_format *self, text_stream *OUT, weave_target *wv,
text_stream *url, text_stream *content, int external) {
HTML__begin_link_with_class(OUT, (external)?TL_IS_479:TL_IS_480, url);
WRITE("%S", content);
HTML__end_link(OUT);
}
#line 477 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__footnote_cue(weave_format *self, text_stream *OUT, weave_target *wv,
text_stream *cue) {
text_stream *fn_plugin_name =
Bibliographic__get_datum(wv->weave_web->md, TL_IS_481);
if (Str__ne_insensitive(fn_plugin_name, TL_IS_482))
Swarm__ensure_plugin(wv, fn_plugin_name);
WRITE("<sup id=\"fnref:%S\"><a href=\"#fn:%S\" rel=\"footnote\">%S</a></sup>",
cue, cue, cue);
}
#line 488 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__begin_footnote_text(weave_format *self, text_stream *OUT, weave_target *wv,
text_stream *cue) {
text_stream *fn_plugin_name =
Bibliographic__get_datum(wv->weave_web->md, TL_IS_483);
if (Str__ne_insensitive(fn_plugin_name, TL_IS_484))
Swarm__ensure_plugin(wv, fn_plugin_name);
WRITE("<li class=\"footnote\" id=\"fn:%S\"><p>", cue);
}
#line 498 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__end_footnote_text(weave_format *self, text_stream *OUT, weave_target *wv,
text_stream *cue) {
text_stream *fn_plugin_name =
Bibliographic__get_datum(wv->weave_web->md, TL_IS_485);
if (Str__ne_insensitive(fn_plugin_name, TL_IS_486))
Swarm__ensure_plugin(wv, fn_plugin_name);
WRITE("<a href=\"#fnref:%S\" title=\"return to text\"> &#x21A9;</a></p></li>", cue);
}
#line 508 "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 519 "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 528 "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 534 "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_487),
figname);
filename *RF = Filenames__from_text(figname);
HTML_OPEN("center");
HTML__image(OUT, RF);
Patterns__copy_file_into_weave(wv->weave_web, F);
HTML_CLOSE("center");
WRITE("\n");
}
#line 549 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__embed(weave_format *self, text_stream *OUT, weave_target *wv,
text_stream *service, text_stream *ID) {
text_stream *CH = TL_IS_488;
text_stream *CW = TL_IS_489;
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, ID, L"(%c+) at (%c+) by (%c+)")) {
CW = Str__duplicate(mr.exp[1]);
CH = Str__duplicate(mr.exp[2]);
ID = mr.exp[0];
} else if (Regexp__match(&mr, ID, L"(%c+) at (%c+)")) {
CH = Str__duplicate(mr.exp[1]);
ID = mr.exp[0];
}
HTMLFormat__exit_current_paragraph(OUT);
TEMPORARY_TEXT(embed_leaf);
WRITE_TO(embed_leaf, "%S.html", service);
filename *F = Filenames__in_folder(
Pathnames__subfolder(wv->weave_web->md->path_to_web, TL_IS_490), embed_leaf);
if (TextFiles__exists(F) == FALSE)
F = Filenames__in_folder(
Pathnames__subfolder(path_to_inweb, TL_IS_491), embed_leaf);
DISCARD_TEXT(embed_leaf);
if (TextFiles__exists(F) == FALSE) {
Main__error_in_web(TL_IS_492, wv->current_weave_line);
return;
}
Bibliographic__set_datum(wv->weave_web->md, TL_IS_493, ID);
Bibliographic__set_datum(wv->weave_web->md, TL_IS_494, CW);
Bibliographic__set_datum(wv->weave_web->md, TL_IS_495, CH);
HTML_OPEN("center");
Indexer__run(wv->weave_web, TL_IS_496, F, NULL, OUT, wv->pattern, NULL, NULL, NULL, TRUE);
HTML_CLOSE("center");
WRITE("\n");
Regexp__dispose_of(&mr);
}
#line 588 "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("&lt;");
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("&gt;%s", (defn)?" =":"");
}
#line 603 "inweb/Chapter 5/HTML Formats.w"
void HTMLFormat__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) {
HTMLFormat__exit_current_paragraph(OUT);
}
#line 608 "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 621 "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, int plainly) {
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:
if (plainly) HTMLFormat__pre(OUT, "undisplay");
else 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");
if (plainly) HTMLFormat__pre(OUT, "undisplay");
else 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 690 "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 711 "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 721 "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("&amp;");
else if (Str__get_at(id, i) == '<') WRITE("&lt;");
else if (Str__get_at(id, i) == '>') WRITE("&gt;");
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("&mdash;"); 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(" &mdash;"); i+=2;
} else PUT(Str__get_at(id, i));
}
}
#line 742 "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)
Colonies__paragraph_URL(TEMP, par1, page_section, TRUE);
HTML__begin_link(OUT, TEMP);
DISCARD_TEXT(TEMP)
WRITE("%s%S",
(Str__get_first_char(par1->ornament) == 'S')?"&#167;":"&para;",
par1->paragraph_number);
if (par2) WRITE("-%S", par2->paragraph_number);
HTML__end_link(OUT);
}
#line 756 "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);
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("<i>(This section begins %S.)</i>", C->md->ch_title);
else {
TEMPORARY_TEXT(TEMP);
Colonies__section_URL(TEMP, prev_S->md);
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("<i>(This section ends %S.)</i>", C->md->ch_title);
else {
TEMPORARY_TEXT(TEMP);
Colonies__section_URL(TEMP, next_S->md);
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_497, wv->booklet_title);
Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_498, wv, WEAVE_SECOND_HALF);
}
#line 803 "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_499));
W->as_ebook = Epub__new(T, "P");
filename *CSS = Patterns__obtain_filename(pattern, TL_IS_500);
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 17 "inweb/Chapter 5/Weave Plugins.w"
#line 19 "inweb/Chapter 5/Weave Plugins.w"
weave_plugin *WeavePlugins__new(text_stream *name) {
weave_plugin *wp = CREATE(weave_plugin);
wp->plugin_name = Str__duplicate(name);
return wp;
}
#line 33 "inweb/Chapter 5/Weave Plugins.w"
void WeavePlugins__include(OUTPUT_STREAM, web *W, weave_plugin *wp,
weave_pattern *pattern) {
pathname *P1 = Pathnames__subfolder(W->md->path_to_web, TL_IS_501);
pathname *P2 = Pathnames__subfolder(path_to_inweb, TL_IS_502);
TEMPORARY_TEXT(embed_leaf);
TEMPORARY_TEXT(css_leaf);
WRITE_TO(embed_leaf, "%S.html", wp->plugin_name);
WRITE_TO(css_leaf, "%S.css", wp->plugin_name);
filename *F = P1?(Filenames__in_folder(P1, embed_leaf)):NULL;
if (TextFiles__exists(F) == FALSE) F = P2?(Filenames__in_folder(P2, embed_leaf)):NULL;
filename *CF = P1?(Filenames__in_folder(P1, css_leaf)):NULL;
if (TextFiles__exists(CF) == FALSE) CF = P2?(Filenames__in_folder(P2, css_leaf)):NULL;
DISCARD_TEXT(embed_leaf);
DISCARD_TEXT(css_leaf);
if (TextFiles__exists(F) == FALSE) {
TEMPORARY_TEXT(err);
WRITE_TO(err, "The plugin '%S' is not supported", wp->plugin_name);
Main__error_in_web(err, NULL);
return;
}
Indexer__run(W, TL_IS_503, F, NULL, OUT, pattern, NULL, NULL, NULL, TRUE);
if (TextFiles__exists(CF)) {
WRITE("<link href=\"%S.css\" rel=\"stylesheet\" rev=\"stylesheet\" type=\"text/css\">\n",
wp->plugin_name);
Patterns__copy_file_into_weave(W, CF);
}
}
#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_504, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_505);
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_504, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_505);
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_504, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_505);
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_507);
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_506);
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_508)) || (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_509);
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_510, NULL, NULL);
ADD_TO_LINKED_LIST(V, macro, ws.known_macros);
macro *P = Readme__new_macro(TL_IS_511, NULL, NULL);
ADD_TO_LINKED_LIST(P, macro, ws.known_macros);
macro *A = Readme__new_macro(TL_IS_512, 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_513, 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<x; j++) PUT_TO(mt.pars[n], Str__get_at(chunk, j));
Str__trim_white_space(mt.pars[n]);
if ((Str__get_first_char(mt.pars[n]) == '\'') &&
(Str__get_last_char(mt.pars[n]) == '\'')) {
Str__delete_first_character(mt.pars[n]);
Str__delete_last_character(mt.pars[n]);
}
mt.no_pars++;
}
from = x+1;
}
#line 115 "inweb/Chapter 6/Readme Writeme.w"
;
} else if ((c == ',') && (bl == 1))
{
#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<x; j++) PUT_TO(mt.pars[n], Str__get_at(chunk, j));
Str__trim_white_space(mt.pars[n]);
if ((Str__get_first_char(mt.pars[n]) == '\'') &&
(Str__get_last_char(mt.pars[n]) == '\'')) {
Str__delete_first_character(mt.pars[n]);
Str__delete_last_character(mt.pars[n]);
}
mt.no_pars++;
}
from = x+1;
}
#line 116 "inweb/Chapter 6/Readme Writeme.w"
;
}
x++;
}
Str__delete_n_characters(chunk, x);
}
return mt;
}
#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) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, text, L"(%c*?)@(%i+)(%c*)")) {
Readme__expand_material(ws, OUT, mr.exp[0], tfp);
macro_tokens mt = Readme__parse_token_list(mr.exp[2], tfp);
mt.down = ws->stack_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_514))
{
#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_517);
DISCARD_TEXT(program);
}
}
#line 205 "inweb/Chapter 6/Readme Writeme.w"
else if (Str__eq(M->name, TL_IS_515))
{
#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_518);
DISCARD_TEXT(program);
}
}
#line 206 "inweb/Chapter 6/Readme Writeme.w"
else if (Str__eq(M->name, TL_IS_516))
{
#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_519)) WRITE("%S", A->date);
else if (Str__eq(datum, TL_IS_520)) 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_521), TL_IS_522);
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_523);
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_524);
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_525);
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);
}
#line 25 "inweb/Chapter 6/Colonies.w"
#line 49 "inweb/Chapter 6/Colonies.w"
#line 62 "inweb/Chapter 6/Colonies.w"
void Colonies__load(filename *F) {
colony *C = CREATE(colony);
C->members = NEW_LINKED_LIST(colony_member);
colony_reader_state crs;
crs.province = C;
crs.nav = NULL;
crs.crumbs = NEW_LINKED_LIST(breadcrumb_request);
crs.pattern = NULL;
TextFiles__read(F, FALSE, "can't open colony file",
TRUE, Colonies__read_line, NULL, (void *) &crs);
}
#line 78 "inweb/Chapter 6/Colonies.w"
void Colonies__read_line(text_stream *line, text_file_position *tfp, void *v_crs) {
colony_reader_state *crs = (colony_reader_state *) v_crs;
colony *C = crs->province;
Str__trim_white_space(line); /* ignore trailing space */
if (Str__len(line) == 0) return; /* ignore blank lines */
if (Str__get_first_char(line) == '#') return; /* lines opening with |#| are comments */
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, line, L"(%c*?): \"*(%C+)\" at \"(%c*)\" in \"(%c*)\"")) {
colony_member *CM = CREATE(colony_member);
if (Str__eq(mr.exp[0], TL_IS_526)) CM->web_rather_than_module = TRUE;
else if (Str__eq(mr.exp[0], TL_IS_527)) CM->web_rather_than_module = FALSE;
else {
CM->web_rather_than_module = FALSE;
Errors__in_text_file("text before ':' must be 'web' or 'module'", tfp);
}
CM->name = Str__duplicate(mr.exp[1]);
CM->path = Str__duplicate(mr.exp[2]);
CM->home_leaf = Str__new();
if (Str__suffix_eq(CM->path, TL_IS_528, 6)) {
filename *F = Filenames__from_text(CM->path);
Filenames__write_unextended_leafname(CM->home_leaf, F);
WRITE_TO(CM->home_leaf, ".html");
} else {
WRITE_TO(CM->home_leaf, "index.html");
}
CM->weave_path = Pathnames__from_text(mr.exp[3]);
CM->loaded = NULL;
CM->navigation = crs->nav;
CM->breadcrumb_tail = crs->crumbs;
CM->default_weave_pattern = Str__duplicate(crs->pattern);
ADD_TO_LINKED_LIST(CM, colony_member, C->members);
} else if (Regexp__match(&mr, line, L"pattern: none")) {
crs->pattern = NULL;
} else if (Regexp__match(&mr, line, L"pattern: *(%c*)")) {
crs->pattern = Str__duplicate(mr.exp[0]);
} else if (Regexp__match(&mr, line, L"navigation: none")) {
crs->nav = NULL;
} else if (Regexp__match(&mr, line, L"navigation: *(%c*)")) {
crs->nav = Filenames__from_text(mr.exp[0]);
} else if (Regexp__match(&mr, line, L"breadcrumbs: none")) {
crs->crumbs = NEW_LINKED_LIST(breadcrumb_request);
} else if (Regexp__match(&mr, line, L"breadcrumbs: *(%c*)")) {
crs->crumbs = NEW_LINKED_LIST(breadcrumb_request);
match_results mr2 = Regexp__create_mr();
while (Regexp__match(&mr2, mr.exp[0], L"(\"%c*?\") > (%c*)")) {
Colonies__add_crumb(crs->crumbs, mr2.exp[0], tfp);
Str__clear(mr.exp[0]); Str__copy(mr.exp[0], mr2.exp[1]);
}
Colonies__add_crumb(crs->crumbs, mr.exp[0], tfp);
} else {
Errors__in_text_file("unable to read colony member", tfp);
}
Regexp__dispose_of(&mr);
}
#line 136 "inweb/Chapter 6/Colonies.w"
void Colonies__add_crumb(linked_list *L, text_stream *spec, text_file_position *tfp) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, spec, L"\"(%c*?)\"") == FALSE) {
Errors__in_text_file("each crumb must be in double-quotes", tfp);
return;
}
spec = mr.exp[0];
breadcrumb_request *br = Colonies__request_breadcrumb(spec);
ADD_TO_LINKED_LIST(br, breadcrumb_request, L);
Regexp__dispose_of(&mr);
}
#line 153 "inweb/Chapter 6/Colonies.w"
breadcrumb_request *Colonies__request_breadcrumb(text_stream *arg) {
breadcrumb_request *BR = CREATE(breadcrumb_request);
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, arg, L"(%c*?): *(%c*)")) {
BR->breadcrumb_text = Str__duplicate(mr.exp[0]);
BR->breadcrumb_link = Str__duplicate(mr.exp[1]);
} else {
BR->breadcrumb_text = Str__duplicate(arg);
BR->breadcrumb_link = Str__duplicate(arg);
WRITE_TO(BR->breadcrumb_link, ".html");
}
Regexp__dispose_of(&mr);
return BR;
}
void Colonies__drop_initial_breadcrumbs(OUTPUT_STREAM, filename *F, linked_list *crumbs) {
breadcrumb_request *BR;
LOOP_OVER_LINKED_LIST(BR, breadcrumb_request, crumbs) {
TEMPORARY_TEXT(url);
Colonies__link_URL(url, BR->breadcrumb_link, F);
HTMLFormat__breadcrumb(OUT, BR->breadcrumb_text, url);
DISCARD_TEXT(url);
}
}
#line 184 "inweb/Chapter 6/Colonies.w"
colony_member *Colonies__find(text_stream *T) {
colony *C;
LOOP_OVER(C, colony) {
colony_member *CM;
LOOP_OVER_LINKED_LIST(CM, colony_member, C->members)
if (Str__eq_insensitive(T, CM->name))
return CM;
}
return NULL;
}
#line 202 "inweb/Chapter 6/Colonies.w"
module *Colonies__as_module(colony_member *CM, source_line *L, web_md *Wm) {
if (CM->loaded == NULL)
{
#line 211 "inweb/Chapter 6/Colonies.w"
if ((Wm) && (Str__eq_insensitive(Wm->as_module->module_name, CM->name)))
CM->loaded = Wm;
}
#line 203 "inweb/Chapter 6/Colonies.w"
;
if (CM->loaded == NULL)
{
#line 215 "inweb/Chapter 6/Colonies.w"
if (Wm) {
module *M;
LOOP_OVER_LINKED_LIST(M, module, Wm->as_module->dependencies)
if (Str__eq_insensitive(M->module_name, CM->name))
CM->loaded = Wm;
}
}
#line 204 "inweb/Chapter 6/Colonies.w"
;
if (CM->loaded == NULL)
{
#line 223 "inweb/Chapter 6/Colonies.w"
filename *F = NULL;
pathname *P = NULL;
if (Str__suffix_eq(CM->path, TL_IS_529, 6))
F = Filenames__from_text(CM->path);
else
P = Pathnames__from_text(CM->path);
CM->loaded = WebMetadata__get_without_modules(P, F);
}
#line 205 "inweb/Chapter 6/Colonies.w"
;
if (CM->loaded == NULL)
{
#line 232 "inweb/Chapter 6/Colonies.w"
TEMPORARY_TEXT(err);
WRITE_TO(err, "unable to load '%S'", CM->name);
Main__error_in_web(err, L);
}
#line 206 "inweb/Chapter 6/Colonies.w"
;
return CM->loaded->as_module;
}
#line 255 "inweb/Chapter 6/Colonies.w"
int Colonies__resolve_reference_in_weave(text_stream *url, text_stream *title,
filename *for_HTML_file, text_stream *text, web_md *Wm, source_line *L) {
module *from_M = (Wm)?(Wm->as_module):NULL;
module *search_M = from_M;
colony_member *search_CM = NULL;
int external = FALSE;
{
#line 289 "inweb/Chapter 6/Colonies.w"
search_CM = Colonies__find(text);
if (search_CM) {
module *found_M = Colonies__as_module(search_CM, L, Wm);
section_md *found_Sm = FIRST_IN_LINKED_LIST(section_md, found_M->sections_md);
int bare_module_name = TRUE;
WRITE_TO(title, "%S", search_CM->name);
{
#line 336 "inweb/Chapter 6/Colonies.w"
if (found_M == NULL) internal_error("could not locate M");
if (search_CM)
{
#line 342 "inweb/Chapter 6/Colonies.w"
pathname *from = Filenames__get_path_to(for_HTML_file);
pathname *to = search_CM->weave_path;
Pathnames__relative_URL(url, from, to);
if (bare_module_name) WRITE_TO(url, "%S", search_CM->home_leaf);
else if (found_Sm) Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", search_CM->name);
}
#line 337 "inweb/Chapter 6/Colonies.w"
else
{
#line 355 "inweb/Chapter 6/Colonies.w"
if (found_M == from_M) {
Colonies__section_URL(url, found_Sm);
} else {
WRITE_TO(url, "../%S-module/", found_M->module_name);
Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", found_M->module_name);
}
}
#line 338 "inweb/Chapter 6/Colonies.w"
;
return TRUE;
}
#line 295 "inweb/Chapter 6/Colonies.w"
;
}
}
#line 262 "inweb/Chapter 6/Colonies.w"
;
{
#line 299 "inweb/Chapter 6/Colonies.w"
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, text, L"(%c*?): (%c*)")) {
search_CM = Colonies__find(mr.exp[0]);
if (search_CM) {
module *found_M = Colonies__as_module(search_CM, L, Wm);
if (found_M) {
search_M = found_M;
text = Str__duplicate(mr.exp[1]);
external = TRUE;
}
}
}
Regexp__dispose_of(&mr);
}
#line 263 "inweb/Chapter 6/Colonies.w"
;
module *found_M = NULL;
section_md *found_Sm = NULL;
int bare_module_name = FALSE;
int N = WebModules__named_reference(&found_M, &found_Sm, &bare_module_name,
title, search_M, text, FALSE);
if (N == 0) {
if ((L) && (external == FALSE)) {
{
#line 314 "inweb/Chapter 6/Colonies.w"
language_function *fn;
LOOP_OVER(fn, language_function) {
if (Str__eq_insensitive(fn->function_name, text)) {
Colonies__paragraph_URL(url, fn->function_header_at->owning_paragraph,
L->owning_section, TRUE);
WRITE_TO(title, "%S", fn->function_name);
return TRUE;
}
}
}
#line 272 "inweb/Chapter 6/Colonies.w"
;
{
#line 325 "inweb/Chapter 6/Colonies.w"
language_type *str;
LOOP_OVER(str, language_type) {
if (Str__eq_insensitive(str->structure_name, text)) {
Colonies__paragraph_URL(url, str->structure_header_at->owning_paragraph,
L->owning_section, TRUE);
WRITE_TO(title, "%S", str->structure_name);
return TRUE;
}
}
}
#line 273 "inweb/Chapter 6/Colonies.w"
;
}
Main__error_in_web(TL_IS_530, L);
return FALSE;
} else if (N > 1) {
Main__error_in_web(TL_IS_531, L);
WebModules__named_reference(&found_M, &found_Sm, &bare_module_name,
title, search_M, text, TRUE);
return FALSE;
} else {
{
#line 336 "inweb/Chapter 6/Colonies.w"
if (found_M == NULL) internal_error("could not locate M");
if (search_CM)
{
#line 342 "inweb/Chapter 6/Colonies.w"
pathname *from = Filenames__get_path_to(for_HTML_file);
pathname *to = search_CM->weave_path;
Pathnames__relative_URL(url, from, to);
if (bare_module_name) WRITE_TO(url, "%S", search_CM->home_leaf);
else if (found_Sm) Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", search_CM->name);
}
#line 337 "inweb/Chapter 6/Colonies.w"
else
{
#line 355 "inweb/Chapter 6/Colonies.w"
if (found_M == from_M) {
Colonies__section_URL(url, found_Sm);
} else {
WRITE_TO(url, "../%S-module/", found_M->module_name);
Colonies__section_URL(url, found_Sm);
if (bare_module_name == FALSE)
WRITE_TO(title, " (in %S)", found_M->module_name);
}
}
#line 338 "inweb/Chapter 6/Colonies.w"
;
return TRUE;
}
#line 283 "inweb/Chapter 6/Colonies.w"
;
return TRUE;
}
}
#line 367 "inweb/Chapter 6/Colonies.w"
void Colonies__link_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) {
match_results mr = Regexp__create_mr();
if (Regexp__match(&mr, link_text, L"//(%c+)//"))
Colonies__reference_URL(OUT, mr.exp[0], F);
else
WRITE("%S", link_text);
Regexp__dispose_of(&mr);
}
void Colonies__reference_URL(OUTPUT_STREAM, text_stream *link_text, filename *F) {
TEMPORARY_TEXT(title);
TEMPORARY_TEXT(url);
if (Colonies__resolve_reference_in_weave(url, title, F, link_text, NULL, NULL))
WRITE("%S", url);
else
PRINT("Warning: unable to resolve reference '%S' in navigation\n", link_text);
DISCARD_TEXT(title);
DISCARD_TEXT(url);
}
void Colonies__section_URL(OUTPUT_STREAM, section_md *Sm) {
if (Sm == NULL) internal_error("unwoven section");
LOOP_THROUGH_TEXT(pos, Sm->sect_range)
if ((Str__get(pos) == '/') || (Str__get(pos) == ' '))
PUT('-');
else
PUT(Str__get(pos));
WRITE(".html");
}
void Colonies__paragraph_URL(OUTPUT_STREAM, paragraph *P, section *from, int a_link) {
TEMPORARY_TEXT(linkto);
if ((from) && (P->under_section != from)) {
Str__copy(linkto, P->under_section->md->sect_range);
LOOP_THROUGH_TEXT(pos, linkto)
if ((Str__get(pos) == '/') || (Str__get(pos) == ' '))
Str__put(pos, '-');
WRITE_TO(linkto, ".html");
}
WRITE("%S", linkto);
if (P) WRITE("%s%S", (a_link)?"#":"", P->ornament);
DISCARD_TEXT(linkto);
if (P) {
WRITE("P");
text_stream *N = P->paragraph_number;
LOOP_THROUGH_TEXT(pos, N)
if (Str__get(pos) == '.') WRITE("_");
else PUT(Str__get(pos));
}
}
void register_tangled_nonterminals(void) {
}
void register_tangled_text_literals(void) {
TL_IS_0 = Str__literal(L"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"Sequential Section Ranges");
TL_IS_20 = Str__literal(L"On");
TL_IS_21 = Str__literal(L"Web Syntax Version: 1");
TL_IS_22 = Str__literal(L"Web Syntax Version: 2");
TL_IS_23 = Str__literal(L"S");
TL_IS_24 = Str__literal(L"Sections");
TL_IS_25 = Str__literal(L"All");
TL_IS_26 = Str__literal(L"Headers");
TL_IS_27 = Str__literal(L"Language");
TL_IS_28 = Str__literal(L"Language");
TL_IS_29 = Str__literal(L"Contents.w");
TL_IS_30 = Str__literal(L"Author");
TL_IS_31 = Str__literal(L"Language");
TL_IS_32 = Str__literal(L"Purpose");
TL_IS_33 = Str__literal(L"Title");
TL_IS_34 = Str__literal(L"License");
TL_IS_35 = Str__literal(L"Licence");
TL_IS_36 = Str__literal(L"Short Title");
TL_IS_37 = Str__literal(L"Capitalized Title");
TL_IS_38 = Str__literal(L"Build Date");
TL_IS_39 = Str__literal(L"Build Number");
TL_IS_40 = Str__literal(L"Prerelease");
TL_IS_41 = Str__literal(L"Semantic Version Number");
TL_IS_42 = Str__literal(L"Version Number");
TL_IS_43 = Str__literal(L"1");
TL_IS_44 = Str__literal(L"Version Name");
TL_IS_45 = Str__literal(L"Index Template");
TL_IS_46 = Str__literal(L"Preform Language");
TL_IS_47 = Str__literal(L"Declare Section Usage");
TL_IS_48 = Str__literal(L"Off");
TL_IS_49 = Str__literal(L"Namespaces");
TL_IS_50 = Str__literal(L"Off");
TL_IS_51 = Str__literal(L"Sequential Section Ranges");
TL_IS_52 = Str__literal(L"Off");
TL_IS_53 = Str__literal(L"Strict Usage Rules");
TL_IS_54 = Str__literal(L"Off");
TL_IS_55 = Str__literal(L"TeX Mathematics Notation");
TL_IS_56 = Str__literal(L"On");
TL_IS_57 = Str__literal(L"TeX Mathematics Plugin");
TL_IS_58 = Str__literal(L"MathJax3");
TL_IS_59 = Str__literal(L"Footnote Begins Notation");
TL_IS_60 = Str__literal(L"[");
TL_IS_61 = Str__literal(L"Footnote Ends Notation");
TL_IS_62 = Str__literal(L"]");
TL_IS_63 = Str__literal(L"Footnotes Plugin");
TL_IS_64 = Str__literal(L"Bigfoot");
TL_IS_65 = Str__literal(L"Code In Commentary Notation");
TL_IS_66 = Str__literal(L"|");
TL_IS_67 = Str__literal(L"Code In Code Comments Notation");
TL_IS_68 = Str__literal(L"|");
TL_IS_69 = Str__literal(L"Cross-References Notation");
TL_IS_70 = Str__literal(L"//");
TL_IS_71 = Str__literal(L"Web Syntax Version");
TL_IS_72 = Str__literal(L"Capitalized Title");
TL_IS_73 = Str__literal(L"miscellaneous");
TL_IS_74 = Str__literal(L"(main)");
TL_IS_75 = Str__literal(L"build.txt");
TL_IS_76 = Str__literal(L"build.txt");
TL_IS_77 = Str__literal(L"Prerelease");
TL_IS_78 = Str__literal(L"Build Number");
TL_IS_79 = Str__literal(L"Build Date");
TL_IS_80 = Str__literal(L"Semantic Version Number");
TL_IS_81 = Str__literal(L"Version Number");
TL_IS_82 = Str__literal(L"Prerelease");
TL_IS_83 = Str__literal(L"Build Number");
TL_IS_84 = Str__literal(L"Semantic Version Number");
TL_IS_85 = Str__literal(L"The compiler is not feeling well today.");
TL_IS_86 = Str__literal(L"inweb");
TL_IS_87 = Str__literal(L"Patterns");
TL_IS_88 = Str__literal(L"Materials");
TL_IS_89 = Str__literal(L"makescript.txt");
TL_IS_90 = Str__literal(L"gitignorescript.txt");
TL_IS_91 = Str__literal(L"READMEscript.txt");
TL_IS_92 = Str__literal(L"Short Title");
TL_IS_93 = Str__literal(L"Short Title");
TL_IS_94 = Str__literal(L"Title");
TL_IS_95 = Str__literal(L"0");
TL_IS_96 = Str__literal(L"for locating programming language definitions");
TL_IS_97 = Str__literal(L"for analysing a web");
TL_IS_98 = Str__literal(L"for weaving a web");
TL_IS_99 = Str__literal(L"for tangling a web");
TL_IS_100 = Str__literal(L"for dealing with colonies of webs together");
TL_IS_101 = Str__literal(L".inweb");
TL_IS_102 = Str__literal(L"0");
TL_IS_103 = Str__literal(L"0");
TL_IS_104 = Str__literal(L"tex");
TL_IS_105 = Str__literal(L"pdftex");
TL_IS_106 = Str__literal(L"open");
TL_IS_107 = Str__literal(L"Patterns");
TL_IS_108 = Str__literal(L"pattern.txt");
TL_IS_109 = Str__literal(L"pattern.txt");
TL_IS_110 = Str__literal(L"format");
TL_IS_111 = Str__literal(L"abbrevs");
TL_IS_112 = Str__literal(L"numbered");
TL_IS_113 = Str__literal(L"default-range");
TL_IS_114 = Str__literal(L"tex-command");
TL_IS_115 = Str__literal(L"pdftex-command");
TL_IS_116 = Str__literal(L"open-command");
TL_IS_117 = Str__literal(L"Booklet Title");
TL_IS_118 = Str__literal(L"yes");
TL_IS_119 = Str__literal(L"no");
TL_IS_120 = Str__literal(L"../");
TL_IS_121 = Str__literal(L"Inweb Version");
TL_IS_122 = Str__literal(L"Language");
TL_IS_123 = Str__literal(L"Woven");
TL_IS_124 = Str__literal(L"Tangled");
TL_IS_125 = Str__literal(L"Title");
TL_IS_126 = Str__literal(L"");
TL_IS_127 = Str__literal(L"=");
TL_IS_128 = Str__literal(L"@");
TL_IS_129 = Str__literal(L"Figures");
TL_IS_130 = Str__literal(L"unknown [[command]]");
TL_IS_131 = Str__literal(L"<...> definition begins outside of a paragraph");
TL_IS_132 = Str__literal(L"(very early code)");
TL_IS_133 = Str__literal(L"(early code)");
TL_IS_134 = Str__literal(L"Figures");
TL_IS_135 = Str__literal(L"Figures");
TL_IS_136 = Str__literal(L"unknown bracketed annotation");
TL_IS_137 = Str__literal(L"unknown material after '='");
TL_IS_138 = Str__literal(L"undisplayed");
TL_IS_139 = Str__literal(L"hyperlinked");
TL_IS_140 = Str__literal(L"only 'undisplayed' and/or 'hyperlinked' can precede 'text' here");
TL_IS_141 = Str__literal(L"=");
TL_IS_142 = Str__literal(L"don't understand @command");
TL_IS_143 = Str__literal(L"Purpose used after bar");
TL_IS_144 = Str__literal(L"Interface used after bar");
TL_IS_145 = Str__literal(L"Definitions used after bar");
TL_IS_146 = Str__literal(L"second bar in the same section");
TL_IS_147 = Str__literal(L"enumeration constants can't supply a value");
TL_IS_148 = Str__literal(L"P");
TL_IS_149 = Str__literal(L"S");
TL_IS_150 = Str__literal(L"Footnote Begins Notation");
TL_IS_151 = Str__literal(L"Footnote Ends Notation");
TL_IS_152 = Str__literal(L"Off");
TL_IS_153 = Str__literal(L"ifdef-");
TL_IS_154 = Str__literal(L"ifndef-");
TL_IS_155 = Str__literal(L".");
TL_IS_156 = Str__literal(L"This paragraph is used only if ");
TL_IS_157 = Str__literal(L" and if ");
TL_IS_158 = Str__literal(L" and ");
TL_IS_159 = Str__literal(L" is");
TL_IS_160 = Str__literal(L" are");
TL_IS_161 = Str__literal(L" defined");
TL_IS_162 = Str__literal(L" undefined");
TL_IS_163 = Str__literal(L"enumeration constants must belong to a _FAMILY");
TL_IS_164 = Str__literal(L"this enumeration _FAMILY is unknown");
TL_IS_165 = Str__literal(L"this enumeration _FAMILY already exists");
TL_IS_166 = Str__literal(L"unrecognised interface line");
TL_IS_167 = Str__literal(L"makescript.txt");
TL_IS_168 = Str__literal(L"makescript.txt");
TL_IS_169 = Str__literal(L"gitignorescript.txt");
TL_IS_170 = Str__literal(L"gitignorescript.txt");
TL_IS_171 = Str__literal(L"cover-sheet");
TL_IS_172 = Str__literal(L"Booklet Title");
TL_IS_173 = Str__literal(L"Version Number");
TL_IS_174 = Str__literal(L"Version Number");
TL_IS_175 = Str__literal(L" ");
TL_IS_176 = Str__literal(L"chaptered-index.html");
TL_IS_177 = Str__literal(L"unchaptered-index.html");
TL_IS_178 = Str__literal(L"index.html");
TL_IS_179 = Str__literal(L"index.html");
TL_IS_180 = Str__literal(L"cover-sheet");
TL_IS_181 = Str__literal(L"nav.html");
TL_IS_182 = Str__literal(L"nav.html");
TL_IS_183 = Str__literal(L"Index");
TL_IS_184 = Str__literal(L"index");
TL_IS_185 = Str__literal(L"index.html");
TL_IS_186 = Str__literal(L"Purpose");
TL_IS_187 = Str__literal(L"Booklet Title");
TL_IS_188 = Str__literal(L"Booklet Title");
TL_IS_189 = Str__literal(L"Booklet Title");
TL_IS_190 = Str__literal(L"Booklet Title");
TL_IS_191 = Str__literal(L"Definitions");
TL_IS_192 = Str__literal(L"");
TL_IS_193 = Str__literal(L"");
TL_IS_194 = Str__literal(L"");
TL_IS_195 = Str__literal(L"");
TL_IS_196 = Str__literal(L"this is a duplicate footnote cue");
TL_IS_197 = Str__literal(L"this is a footnote cue within a footnote");
TL_IS_198 = Str__literal(L"this is a duplicate footnote text");
TL_IS_199 = Str__literal(L"define");
TL_IS_200 = Str__literal(L"enum");
TL_IS_201 = Str__literal(L"weavesection");
TL_IS_202 = Str__literal(L"weavesections");
TL_IS_203 = Str__literal(L"weavesectionss");
TL_IS_204 = Str__literal(L"weavesectionsss");
TL_IS_205 = Str__literal(L"nsweavesection");
TL_IS_206 = Str__literal(L"nsweavesections");
TL_IS_207 = Str__literal(L"tweavesection");
TL_IS_208 = Str__literal(L"tweavesections");
TL_IS_209 = Str__literal(L"tweavesectionss");
TL_IS_210 = Str__literal(L"tweavesectionsss");
TL_IS_211 = Str__literal(L"Title");
TL_IS_212 = Str__literal(L"This code is ");
TL_IS_213 = Str__literal(L"never used");
TL_IS_214 = Str__literal(L", ");
TL_IS_215 = Str__literal(L" and ");
TL_IS_216 = Str__literal(L"used in ");
TL_IS_217 = Str__literal(L" (twice)");
TL_IS_218 = Str__literal(L" (three times)");
TL_IS_219 = Str__literal(L" (four times)");
TL_IS_220 = Str__literal(L" (five times)");
TL_IS_221 = Str__literal(L".");
TL_IS_222 = Str__literal(L"The structure ");
TL_IS_223 = Str__literal(L" is private to this section");
TL_IS_224 = Str__literal(L" is accessed in ");
TL_IS_225 = Str__literal(L", ");
TL_IS_226 = Str__literal(L" and here");
TL_IS_227 = Str__literal(L".");
TL_IS_228 = Str__literal(L"The function ");
TL_IS_229 = Str__literal(L" appears nowhere else");
TL_IS_230 = Str__literal(L"none");
TL_IS_231 = Str__literal(L")");
TL_IS_232 = Str__literal(L".");
TL_IS_233 = Str__literal(L" is used in ");
TL_IS_234 = Str__literal(L"), ");
TL_IS_235 = Str__literal(L", ");
TL_IS_236 = Str__literal(L", ");
TL_IS_237 = Str__literal(L" (");
TL_IS_238 = Str__literal(L", ");
TL_IS_239 = Str__literal(L"");
TL_IS_240 = Str__literal(L"");
TL_IS_241 = Str__literal(L"");
TL_IS_242 = Str__literal(L"");
TL_IS_243 = Str__literal(L"");
TL_IS_244 = Str__literal(L"misplaced definition");
TL_IS_245 = Str__literal(L"unknown macro");
TL_IS_246 = Str__literal(L"Dialects");
TL_IS_247 = Str__literal(L"C");
TL_IS_248 = Str__literal(L"Languages");
TL_IS_249 = Str__literal(L"InC");
TL_IS_250 = Str__literal(L"Name");
TL_IS_251 = Str__literal(L"Details");
TL_IS_252 = Str__literal(L"Extension");
TL_IS_253 = Str__literal(L"Line Comment");
TL_IS_254 = Str__literal(L"Whole Line Comment");
TL_IS_255 = Str__literal(L"Multiline Comment Open");
TL_IS_256 = Str__literal(L"Multiline Comment Close");
TL_IS_257 = Str__literal(L"String Literal");
TL_IS_258 = Str__literal(L"String Literal Escape");
TL_IS_259 = Str__literal(L"Character Literal");
TL_IS_260 = Str__literal(L"Character Literal Escape");
TL_IS_261 = Str__literal(L"Binary Literal Prefix");
TL_IS_262 = Str__literal(L"Octal Literal Prefix");
TL_IS_263 = Str__literal(L"Hexadecimal Literal Prefix");
TL_IS_264 = Str__literal(L"Negative Literal Prefix");
TL_IS_265 = Str__literal(L"Shebang");
TL_IS_266 = Str__literal(L"Line Marker");
TL_IS_267 = Str__literal(L"Before Named Paragraph Expansion");
TL_IS_268 = Str__literal(L"After Named Paragraph Expansion");
TL_IS_269 = Str__literal(L"Start Definition");
TL_IS_270 = Str__literal(L"Prolong Definition");
TL_IS_271 = Str__literal(L"End Definition");
TL_IS_272 = Str__literal(L"Start Ifdef");
TL_IS_273 = Str__literal(L"Start Ifndef");
TL_IS_274 = Str__literal(L"End Ifdef");
TL_IS_275 = Str__literal(L"End Ifndef");
TL_IS_276 = Str__literal(L"C-Like");
TL_IS_277 = Str__literal(L"Suppress Disclaimer");
TL_IS_278 = Str__literal(L"Supports Namespaces");
TL_IS_279 = Str__literal(L"Function Declaration Notation");
TL_IS_280 = Str__literal(L"Type Declaration Notation");
TL_IS_281 = Str__literal(L"}");
TL_IS_282 = Str__literal(L"unquoted");
TL_IS_283 = Str__literal(L"{");
TL_IS_284 = Str__literal(L"debug");
TL_IS_285 = Str__literal(L"!string");
TL_IS_286 = Str__literal(L"!function");
TL_IS_287 = Str__literal(L"!definition");
TL_IS_288 = Str__literal(L"!reserved");
TL_IS_289 = Str__literal(L"!element");
TL_IS_290 = Str__literal(L"!identifier");
TL_IS_291 = Str__literal(L"!character");
TL_IS_292 = Str__literal(L"!constant");
TL_IS_293 = Str__literal(L"!plain");
TL_IS_294 = Str__literal(L"!extract");
TL_IS_295 = Str__literal(L"!comment");
TL_IS_296 = Str__literal(L"true");
TL_IS_297 = Str__literal(L"false");
TL_IS_298 = Str__literal(L"both");
TL_IS_299 = Str__literal(L"brackets");
TL_IS_300 = Str__literal(L"characters");
TL_IS_301 = Str__literal(L"coloured");
TL_IS_302 = Str__literal(L"colouring");
TL_IS_303 = Str__literal(L"debug");
TL_IS_304 = Str__literal(L"false");
TL_IS_305 = Str__literal(L"in");
TL_IS_306 = Str__literal(L"instances");
TL_IS_307 = Str__literal(L"keyword");
TL_IS_308 = Str__literal(L"matches");
TL_IS_309 = Str__literal(L"matching");
TL_IS_310 = Str__literal(L"not");
TL_IS_311 = Str__literal(L"of");
TL_IS_312 = Str__literal(L"on");
TL_IS_313 = Str__literal(L"optionally");
TL_IS_314 = Str__literal(L"prefix");
TL_IS_315 = Str__literal(L"runs");
TL_IS_316 = Str__literal(L"spaced");
TL_IS_317 = Str__literal(L"suffix");
TL_IS_318 = Str__literal(L"true");
TL_IS_319 = Str__literal(L"unquoted");
TL_IS_320 = Str__literal(L"Structures");
TL_IS_321 = Str__literal(L"Main::");
TL_IS_322 = Str__literal(L"Tangled output generated by inweb: do not edit");
TL_IS_323 = Str__literal(L"this programming language does not support @d");
TL_IS_324 = Str__literal(L"this programming language does not support multiline @d");
TL_IS_325 = Str__literal(L"Structures");
TL_IS_326 = Str__literal(L"program ended with conditional compilation open");
TL_IS_327 = Str__literal(L"conditional compilation too deeply nested");
TL_IS_328 = Str__literal(L"found #endif without #ifdef or #ifndef");
TL_IS_329 = Str__literal(L"Namespaces");
TL_IS_330 = Str__literal(L"Being internally called, this function mustn't belong to a :: namespace");
TL_IS_331 = Str__literal(L"Being externally called, this function must belong to a :: namespace");
TL_IS_332 = Str__literal(L"quartz");
TL_IS_333 = Str__literal(L"quartz");
TL_IS_334 = Str__literal(L"quartz");
TL_IS_335 = Str__literal(L"like this");
TL_IS_336 = Str__literal(L"most_recent_result");
TL_IS_337 = Str__literal(L"most_recent_result_p");
TL_IS_338 = Str__literal(L"Syntax.preform");
TL_IS_339 = Str__literal(L"Preform Language");
TL_IS_340 = Str__literal(L"Preform Language");
TL_IS_341 = Str__literal(L"");
TL_IS_342 = Str__literal(L"");
TL_IS_343 = Str__literal(L"Code In Code Comments Notation");
TL_IS_344 = Str__literal(L"Code In Commentary Notation");
TL_IS_345 = Str__literal(L"Off");
TL_IS_346 = Str__literal(L"Cross-References Notation");
TL_IS_347 = Str__literal(L"Off");
TL_IS_348 = Str__literal(L"http://");
TL_IS_349 = Str__literal(L"https://");
TL_IS_350 = Str__literal(L"TeX Mathematics Notation");
TL_IS_351 = Str__literal(L"plain");
TL_IS_352 = Str__literal(L".txt");
TL_IS_353 = Str__literal(L"TeX");
TL_IS_354 = Str__literal(L".tex");
TL_IS_355 = Str__literal(L"DVI");
TL_IS_356 = Str__literal(L".tex");
TL_IS_357 = Str__literal(L"PDF");
TL_IS_358 = Str__literal(L".tex");
TL_IS_359 = Str__literal(L"inweb-macros.tex");
TL_IS_360 = Str__literal(L"not");
TL_IS_361 = Str__literal(L"leq");
TL_IS_362 = Str__literal(L"geq");
TL_IS_363 = Str__literal(L"sim");
TL_IS_364 = Str__literal(L"hbox");
TL_IS_365 = Str__literal(L"left");
TL_IS_366 = Str__literal(L"right");
TL_IS_367 = Str__literal(L"Rightarrow");
TL_IS_368 = Str__literal(L"Leftrightarrow");
TL_IS_369 = Str__literal(L"to");
TL_IS_370 = Str__literal(L"rightarrow");
TL_IS_371 = Str__literal(L"longrightarrow");
TL_IS_372 = Str__literal(L"leftarrow");
TL_IS_373 = Str__literal(L"longleftarrow");
TL_IS_374 = Str__literal(L"lbrace");
TL_IS_375 = Str__literal(L"mid");
TL_IS_376 = Str__literal(L"rbrace");
TL_IS_377 = Str__literal(L"cdot");
TL_IS_378 = Str__literal(L"cdots");
TL_IS_379 = Str__literal(L"dots");
TL_IS_380 = Str__literal(L"times");
TL_IS_381 = Str__literal(L"quad");
TL_IS_382 = Str__literal(L"qquad");
TL_IS_383 = Str__literal(L"TeX");
TL_IS_384 = Str__literal(L"neq");
TL_IS_385 = Str__literal(L"noteq");
TL_IS_386 = Str__literal(L"ell");
TL_IS_387 = Str__literal(L"log");
TL_IS_388 = Str__literal(L"exp");
TL_IS_389 = Str__literal(L"sin");
TL_IS_390 = Str__literal(L"cos");
TL_IS_391 = Str__literal(L"tan");
TL_IS_392 = Str__literal(L"top");
TL_IS_393 = Str__literal(L"Alpha");
TL_IS_394 = Str__literal(L"Beta");
TL_IS_395 = Str__literal(L"Gamma");
TL_IS_396 = Str__literal(L"Delta");
TL_IS_397 = Str__literal(L"Epsilon");
TL_IS_398 = Str__literal(L"Zeta");
TL_IS_399 = Str__literal(L"Eta");
TL_IS_400 = Str__literal(L"Theta");
TL_IS_401 = Str__literal(L"Iota");
TL_IS_402 = Str__literal(L"Kappa");
TL_IS_403 = Str__literal(L"Lambda");
TL_IS_404 = Str__literal(L"Mu");
TL_IS_405 = Str__literal(L"Nu");
TL_IS_406 = Str__literal(L"Xi");
TL_IS_407 = Str__literal(L"Omicron");
TL_IS_408 = Str__literal(L"Pi");
TL_IS_409 = Str__literal(L"Rho");
TL_IS_410 = Str__literal(L"Varsigma");
TL_IS_411 = Str__literal(L"Sigma");
TL_IS_412 = Str__literal(L"Tau");
TL_IS_413 = Str__literal(L"Upsilon");
TL_IS_414 = Str__literal(L"Phi");
TL_IS_415 = Str__literal(L"Chi");
TL_IS_416 = Str__literal(L"Psi");
TL_IS_417 = Str__literal(L"Omega");
TL_IS_418 = Str__literal(L"alpha");
TL_IS_419 = Str__literal(L"beta");
TL_IS_420 = Str__literal(L"gamma");
TL_IS_421 = Str__literal(L"delta");
TL_IS_422 = Str__literal(L"epsilon");
TL_IS_423 = Str__literal(L"zeta");
TL_IS_424 = Str__literal(L"eta");
TL_IS_425 = Str__literal(L"theta");
TL_IS_426 = Str__literal(L"iota");
TL_IS_427 = Str__literal(L"kappa");
TL_IS_428 = Str__literal(L"lambda");
TL_IS_429 = Str__literal(L"mu");
TL_IS_430 = Str__literal(L"nu");
TL_IS_431 = Str__literal(L"xi");
TL_IS_432 = Str__literal(L"omicron");
TL_IS_433 = Str__literal(L"pi");
TL_IS_434 = Str__literal(L"rho");
TL_IS_435 = Str__literal(L"varsigma");
TL_IS_436 = Str__literal(L"sigma");
TL_IS_437 = Str__literal(L"tau");
TL_IS_438 = Str__literal(L"upsilon");
TL_IS_439 = Str__literal(L"phi");
TL_IS_440 = Str__literal(L"chi");
TL_IS_441 = Str__literal(L"psi");
TL_IS_442 = Str__literal(L"omega");
TL_IS_443 = Str__literal(L"exists");
TL_IS_444 = Str__literal(L"in");
TL_IS_445 = Str__literal(L"forall");
TL_IS_446 = Str__literal(L"cap");
TL_IS_447 = Str__literal(L"emptyset");
TL_IS_448 = Str__literal(L"subseteq");
TL_IS_449 = Str__literal(L"land");
TL_IS_450 = Str__literal(L"lor");
TL_IS_451 = Str__literal(L"lnot");
TL_IS_452 = Str__literal(L"sum");
TL_IS_453 = Str__literal(L"prod");
TL_IS_454 = Str__literal(L"n");
TL_IS_455 = Str__literal(L"t");
TL_IS_456 = Str__literal(L"exists");
TL_IS_457 = Str__literal(L"forall");
TL_IS_458 = Str__literal(L"HTML");
TL_IS_459 = Str__literal(L".html");
TL_IS_460 = Str__literal(L"ePub");
TL_IS_461 = Str__literal(L".html");
TL_IS_462 = Str__literal(L"template");
TL_IS_463 = Str__literal(L"inweb.css");
TL_IS_464 = Str__literal(L"TeX Mathematics Plugin");
TL_IS_465 = Str__literal(L"None");
TL_IS_466 = Str__literal(L"");
TL_IS_467 = Str__literal(L"template");
TL_IS_468 = Str__literal(L"crumbs.gif");
TL_IS_469 = Str__literal(L"Title");
TL_IS_470 = Str__literal(L"Short Title");
TL_IS_471 = Str__literal(L"Short Title");
TL_IS_472 = Str__literal(L"index.html");
TL_IS_473 = Str__literal(L"enum");
TL_IS_474 = Str__literal(L"Cross-References Notation");
TL_IS_475 = Str__literal(L"Off");
TL_IS_476 = Str__literal(L"http://");
TL_IS_477 = Str__literal(L"https://");
TL_IS_478 = Str__literal(L"Popups");
TL_IS_479 = Str__literal(L"external");
TL_IS_480 = Str__literal(L"internal");
TL_IS_481 = Str__literal(L"Footnotes Plugin");
TL_IS_482 = Str__literal(L"None");
TL_IS_483 = Str__literal(L"Footnotes Plugin");
TL_IS_484 = Str__literal(L"None");
TL_IS_485 = Str__literal(L"Footnotes Plugin");
TL_IS_486 = Str__literal(L"None");
TL_IS_487 = Str__literal(L"Figures");
TL_IS_488 = Str__literal(L"405");
TL_IS_489 = Str__literal(L"720");
TL_IS_490 = Str__literal(L"Embedding");
TL_IS_491 = Str__literal(L"Embedding");
TL_IS_492 = Str__literal(L"This is not a supported service");
TL_IS_493 = Str__literal(L"Content ID");
TL_IS_494 = Str__literal(L"Content Width");
TL_IS_495 = Str__literal(L"Content Height");
TL_IS_496 = Str__literal(L"");
TL_IS_497 = Str__literal(L"Booklet Title");
TL_IS_498 = Str__literal(L"template");
TL_IS_499 = Str__literal(L"Title");
TL_IS_500 = Str__literal(L"inweb.css");
TL_IS_501 = Str__literal(L"Plugins");
TL_IS_502 = Str__literal(L"Plugins");
TL_IS_503 = Str__literal(L"");
TL_IS_504 = Str__literal(L" ");
TL_IS_505 = Str__literal(L"all");
TL_IS_506 = Str__literal(L"platform-settings.mk");
TL_IS_507 = Str__literal(L"intest");
TL_IS_508 = Str__literal(L"all");
TL_IS_509 = Str__literal(L"gitignorescript.txt");
TL_IS_510 = Str__literal(L"version");
TL_IS_511 = Str__literal(L"purpose");
TL_IS_512 = Str__literal(L"var");
TL_IS_513 = Str__literal(L"\n");
TL_IS_514 = Str__literal(L"version");
TL_IS_515 = Str__literal(L"purpose");
TL_IS_516 = Str__literal(L"var");
TL_IS_517 = Str__literal(L"Version Number");
TL_IS_518 = Str__literal(L"Purpose");
TL_IS_519 = Str__literal(L"Build Date");
TL_IS_520 = Str__literal(L"Version Number");
TL_IS_521 = Str__literal(L"inform6");
TL_IS_522 = Str__literal(L"header.h");
TL_IS_523 = Str__literal(L"(manifest).txt");
TL_IS_524 = Str__literal(L"README.txt");
TL_IS_525 = Str__literal(L"README.md");
TL_IS_526 = Str__literal(L"web");
TL_IS_527 = Str__literal(L"module");
TL_IS_528 = Str__literal(L".inweb");
TL_IS_529 = Str__literal(L".inweb");
TL_IS_530 = Str__literal(L"Can't find this cross-reference");
TL_IS_531 = Str__literal(L"Multiple cross-references might be meant here");
}