23830 lines
824 KiB
C
23830 lines
824 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.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 c_structure_MT 33
|
|
#define chapter_MT 34
|
|
#define colouring_rule_MT 35
|
|
#define enumeration_set_MT 36
|
|
#define function_MT 37
|
|
#define hash_table_entry_MT 38
|
|
#define hash_table_entry_usage_MT 39
|
|
#define colouring_language_block_MT 40
|
|
#define macro_MT 41
|
|
#define macro_tokens_MT 42
|
|
#define macro_usage_MT 43
|
|
#define nonterminal_variable_MT 44
|
|
#define para_macro_MT 45
|
|
#define paragraph_MT 46
|
|
#define paragraph_tagging_MT 47
|
|
#define preform_nonterminal_MT 48
|
|
#define programming_language_MT 49
|
|
#define reserved_word_MT 50
|
|
#define section_MT 51
|
|
#define source_line_array_MT 52
|
|
#define structure_element_MT 53
|
|
#define tangle_target_MT 54
|
|
#define tex_results_MT 55
|
|
#define text_literal_MT 56
|
|
#define theme_tag_MT 57
|
|
#define weave_format_MT 58
|
|
#define weave_pattern_MT 59
|
|
#define weave_target_MT 60
|
|
#define web_MT 61
|
|
#define writeme_asset_MT 62
|
|
#define NO_MODE 0
|
|
#define ANALYSE_MODE 1
|
|
#define TANGLE_MODE 2
|
|
#define WEAVE_MODE 3
|
|
#define TRANSLATE_MODE 4
|
|
#define SWARM_OFF_SWM 0
|
|
#define SWARM_INDEX_SWM 1
|
|
#define SWARM_CHAPTERS_SWM 2
|
|
#define SWARM_SECTIONS_SWM 3
|
|
#define VERBOSE_CLSW 6
|
|
#define IMPORT_FROM_CLSW 7
|
|
#define LANGUAGES_CLSG 2
|
|
#define LANGUAGE_CLSW 8
|
|
#define LANGUAGES_CLSW 9
|
|
#define SHOW_LANGUAGES_CLSW 10
|
|
#define ANALYSIS_CLSG 3
|
|
#define CATALOGUE_CLSW 11
|
|
#define FUNCTIONS_CLSW 12
|
|
#define STRUCTURES_CLSW 13
|
|
#define ADVANCE_CLSW 14
|
|
#define GITIGNORE_CLSW 15
|
|
#define MAKEFILE_CLSW 16
|
|
#define WRITEME_CLSW 17
|
|
#define ADVANCE_FILE_CLSW 18
|
|
#define PROTOTYPE_CLSW 19
|
|
#define SCAN_CLSW 20
|
|
#define WEAVING_CLSG 4
|
|
#define WEAVE_CLSW 21
|
|
#define WEAVE_INTO_CLSW 22
|
|
#define WEAVE_TO_CLSW 23
|
|
#define SEQUENTIAL_CLSW 24
|
|
#define OPEN_CLSW 25
|
|
#define WEAVE_AS_CLSW 26
|
|
#define WEAVE_TAG_CLSW 27
|
|
#define WEAVE_DOCS_CLSW 28
|
|
#define BREADCRUMB_CLSW 29
|
|
#define NAVIGATION_CLSW 30
|
|
#define TANGLING_CLSG 5
|
|
#define TANGLE_CLSW 31
|
|
#define TANGLE_TO_CLSW 32
|
|
#define LOOP_WITHIN_TANGLE(C, S, T)\
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)\
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)\
|
|
if (S->sect_target == T)\
|
|
for (source_line *L = S->first_line; L; L = L->next_line)
|
|
#define NO_LCAT 0
|
|
#define BAR_LCAT 1
|
|
#define BEGIN_CODE_LCAT 2
|
|
#define BEGIN_DEFINITION_LCAT 3
|
|
#define C_LIBRARY_INCLUDE_LCAT 4
|
|
#define CHAPTER_HEADING_LCAT 5
|
|
#define CODE_BODY_LCAT 6
|
|
#define COMMAND_LCAT 7
|
|
#define COMMENT_BODY_LCAT 8
|
|
#define CONT_DEFINITION_LCAT 9
|
|
#define DEFINITIONS_LCAT 10
|
|
#define HEADING_START_LCAT 11
|
|
#define INTERFACE_BODY_LCAT 12
|
|
#define INTERFACE_LCAT 13
|
|
#define MACRO_DEFINITION_LCAT 14
|
|
#define PARAGRAPH_START_LCAT 15
|
|
#define PREFORM_GRAMMAR_LCAT 16
|
|
#define PREFORM_LCAT 17
|
|
#define PURPOSE_BODY_LCAT 18
|
|
#define PURPOSE_LCAT 19
|
|
#define SECTION_HEADING_LCAT 20
|
|
#define SOURCE_DISPLAY_LCAT 21
|
|
#define TEXT_EXTRACT_LCAT 22
|
|
#define TYPEDEF_LCAT 23
|
|
#define NO_CMD 0
|
|
#define PAGEBREAK_CMD 1
|
|
#define GRAMMAR_INDEX_CMD 2
|
|
#define FIGURE_CMD 3
|
|
#define TAG_CMD 4
|
|
#define ORDINARY_WEIGHT 0 /* an ordinary paragraph has this "weight" */
|
|
#define SUBHEADING_WEIGHT 1 /* a heading paragraph */
|
|
#define BASIC_SECTIONCAT 1
|
|
#define STRUCTURES_SECTIONCAT 2
|
|
#define FUNCTIONS_SECTIONCAT 3
|
|
#define ELEMENT_ACCESS_USAGE 0x00000001 /* C-like languages: access via |->| or |.| operators to structure element */
|
|
#define FCALL_USAGE 0x00000002 /* C-like languages: function call made using brackets, |name(args)| */
|
|
#define PREFORM_IN_CODE_USAGE 0x00000004 /* InC only: use of a Preform nonterminal as a C "constant" */
|
|
#define PREFORM_IN_GRAMMAR_USAGE 0x00000008 /* InC only: ditto, but within Preform production rather than C code */
|
|
#define MISC_USAGE 0x00000010 /* any other appearance as an identifier */
|
|
#define ANY_USAGE 0x7fffffff /* any of the above */
|
|
#define HASH_TAB_SIZE 1000 /* the possible hash codes are 0 up to this minus 1 */
|
|
#define NUMBER_HASH 0 /* literal decimal integers, and no other words, have this hash code */
|
|
#define WEAVE_FIRST_HALF 1
|
|
#define WEAVE_SECOND_HALF 2
|
|
#define IN_SECOND_HALF 4
|
|
#define MAX_TEMPLATE_LINES 256 /* maximum number of lines in template */
|
|
#define CI_STACK_CAPACITY 8 /* maximum recursion of chapter/section iteration */
|
|
#define TRACE_CI_EXECUTION FALSE /* set true for debugging */
|
|
#define CHAPTER_LEVEL 1
|
|
#define SECTION_LEVEL 2
|
|
#define REGULAR_MATERIAL 1
|
|
#define MACRO_MATERIAL 2
|
|
#define DEFINITION_MATERIAL 3
|
|
#define CODE_MATERIAL 4
|
|
#define LOOP_OVER_PARAGRAPHS(C, S, T, P)\
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)\
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)\
|
|
if (S->sect_target == T)\
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
#define WHOLE_LINE_CRULE_RUN -1 /* This block applies to the whole snippet being coloured */
|
|
#define CHARACTERS_CRULE_RUN -2 /* This block applies to each character in turn */
|
|
#define INSTANCES_CRULE_RUN -3 /* This block applies to each instance in turn */
|
|
#define NOT_A_RULE_PREFIX 1 /* this isn't a prefix rule */
|
|
#define UNSPACED_RULE_PREFIX 2 /* for |prefix P| */
|
|
#define SPACED_RULE_PREFIX 3 /* for |spaced prefix P| */
|
|
#define OPTIONALLY_SPACED_RULE_PREFIX 4 /* for |optionally spaced prefix P| */
|
|
#define UNSPACED_RULE_SUFFIX 5 /* for |suffix P| */
|
|
#define SPACED_RULE_SUFFIX 6 /* for |spaced suffix P| */
|
|
#define OPTIONALLY_SPACED_RULE_SUFFIX 7 /* for |optionally spaced suffix P| */
|
|
#define DEFINITION_COLOUR 'd'
|
|
#define FUNCTION_COLOUR 'f'
|
|
#define RESERVED_COLOUR 'r'
|
|
#define ELEMENT_COLOUR 'e'
|
|
#define IDENTIFIER_COLOUR 'i'
|
|
#define CHAR_LITERAL_COLOUR 'c'
|
|
#define CONSTANT_COLOUR 'n'
|
|
#define STRING_COLOUR 's'
|
|
#define PLAIN_COLOUR 'p'
|
|
#define EXTRACT_COLOUR 'x'
|
|
#define COMMENT_COLOUR '!'
|
|
#define NOT_A_COLOUR ' '
|
|
#define UNQUOTED_COLOUR '_'
|
|
#define FURTHER_PARSING_PAR_MTID 2
|
|
#define SUBCATEGORISE_LINE_PAR_MTID 3
|
|
#define PARSE_COMMENT_TAN_MTID 4
|
|
#define SHEBANG_TAN_MTID 5
|
|
#define SUPPRESS_DISCLAIMER_TAN_MTID 6
|
|
#define ADDITIONAL_EARLY_MATTER_TAN_MTID 7
|
|
#define START_DEFN_TAN_MTID 8
|
|
#define PROLONG_DEFN_TAN_MTID 9
|
|
#define END_DEFN_TAN_MTID 10
|
|
#define ADDITIONAL_PREDECLARATIONS_TAN_MTID 11
|
|
#define SUPPRESS_EXPANSION_TAN_MTID 12
|
|
#define TANGLE_COMMAND_TAN_MTID 13
|
|
#define WILL_TANGLE_EXTRA_LINE_TAN_MTID 14
|
|
#define TANGLE_EXTRA_LINE_TAN_MTID 15
|
|
#define INSERT_LINE_MARKER_TAN_MTID 16
|
|
#define BEFORE_MACRO_EXPANSION_TAN_MTID 17
|
|
#define AFTER_MACRO_EXPANSION_TAN_MTID 18
|
|
#define OPEN_IFDEF_TAN_MTID 19
|
|
#define CLOSE_IFDEF_TAN_MTID 20
|
|
#define COMMENT_TAN_MTID 21
|
|
#define TANGLE_CODE_UNUSUALLY_TAN_MTID 22
|
|
#define GNABEHS_TAN_MTID 23
|
|
#define ADDITIONAL_TANGLING_TAN_MTID 24
|
|
#define BEGIN_WEAVE_WEA_MTID 25
|
|
#define SKIP_IN_WEAVING_WEA_MTID 26
|
|
#define RESET_SYNTAX_COLOURING_WEA_MTID 27
|
|
#define SYNTAX_COLOUR_WEA_MTID 28
|
|
#define WEAVE_CODE_LINE_WEA_MTID 29
|
|
#define NOTIFY_NEW_TAG_WEA_MTID 30
|
|
#define CATALOGUE_ANA_MTID 31
|
|
#define EARLY_PREWEAVE_ANALYSIS_ANA_MTID 32
|
|
#define LATE_PREWEAVE_ANALYSIS_ANA_MTID 33
|
|
#define SHARE_ELEMENT_ANA_MTID 34
|
|
#define UNSPACED_RULE_PREFIX 2 /* for |prefix P| */
|
|
#define SPACED_RULE_PREFIX 3 /* for |spaced prefix P| */
|
|
#define OPTIONALLY_SPACED_RULE_PREFIX 4 /* for |optionally spaced prefix P| */
|
|
#define UNSPACED_RULE_SUFFIX 5 /* for |suffix P| */
|
|
#define SPACED_RULE_SUFFIX 6 /* for |spaced suffix P| */
|
|
#define OPTIONALLY_SPACED_RULE_SUFFIX 7 /* for |optionally spaced suffix P| */
|
|
#define MAX_CONDITIONAL_COMPILATION_STACK 8
|
|
#define MAX_ARG_LINES 32 /* maximum number of lines over which a function's header can extend */
|
|
#define NOT_A_NONTERMINAL -4
|
|
#define A_FLEXIBLE_NONTERMINAL -3
|
|
#define A_VORACIOUS_NONTERMINAL -2
|
|
#define A_GRAMMAR_NONTERMINAL -1
|
|
#define INFINITE_WORD_COUNT 1000000000
|
|
#define BEGIN_WEAVING_FOR_MTID 35
|
|
#define END_WEAVING_FOR_MTID 36
|
|
#define TOP_FOR_MTID 37
|
|
#define TOC_FOR_MTID 38
|
|
#define CHAPTER_TP_FOR_MTID 39
|
|
#define SUBHEADING_FOR_MTID 40
|
|
#define PARAGRAPH_HEADING_FOR_MTID 41
|
|
#define SOURCE_CODE_FOR_MTID 42
|
|
#define INLINE_CODE_FOR_MTID 43
|
|
#define DISPLAY_LINE_FOR_MTID 44
|
|
#define ITEM_FOR_MTID 45
|
|
#define BAR_FOR_MTID 46
|
|
#define FIGURE_FOR_MTID 47
|
|
#define PARA_MACRO_FOR_MTID 48
|
|
#define PAGEBREAK_FOR_MTID 49
|
|
#define BLANK_LINE_FOR_MTID 50
|
|
#define AFTER_DEFINITIONS_FOR_MTID 51
|
|
#define CHANGE_MATERIAL_FOR_MTID 52
|
|
#define CHANGE_COLOUR_FOR_MTID 53
|
|
#define COMMENTARY_TEXT_FOR_MTID 54
|
|
#define PRESERVE_MATH_MODE_FOR_MTID 55
|
|
#define PREFORM_DOCUMENT_FOR_MTID 56
|
|
#define ENDNOTE_FOR_MTID 57
|
|
#define LOCALE_FOR_MTID 58
|
|
#define TAIL_FOR_MTID 59
|
|
#define POST_PROCESS_POS_MTID 60
|
|
#define POST_PROCESS_REPORT_POS_MTID 61
|
|
#define INDEX_PDFS_POS_MTID 62
|
|
#define POST_PROCESS_SUBSTITUTE_POS_MTID 63
|
|
#define HTML_OUT 0 /* write position in HTML file is currently outside of p, pre, li */
|
|
#define HTML_IN_P 1 /* write position in HTML file is currently outside p */
|
|
#define HTML_IN_PRE 2 /* write position in HTML file is currently outside pre */
|
|
#define HTML_IN_LI 3 /* write position in HTML file is currently outside li */
|
|
#define NO_DEFINED_CLSW_VALUES 33
|
|
#define NO_DEFINED_DA_VALUES 4
|
|
#define NO_DEFINED_MT_VALUES 63
|
|
#define NO_DEFINED_MREASON_VALUES 5
|
|
#define NO_DEFINED_MTID_VALUES 63
|
|
#define NO_DEFINED_CLSF_VALUES 5
|
|
#define NO_DEFINED_CLSG_VALUES 6
|
|
#define NO_DEFINED_SEMVERPART_VALUES 3
|
|
#define NO_DEFINED_END_VALUES 4
|
|
#define NO_DEFINED_SYNTAX_VALUES 2
|
|
#define NO_DEFINED_MOM_VALUES 4
|
|
#define NO_DEFINED_MODE_VALUES 5
|
|
#define NO_DEFINED_SWM_VALUES 4
|
|
#define NO_DEFINED_LCAT_VALUES 24
|
|
#define NO_DEFINED_CMD_VALUES 5
|
|
#define NO_DEFINED_SECTIONCAT_VALUES 3
|
|
#define NO_DEFINED_MATERIAL_VALUES 4
|
|
#line 41 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
typedef struct debugging_aspect {
|
|
struct text_stream *hyphenated_name; /* e.g., "memory-usage" */
|
|
struct text_stream *negated_name; /* e.g., "no-memory-usage" */
|
|
struct text_stream *unhyphenated_name; /* e.g., "memory usage" */
|
|
int on_or_off; /* whether or not active when writing to debugging log */
|
|
int alternate; /* whether or not active when writing in trace mode */
|
|
MEMORY_MANAGEMENT
|
|
} debugging_aspect;
|
|
#line 87 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
typedef struct allocation_status_structure {
|
|
/* actually needed for allocation purposes: */
|
|
int objects_allocated; /* total number of objects (or arrays) ever allocated */
|
|
void *first_in_memory; /* head of doubly linked list */
|
|
void *last_in_memory; /* tail of doubly linked list */
|
|
|
|
/* used only to provide statistics for the debugging log: */
|
|
char *name_of_type; /* e.g., |"lexicon_entry_MT"| */
|
|
int bytes_allocated; /* total allocation for this type of object, not counting overhead */
|
|
int objects_count; /* total number currently in existence (i.e., undeleted) */
|
|
int no_allocated_together; /* number of objects in each array of this type of object */
|
|
} allocation_status_structure;
|
|
#line 169 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
typedef struct memblock_header {
|
|
int block_number;
|
|
struct memblock_header *next;
|
|
char *the_memory;
|
|
} memblock_header;
|
|
#line 251 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
typedef struct memory_frame {
|
|
int integrity_check; /* this should always contain the |INTEGRITY_NUMBER| */
|
|
struct memory_frame *next_frame; /* next frame in the list of memory frames */
|
|
int mem_type; /* type of object stored in this frame */
|
|
int allocation_id; /* allocation ID number of object stored in this frame */
|
|
} memory_frame;
|
|
#line 700 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
typedef struct string_storage_area {
|
|
char *storage_at;
|
|
int first_free_byte;
|
|
MEMORY_MANAGEMENT
|
|
} string_storage_area;
|
|
#line 879 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
typedef struct general_pointer {
|
|
void *pointer_to_data;
|
|
int run_time_type_code;
|
|
} general_pointer;
|
|
#line 233 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
typedef struct text_stream {
|
|
int stream_flags; /* bitmap of the |*_STRF| values above */
|
|
FILE *write_to_file; /* for an open stream, exactly one of these is |NULL| */
|
|
struct HTML_file_state *as_HTML; /* relevant only to the |HTML::| section */
|
|
wchar_t *write_to_memory;
|
|
struct filename *file_written; /* ditto */
|
|
int chars_written; /* number of characters sent, counting |\n| as 1 */
|
|
int chars_capacity; /* maximum number the stream can accept without claiming more resources */
|
|
struct text_stream *stream_continues; /* if one memory stream is extended by another */
|
|
} text_stream;
|
|
#line 36 "inweb/foundation-module/Chapter 2/Methods.w"
|
|
typedef struct method_set {
|
|
struct method *first_method;
|
|
MEMORY_MANAGEMENT
|
|
} method_set;
|
|
#line 78 "inweb/foundation-module/Chapter 2/Methods.w"
|
|
typedef struct method {
|
|
int method_id;
|
|
void *method_function;
|
|
struct method *next_method;
|
|
MEMORY_MANAGEMENT
|
|
} method;
|
|
#line 23 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
typedef struct linked_list_item {
|
|
void *item_contents;
|
|
struct linked_list_item *next_list_item;
|
|
} linked_list_item;
|
|
#line 15 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
typedef struct linked_list {
|
|
struct linked_list_item *first_list_item;
|
|
struct linked_list_item *last_list_item;
|
|
int linked_list_length;
|
|
struct linked_list_item early_items[NO_LL_EARLY_ITEMS];
|
|
MEMORY_MANAGEMENT
|
|
} linked_list;
|
|
#line 13 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
typedef struct dictionary {
|
|
int textual; /* values are texts? */
|
|
int no_entries; /* total number of key-value pairs currently stored here */
|
|
int hash_table_size; /* size of array... */
|
|
struct dict_entry *hash_table; /* ...of linked lists of dictionary entries */
|
|
MEMORY_MANAGEMENT
|
|
} dictionary;
|
|
#line 21 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
typedef struct dict_entry {
|
|
int vacant; /* a "vacant" entry is not currently used to store a k-v pair */
|
|
struct text_stream *key; /* for non-vacant entries only: the key text */
|
|
void *value; /* for non-vacant entries only: the value, some kind of pointer */
|
|
struct dict_entry *next_in_entry;
|
|
} dict_entry;
|
|
#line 38 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
typedef struct command_line_switch {
|
|
int switch_id;
|
|
struct text_stream *switch_name; /* e.g., |no-verbose| */
|
|
struct text_stream *switch_sort_name; /* e.g., |verbose| */
|
|
struct text_stream *help_text;
|
|
int valency; /* 1 for bare, 2 for one argument follows */
|
|
int form; /* one of the |*_CLSF| values above */
|
|
int switch_group; /* one of the |*_CLSG| valyes above */
|
|
int active_by_default; /* relevant only for booleans */
|
|
struct command_line_switch *negates; /* relevant only for booleans */
|
|
MEMORY_MANAGEMENT
|
|
} command_line_switch;
|
|
#line 171 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
typedef struct clf_reader_state {
|
|
void *state;
|
|
void (*f)(int, int, text_stream *, void *);
|
|
void (*g)(int, text_stream *, void *);
|
|
int subs;
|
|
int nrt;
|
|
} clf_reader_state;
|
|
#line 38 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
typedef struct pathname {
|
|
struct text_stream *intermediate;
|
|
struct pathname *pathname_of_parent;
|
|
int known_to_exist; /* corresponds to a directory in the filing system */
|
|
MEMORY_MANAGEMENT
|
|
} pathname;
|
|
#line 14 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
typedef struct filename {
|
|
struct pathname *pathname_of_location;
|
|
struct text_stream *leafname;
|
|
MEMORY_MANAGEMENT
|
|
} filename;
|
|
#line 8 "inweb/foundation-module/Chapter 3/Directories.w"
|
|
typedef struct scan_directory {
|
|
void *directory_handle;
|
|
char directory_name_written_out[4*MAX_FILENAME_LENGTH];
|
|
MEMORY_MANAGEMENT
|
|
} scan_directory;
|
|
#line 159 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
typedef struct string_position {
|
|
struct text_stream *S;
|
|
int index;
|
|
} string_position;
|
|
#line 208 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
typedef struct unicode_file_buffer {
|
|
char unicode_feed_buffer[32]; /* holds a single escape such as "[unicode 3106]" */
|
|
int ufb_counter; /* position in the unicode feed buffer */
|
|
} unicode_file_buffer;
|
|
#line 26 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
typedef struct text_file_position {
|
|
struct filename *text_file_filename;
|
|
FILE *handle_when_open;
|
|
struct unicode_file_buffer ufb;
|
|
int line_count; /* counting from 1 */
|
|
int line_position;
|
|
int skip_terminator;
|
|
int actively_scanning; /* whether we are still interested in the rest of the file */
|
|
} text_file_position;
|
|
#line 42 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
typedef struct match_trie {
|
|
int match_character; /* or one of the special cases above */
|
|
wchar_t group_characters[MAX_TRIE_GROUP_SIZE+1];
|
|
wchar_t *match_outcome;
|
|
struct match_trie *on_success;
|
|
struct match_trie *next;
|
|
} match_trie;
|
|
#line 284 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
typedef struct match_avinue {
|
|
struct match_trie *the_trie;
|
|
struct match_avinue *next;
|
|
} match_avinue;
|
|
#line 109 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
typedef struct match_position {
|
|
int tpos; /* position within text being matched */
|
|
int ppos; /* position within pattern */
|
|
int bc; /* count of bracketed subexpressions so far begun */
|
|
int bl; /* bracket indentation level */
|
|
int bracket_nesting[MAX_BRACKETED_SUBEXPRESSIONS];
|
|
/* which subexpression numbers (0, 1, 2, 3) correspond to which nesting */
|
|
int brackets_start[MAX_BRACKETED_SUBEXPRESSIONS], brackets_end[MAX_BRACKETED_SUBEXPRESSIONS];
|
|
/* positions in text being matched, inclusive */
|
|
} match_position;
|
|
#line 126 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
typedef struct match_result {
|
|
wchar_t match_text_storage[MATCH_TEXT_INITIAL_ALLOCATION];
|
|
struct text_stream match_text_struct;
|
|
} match_result;
|
|
#line 130 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
typedef struct match_results {
|
|
int no_matched_texts;
|
|
struct match_result exp_storage[MAX_BRACKETED_SUBEXPRESSIONS];
|
|
struct text_stream *exp[MAX_BRACKETED_SUBEXPRESSIONS];
|
|
} match_results;
|
|
#line 20 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
typedef struct HTML_file_state {
|
|
int XHTML_flag; /* writing strict XHTML for use in epubs */
|
|
struct lifo_stack *tag_stack; /* of |HTML_tag|: those currently open */
|
|
int CSS_included;
|
|
int JS_included;
|
|
MEMORY_MANAGEMENT
|
|
} HTML_file_state;
|
|
#line 43 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
typedef struct HTML_tag {
|
|
char *tag_name;
|
|
int tag_xref;
|
|
MEMORY_MANAGEMENT
|
|
} HTML_tag;
|
|
#line 583 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
typedef struct colour_translation {
|
|
wchar_t *chip_name;
|
|
wchar_t *html_colour;
|
|
} colour_translation;
|
|
#line 23 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
typedef struct ebook {
|
|
struct linked_list *metadata_list; /* of |ebook_datum|: DCMI-standard bibliographic data */
|
|
char *prefix; /* to apply to the page leafnames */
|
|
struct filename *CSS_file_throughout; /* where to find a CSS file to be used for all volumes */
|
|
|
|
struct filename *eventual_epub; /* filename of the final |*.epub| to be made */
|
|
struct pathname *holder; /* directory to put the ingredients into */
|
|
struct pathname *OEBPS_path; /* subdirectory which mysteriously has to be called |OEBPS| */
|
|
|
|
struct linked_list *ebook_volume_list; /* of |ebook_volume| */
|
|
struct ebook_volume *current_volume; /* the one to which chapters are now being added */
|
|
|
|
struct linked_list *ebook_chapter_list; /* of |ebook_chapter| */
|
|
struct ebook_chapter *current_chapter; /* the one to which pages are now being added */
|
|
|
|
struct linked_list *ebook_page_list; /* of |book_page| */
|
|
struct linked_list *ebook_image_list; /* of |ebook_image| */
|
|
MEMORY_MANAGEMENT
|
|
} ebook;
|
|
#line 48 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
typedef struct ebook_datum {
|
|
struct text_stream *key;
|
|
struct text_stream *value;
|
|
MEMORY_MANAGEMENT
|
|
} ebook_datum;
|
|
#line 57 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
typedef struct ebook_volume {
|
|
struct text_stream *volume_title;
|
|
struct ebook_page *volume_starts; /* on which page the volume starts */
|
|
struct filename *CSS_file; /* where to find the CSS file to be included */
|
|
MEMORY_MANAGEMENT
|
|
} ebook_volume;
|
|
#line 64 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
typedef struct ebook_chapter {
|
|
struct text_stream *chapter_title;
|
|
struct ebook_volume *in_volume; /* to which volume this chapter belongs */
|
|
struct ebook_page *chapter_starts; /* on which page the chapter starts */
|
|
struct linked_list *ebook_mark_list; /* of |ebook_mark|: for when multiple navigable points exist within this */
|
|
struct text_stream *start_URL;
|
|
MEMORY_MANAGEMENT
|
|
} ebook_chapter;
|
|
#line 77 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
typedef struct ebook_page {
|
|
struct text_stream *page_title;
|
|
struct text_stream *page_type;
|
|
struct text_stream *page_ID;
|
|
|
|
struct filename *relative_URL; /* eventual URL of this page within the ebook */
|
|
|
|
struct ebook_volume *in_volume; /* to which volume this page belongs */
|
|
struct ebook_chapter *in_chapter; /* to which chapter this page belongs */
|
|
|
|
int nav_entry_written; /* keep track of what we've written to the navigation tree */
|
|
MEMORY_MANAGEMENT
|
|
} ebook_page;
|
|
#line 91 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
typedef struct ebook_mark {
|
|
struct text_stream *mark_text;
|
|
struct text_stream *mark_URL;
|
|
MEMORY_MANAGEMENT
|
|
} ebook_mark;
|
|
#line 97 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
typedef struct ebook_image {
|
|
struct text_stream *image_ID;
|
|
struct filename *relative_URL; /* eventual URL of this image within the ebook */
|
|
MEMORY_MANAGEMENT
|
|
} ebook_image;
|
|
#line 61 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
typedef struct semantic_version_number {
|
|
int version_numbers[SEMVER_NUMBER_DEPTH];
|
|
struct linked_list *prerelease_segments; /* of |text_stream| */
|
|
struct text_stream *build_metadata;
|
|
} semantic_version_number;
|
|
#line 67 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
typedef struct semantic_version_number_holder {
|
|
struct semantic_version_number version;
|
|
MEMORY_MANAGEMENT
|
|
} semantic_version_number_holder;
|
|
#line 24 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
typedef struct range_end {
|
|
int end_type;
|
|
struct semantic_version_number end_value;
|
|
} range_end;
|
|
#line 29 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
typedef struct semver_range {
|
|
struct range_end lower;
|
|
struct range_end upper;
|
|
MEMORY_MANAGEMENT
|
|
} semver_range;
|
|
#line 27 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
typedef struct web_md {
|
|
struct pathname *path_to_web; /* relative to the current working directory */
|
|
struct filename *single_file; /* relative to the current working directory */
|
|
struct linked_list *bibliographic_data; /* of |web_bibliographic_datum| */
|
|
struct semantic_version_number version_number; /* as deduced from bibliographic data */
|
|
int default_syntax; /* which version syntax the sections will have */
|
|
int chaptered; /* has the author explicitly divided it into named chapters? */
|
|
struct text_stream *main_language_name; /* in which most of the sections are written */
|
|
|
|
struct module *as_module; /* the root of a small dependency graph */
|
|
|
|
struct filename *contents_filename; /* or |NULL| for a single-file web */
|
|
struct linked_list *tangle_target_names; /* of |text_stream| */
|
|
struct linked_list *header_filenames; /* of |filename| */
|
|
|
|
struct linked_list *chapters_md; /* of |chapter_md| */
|
|
struct linked_list *sections_md; /* of |section_md| */
|
|
MEMORY_MANAGEMENT
|
|
} web_md;
|
|
#line 50 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
typedef struct chapter_md {
|
|
struct text_stream *ch_range; /* e.g., |P| for Preliminaries, |7| for Chapter 7, |C| for Appendix C */
|
|
struct text_stream *ch_title; /* e.g., "Chapter 3: Fresh Water Fish" */
|
|
struct text_stream *rubric; /* optional; without double-quotation marks */
|
|
|
|
struct text_stream *ch_language_name; /* in which most of the sections are written */
|
|
|
|
int imported; /* from a different web? */
|
|
|
|
struct linked_list *sections_md; /* of |section_md| */
|
|
MEMORY_MANAGEMENT
|
|
} chapter_md;
|
|
#line 66 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
typedef struct section_md {
|
|
struct text_stream *sect_title; /* e.g., "Program Control" */
|
|
int using_syntax; /* which syntax the web is written in */
|
|
int is_a_singleton; /* is this the only section in its entire web? */
|
|
|
|
struct filename *source_file_for_section;
|
|
|
|
struct text_stream *tag_name;
|
|
struct text_stream *sect_independent_language;
|
|
struct text_stream *sect_language_name;
|
|
struct text_stream *titling_line_to_insert;
|
|
MEMORY_MANAGEMENT
|
|
} section_md;
|
|
#line 151 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
typedef struct reader_state {
|
|
struct web_md *Wm;
|
|
struct filename *contents_filename;
|
|
int in_biblio;
|
|
int in_purpose; /* Reading the bit just after the new chapter? */
|
|
struct chapter_md *chapter_being_scanned;
|
|
struct text_stream *chapter_folder_name; /* Where sections in the current chapter live */
|
|
struct text_stream *titling_line_to_insert; /* To be inserted automagically */
|
|
struct pathname *path_to; /* Where web material is being read from */
|
|
struct module *reading_from;
|
|
struct module_search *import_from; /* Where imported webs are */
|
|
struct pathname *path_to_inweb;
|
|
int scan_verbosely;
|
|
int including_modules;
|
|
int main_web_not_module; /* Reading the original web, or an included one? */
|
|
int halt_at_at; /* Used for reading contents pages of single-file webs */
|
|
int halted; /* Set when such a halt has occurred */
|
|
int section_count;
|
|
struct section_md *last_section;
|
|
} reader_state;
|
|
#line 11 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
typedef struct web_bibliographic_datum {
|
|
struct text_stream *key;
|
|
struct text_stream *value;
|
|
int declaration_permitted; /* is the contents page of the web allowed to set this? */
|
|
int declaration_mandatory; /* is it positively required to? */
|
|
int on_or_off; /* boolean: which we handle as the string "On" or "Off" */
|
|
struct web_bibliographic_datum *alias;
|
|
MEMORY_MANAGEMENT
|
|
} web_bibliographic_datum;
|
|
#line 19 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
typedef struct module {
|
|
struct pathname *module_location;
|
|
struct text_stream *module_name;
|
|
struct linked_list *dependencies; /* of |module|: which other modules does this need? */
|
|
struct text_stream *module_tag;
|
|
int origin_marker; /* one of the |*_MOM| values above */
|
|
struct linked_list *sections_md; /* of |section_md|: just the ones in this module */
|
|
MEMORY_MANAGEMENT
|
|
} module;
|
|
#line 71 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
typedef struct module_search {
|
|
struct pathname *path_to_search;
|
|
MEMORY_MANAGEMENT
|
|
} module_search;
|
|
#line 21 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
typedef struct build_file_data {
|
|
struct text_stream *prerelease_text;
|
|
struct text_stream *build_code;
|
|
struct text_stream *build_date;
|
|
} build_file_data;
|
|
#line 11 "inweb/Chapter 1/Configuration.w"
|
|
typedef struct inweb_instructions {
|
|
int inweb_mode; /* our main mode of operation: one of the |*_MODE| constants */
|
|
struct pathname *chosen_web; /* project folder relative to cwd */
|
|
struct filename *chosen_file; /* or, single file relative to cwd */
|
|
struct text_stream *chosen_range; /* which subset of this web we apply to (often, all of it) */
|
|
int chosen_range_actually_chosen; /* rather than being a default choice */
|
|
|
|
int swarm_mode; /* relevant to weaving only: one of the |*_SWARM| constants */
|
|
struct text_stream *tag_setting; /* |-weave-tag X|: weave, but only the material tagged X */
|
|
struct text_stream *weave_format; /* |-weave-as X|: for example, |-weave-as TeX| */
|
|
struct text_stream *weave_pattern; /* |-weave-to X|: for example, |-weave-to HTML| */
|
|
int weave_docs; /* |-docs|: for GitHub Pages */
|
|
|
|
int show_languages_switch; /* |-show-languages|: print list of available PLs */
|
|
int catalogue_switch; /* |-catalogue|: print catalogue of sections */
|
|
int functions_switch; /* |-functions|: print catalogue of functions within sections */
|
|
int structures_switch; /* |-structures|: print catalogue of structures within sections */
|
|
int advance_switch; /* |-advance-build|: advance build file for web */
|
|
int open_pdf_switch; /* |-open-pdf|: open any woven PDF in the OS once it is made */
|
|
int scan_switch; /* |-scan|: simply show the syntactic scan of the source */
|
|
struct filename *weave_to_setting; /* |-weave-to X|: the pathname X, if supplied */
|
|
struct pathname *weave_into_setting; /* |-weave-into X|: the pathname X, if supplied */
|
|
int sequential; /* give the sections sequential sigils */
|
|
struct filename *tangle_setting; /* |-tangle-to X|: the pathname X, if supplied */
|
|
struct filename *makefile_setting; /* |-makefile X|: the filename X, if supplied */
|
|
struct filename *gitignore_setting; /* |-gitignore X|: the filename X, if supplied */
|
|
struct filename *advance_setting; /* |-advance-build-file X|: advance build file X */
|
|
struct filename *writeme_setting; /* |-write-me X|: advance build file X */
|
|
struct filename *prototype_setting; /* |-prototype X|: the pathname X, if supplied */
|
|
struct filename *navigation_setting; /* |-navigation X|: the filename X, if supplied */
|
|
struct linked_list *breadcrumb_setting; /* of |breadcrumb_request| */
|
|
int verbose_switch; /* |-verbose|: print names of files read to stdout */
|
|
int targets; /* used only for parsing */
|
|
|
|
struct pathname *import_setting; /* |-import X|: where to find imported webs */
|
|
} inweb_instructions;
|
|
#line 48 "inweb/Chapter 1/Configuration.w"
|
|
typedef struct breadcrumb_request {
|
|
struct text_stream *breadcrumb_text;
|
|
struct text_stream *breadcrumb_link;
|
|
MEMORY_MANAGEMENT
|
|
} breadcrumb_request;
|
|
#line 11 "inweb/Chapter 1/Patterns.w"
|
|
typedef struct weave_pattern {
|
|
struct text_stream *pattern_name; /* such as |HTML| */
|
|
struct pathname *pattern_location; /* the directory */
|
|
struct weave_pattern *based_on; /* inherit from which other pattern? */
|
|
|
|
struct weave_format *pattern_format; /* such as |DVI|: the desired final format */
|
|
struct linked_list *payloads; /* of |text_stream|: leafnames of associated files */
|
|
struct linked_list *up_payloads; /* of |text_stream|: leafnames of associated files */
|
|
|
|
struct text_stream *tex_command; /* shell command to use for |tex| */
|
|
struct text_stream *pdftex_command; /* shell command to use for |pdftex| */
|
|
struct text_stream *open_command; /* shell command to use for |open| */
|
|
|
|
int embed_CSS; /* embed CSS directly into any HTML files made? */
|
|
int hierarchical; /* weave as one part of a collection of woven webs */
|
|
int show_abbrevs; /* show section range abbreviations in the weave? */
|
|
int number_sections; /* insert section numbers into the weave? */
|
|
struct text_stream *default_range; /* for example, |sections| */
|
|
|
|
struct web *patterned_for; /* the web which caused this to be read in */
|
|
MEMORY_MANAGEMENT
|
|
} weave_pattern;
|
|
#line 28 "inweb/Chapter 2/The Reader.w"
|
|
typedef struct web {
|
|
struct web_md *md;
|
|
struct linked_list *chapters; /* of |chapter| (including Sections, Preliminaries, etc.) */
|
|
|
|
int no_lines; /* total lines in literate source, excluding contents */
|
|
int no_paragraphs; /* this will be at least 1 */
|
|
|
|
struct programming_language *main_language; /* in which most of the sections are written */
|
|
struct linked_list *tangle_targets; /* of |tangle_target| */
|
|
|
|
struct linked_list *headers; /* of |filename|: additional header files */
|
|
int analysed; /* has this been scanned for function usage and such? */
|
|
struct linked_list *c_structures; /* of |c_structure|: used only for C-like languages */
|
|
|
|
struct ebook *as_ebook; /* when being woven to an ebook */
|
|
struct pathname *redirect_weaves_to; /* ditto */
|
|
|
|
MEMORY_MANAGEMENT
|
|
} web;
|
|
#line 51 "inweb/Chapter 2/The Reader.w"
|
|
typedef struct chapter {
|
|
struct chapter_md *md;
|
|
struct web *owning_web;
|
|
struct linked_list *sections; /* of |section| */
|
|
|
|
struct weave_target *ch_weave; /* |NULL| unless this chapter produces a weave of its own */
|
|
int titling_line_inserted; /* has an interleaved chapter heading been added yet? */
|
|
struct programming_language *ch_language; /* in which this chapter is written */
|
|
MEMORY_MANAGEMENT
|
|
} chapter;
|
|
#line 65 "inweb/Chapter 2/The Reader.w"
|
|
typedef struct section {
|
|
struct section_md *md;
|
|
struct web *owning_web;
|
|
struct chapter *owning_chapter;
|
|
|
|
struct text_stream *sect_namespace; /* e.g., "Text::Languages::" */
|
|
struct text_stream *sect_purpose; /* e.g., "To manage the zoo, and feed all penguins" */
|
|
struct text_stream *sect_range; /* e.g., "9/tfto" */
|
|
int barred; /* if version 1 syntax, contains a dividing bar? */
|
|
struct programming_language *sect_language; /* in which this section is written */
|
|
struct tangle_target *sect_target; /* |NULL| unless this section produces a tangle of its own */
|
|
struct weave_target *sect_weave; /* |NULL| unless this section produces a weave of its own */
|
|
|
|
int sect_extent; /* total number of lines in this section */
|
|
struct source_line *first_line; /* for efficiency's sake not held as a |linked_list|, */
|
|
struct source_line *last_line; /* but that's what it is, all the same */
|
|
|
|
int sect_paragraphs; /* total number of paragraphs in this section */
|
|
struct linked_list *paragraphs; /* of |paragraph|: the content of this section */
|
|
struct theme_tag *tag_with; /* automatically tag paras in this section thus */
|
|
|
|
struct linked_list *macros; /* of |para_macro|: those defined in this section */
|
|
|
|
int scratch_flag; /* temporary workspace */
|
|
int paused_until_at; /* ignore the top half of the file, until the first |@| sign */
|
|
int printed_number; /* temporary again: sometimes used in weaving */
|
|
MEMORY_MANAGEMENT
|
|
} section;
|
|
#line 250 "inweb/Chapter 3/The Analyser.w"
|
|
typedef struct hash_table {
|
|
struct linked_list *analysis_hash[HASH_TAB_SIZE]; /* of |hash_table_entry| */
|
|
int analysis_hash_initialised; /* when we start up, array's contents are undefined */
|
|
} hash_table;
|
|
#line 384 "inweb/Chapter 2/The Reader.w"
|
|
typedef struct tangle_target {
|
|
struct programming_language *tangle_language; /* common to the entire contents */
|
|
struct hash_table symbols; /* a table of identifiable names in this program */
|
|
MEMORY_MANAGEMENT
|
|
} tangle_target;
|
|
#line 20 "inweb/Chapter 2/Line Categories.w"
|
|
typedef struct source_line {
|
|
struct text_stream *text; /* the text as read in */
|
|
struct text_stream *text_operand; /* meaning depends on category */
|
|
struct text_stream *text_operand2; /* meaning depends on category */
|
|
|
|
int category; /* what sort of line this is: an |*_LCAT| value */
|
|
int command_code; /* used only for |COMMAND_LCAT| lines: a |*_CMD| value */
|
|
int default_defn; /* used only for |BEGIN_DEFINITION_LCAT| lines */
|
|
struct programming_language *colour_as; /* used only for |TEXT_EXTRACT_LCAT| lines */
|
|
int is_commentary; /* flag */
|
|
struct function *function_defined; /* if any C-like function is defined on this line */
|
|
struct preform_nonterminal *preform_nonterminal_defined; /* similarly */
|
|
int suppress_tangling; /* if e.g., lines are tangled out of order */
|
|
int interface_line_identified; /* only relevant during parsing of Interface lines */
|
|
|
|
struct text_file_position source; /* which file this was read in from, if any */
|
|
|
|
struct section *owning_section; /* for interleaved title lines, it's the one about to start */
|
|
struct source_line *next_line; /* within the owning section's linked list */
|
|
struct paragraph *owning_paragraph; /* for lines falling under paragraphs; |NULL| if not */
|
|
} source_line;
|
|
#line 610 "inweb/Chapter 2/The Parser.w"
|
|
typedef struct paragraph {
|
|
int above_bar; /* placed above the dividing bar in its section (in Version 1 syntax) */
|
|
int placed_early; /* should appear early in the tangled code */
|
|
int placed_very_early; /* should appear very early in the tangled code */
|
|
struct text_stream *ornament; /* a "P" for a pilcrow or "S" for section-marker */
|
|
struct text_stream *paragraph_number; /* used in combination with the ornament */
|
|
int next_child_number; /* used when working out paragraph numbers */
|
|
struct paragraph *parent_paragraph; /* ditto */
|
|
|
|
int weight; /* typographic prominence: one of the |*_WEIGHT| values */
|
|
int starts_on_new_page; /* relevant for weaving to TeX only, of course */
|
|
|
|
struct para_macro *defines_macro; /* there can only be one */
|
|
struct linked_list *functions; /* of |function|: those defined in this para */
|
|
struct linked_list *structures; /* of |c_structure|: similarly */
|
|
struct linked_list *taggings; /* of |paragraph_tagging| */
|
|
struct source_line *first_line_in_paragraph;
|
|
struct section *under_section;
|
|
MEMORY_MANAGEMENT
|
|
} paragraph;
|
|
#line 8 "inweb/Chapter 2/Paragraph Macros.w"
|
|
typedef struct para_macro {
|
|
struct text_stream *macro_name; /* usually long, like "Create a paragraph macro here" */
|
|
struct paragraph *defining_paragraph; /* as printed in small type after the name in any usage */
|
|
struct source_line *defn_start; /* it ends at the end of its defining paragraph */
|
|
struct linked_list *macro_usages; /* of |macro_usage|: only computed for weaves */
|
|
MEMORY_MANAGEMENT
|
|
} para_macro;
|
|
#line 10 "inweb/Chapter 2/Tags.w"
|
|
typedef struct theme_tag {
|
|
struct text_stream *tag_name;
|
|
int ifdef_positive;
|
|
struct text_stream *ifdef_symbol;
|
|
MEMORY_MANAGEMENT
|
|
} theme_tag;
|
|
#line 50 "inweb/Chapter 2/Tags.w"
|
|
typedef struct paragraph_tagging {
|
|
struct theme_tag *the_tag;
|
|
struct text_stream *caption;
|
|
MEMORY_MANAGEMENT
|
|
} paragraph_tagging;
|
|
#line 14 "inweb/Chapter 2/Enumerated Constants.w"
|
|
typedef struct enumeration_set {
|
|
struct text_stream *postfix;
|
|
struct text_stream *stub;
|
|
int first_value;
|
|
int next_free_value;
|
|
struct source_line *last_observed_at;
|
|
MEMORY_MANAGEMENT
|
|
} enumeration_set;
|
|
#line 61 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
typedef struct macro_usage {
|
|
struct paragraph *used_in_paragraph;
|
|
int multiplicity; /* for example, 2 if it's used twice in this paragraph */
|
|
MEMORY_MANAGEMENT
|
|
} macro_usage;
|
|
#line 258 "inweb/Chapter 3/The Analyser.w"
|
|
typedef struct hash_table_entry {
|
|
text_stream *hash_key;
|
|
int reserved_word; /* in the language currently being woven, that is */
|
|
struct linked_list *usages; /* of |hash_table_entry_usage| */
|
|
MEMORY_MANAGEMENT
|
|
} hash_table_entry;
|
|
#line 331 "inweb/Chapter 3/The Analyser.w"
|
|
typedef struct hash_table_entry_usage {
|
|
struct paragraph *usage_recorded_at;
|
|
int form_of_usage; /* bitmap of the |*_USAGE| constants defined above */
|
|
MEMORY_MANAGEMENT
|
|
} hash_table_entry_usage;
|
|
#line 70 "inweb/Chapter 3/The Swarm.w"
|
|
typedef struct weave_target {
|
|
struct web *weave_web; /* which web we weave */
|
|
struct text_stream *weave_range; /* which parts of the web in this weave */
|
|
struct theme_tag *theme_match; /* pick out only paragraphs with this theme */
|
|
struct text_stream *booklet_title;
|
|
struct weave_pattern *pattern; /* which pattern is to be followed */
|
|
struct filename *weave_to; /* where to put it */
|
|
struct weave_format *format; /* plain text, say, or HTML */
|
|
struct text_stream *cover_sheet_to_use; /* leafname of the copy, or |NULL| for no cover */
|
|
void *post_processing_results; /* optional typesetting diagnostics after running through */
|
|
int self_contained; /* make a self-contained file if possible */
|
|
int docs_mode; /* make as part of a |-weave-docs| run */
|
|
struct linked_list *breadcrumbs; /* non-standard breadcrumb trail, if any */
|
|
struct filename *navigation; /* navigation links, or |NULL| if not supplied */
|
|
MEMORY_MANAGEMENT
|
|
} weave_target;
|
|
#line 33 "inweb/Chapter 3/The Indexer.w"
|
|
typedef struct cover_sheet_state {
|
|
struct text_stream *WEAVE_COVER_TO;
|
|
int halves; /* a bitmap of the above values */
|
|
struct weave_target *target;
|
|
} cover_sheet_state;
|
|
#line 164 "inweb/Chapter 3/The Indexer.w"
|
|
typedef struct contents_processor {
|
|
text_stream *tlines[MAX_TEMPLATE_LINES];
|
|
int no_tlines;
|
|
int repeat_stack_level[CI_STACK_CAPACITY];
|
|
linked_list_item *repeat_stack_variable[CI_STACK_CAPACITY];
|
|
linked_list_item *repeat_stack_threshold[CI_STACK_CAPACITY];
|
|
int repeat_stack_startpos[CI_STACK_CAPACITY];
|
|
int stack_pointer; /* And this is our stack pointer for tracking of loops */
|
|
text_stream *restrict_to_range;
|
|
web *nav_web;
|
|
weave_pattern *nav_pattern;
|
|
pathname *nav_path;
|
|
filename *nav_file;
|
|
linked_list *crumbs;
|
|
int docs_mode;
|
|
} contents_processor;
|
|
#line 84 "inweb/Chapter 3/The Weaver.w"
|
|
typedef struct weaver_state {
|
|
int kind_of_material; /* one of the enumerated |*_MATERIAL| constants above */
|
|
int line_break_pending; /* insert a line break before the next woven line? */
|
|
int next_heading_without_vertical_skip;
|
|
int show_section_toc_soon; /* is a table of contents for the section imminent? */
|
|
int horizontal_rule_just_drawn;
|
|
int in_run_of_definitions;
|
|
struct section *last_extract_from;
|
|
struct paragraph *last_endnoted_para;
|
|
int substantive_comment;
|
|
struct text_stream *chaptermark;
|
|
struct text_stream *sectionmark;
|
|
} weaver_state;
|
|
#line 75 "inweb/Chapter 4/Programming Languages.w"
|
|
typedef struct programming_language {
|
|
text_stream *language_name; /* identifies it: see above */
|
|
|
|
/* then a great many fields set directly in the definition file: */
|
|
text_stream *file_extension; /* by default output to a file whose name has this extension */
|
|
text_stream *language_details; /* brief explanation of what language is */
|
|
int supports_namespaces;
|
|
text_stream *line_comment;
|
|
text_stream *whole_line_comment;
|
|
text_stream *multiline_comment_open;
|
|
text_stream *multiline_comment_close;
|
|
text_stream *string_literal;
|
|
text_stream *string_literal_escape;
|
|
text_stream *character_literal;
|
|
text_stream *character_literal_escape;
|
|
text_stream *binary_literal_prefix;
|
|
text_stream *octal_literal_prefix;
|
|
text_stream *hexadecimal_literal_prefix;
|
|
text_stream *negative_literal_prefix;
|
|
text_stream *shebang;
|
|
text_stream *line_marker;
|
|
text_stream *before_macro_expansion;
|
|
text_stream *after_macro_expansion;
|
|
text_stream *start_definition;
|
|
text_stream *prolong_definition;
|
|
text_stream *end_definition;
|
|
text_stream *start_ifdef;
|
|
text_stream *end_ifdef;
|
|
text_stream *start_ifndef;
|
|
text_stream *end_ifndef;
|
|
int suppress_disclaimer;
|
|
int C_like; /* languages with this set have access to extra features */
|
|
|
|
struct linked_list *reserved_words; /* of |reserved_word| */
|
|
struct hash_table built_in_keywords;
|
|
struct colouring_language_block *program; /* algorithm for syntax colouring */
|
|
METHOD_CALLS
|
|
MEMORY_MANAGEMENT
|
|
} programming_language;
|
|
#line 122 "inweb/Chapter 4/Programming Languages.w"
|
|
typedef struct language_reader_state {
|
|
struct programming_language *defining;
|
|
struct colouring_language_block *current_block;
|
|
} language_reader_state;
|
|
#line 335 "inweb/Chapter 4/Programming Languages.w"
|
|
typedef struct colouring_language_block {
|
|
struct linked_list *rules; /* of |colouring_rule| */
|
|
struct colouring_language_block *parent; /* or |NULL| for the topmost one */
|
|
int run; /* one of the |*_CRULE_RUN| values, or else a colour */
|
|
struct text_stream *run_instance; /* used only for |INSTANCES_CRULE_RUN| */
|
|
MEMORY_MANAGEMENT
|
|
} colouring_language_block;
|
|
#line 369 "inweb/Chapter 4/Programming Languages.w"
|
|
typedef struct colouring_rule {
|
|
/* the premiss: */
|
|
int match_colour; /* for |colour C|, or else |NOT_A_COLOUR| */
|
|
int match_keyword_of_colour; /* for |keyword C|, or else |NOT_A_COLOUR| */
|
|
struct text_stream *match_text; /* or length 0 to mean "anything" */
|
|
int match_prefix; /* one of the |*_RULE_PREFIX| values above */
|
|
|
|
/* the conclusion: */
|
|
struct colouring_language_block *execute_block; /* or |NULL|, in which case... */
|
|
int set_to_colour; /* ...paint the snippet in this colour */
|
|
int set_prefix_to_colour; /* ...also paint this (same for suffix) */
|
|
int debug; /* ...or print debugging text to console */
|
|
|
|
/* workspace during painting */
|
|
int fix_position; /* where the prefix or suffix started */
|
|
MEMORY_MANAGEMENT
|
|
} colouring_rule;
|
|
#line 469 "inweb/Chapter 4/Programming Languages.w"
|
|
typedef struct reserved_word {
|
|
struct text_stream *word;
|
|
int colour;
|
|
MEMORY_MANAGEMENT
|
|
} reserved_word;
|
|
#line 122 "inweb/Chapter 4/C-Like Languages.w"
|
|
typedef struct c_structure {
|
|
struct text_stream *structure_name;
|
|
int tangled; /* whether the structure definition has been tangled out */
|
|
struct source_line *typedef_begins; /* opening line of |typedef| */
|
|
struct source_line *typedef_ends; /* closing line, where |}| appears */
|
|
struct linked_list *incorporates; /* of |c_structure| */
|
|
struct linked_list *elements; /* of |structure_element| */
|
|
struct c_structure *next_cst_alphabetically;
|
|
MEMORY_MANAGEMENT
|
|
} c_structure;
|
|
#line 251 "inweb/Chapter 4/C-Like Languages.w"
|
|
typedef struct structure_element {
|
|
struct text_stream *element_name;
|
|
struct source_line *element_created_at;
|
|
int allow_sharing;
|
|
MEMORY_MANAGEMENT
|
|
} structure_element;
|
|
#line 396 "inweb/Chapter 4/C-Like Languages.w"
|
|
typedef struct function {
|
|
struct text_stream *function_name; /* e.g., |"cultivate"| */
|
|
struct text_stream *function_type; /* e.g., |"tree *"| */
|
|
struct text_stream *function_arguments; /* e.g., |"int rainfall)"|: note |)| */
|
|
struct source_line *function_header_at; /* where the first line of the header begins */
|
|
int within_namespace; /* written using InC namespace dividers */
|
|
int called_from_other_sections;
|
|
int call_freely;
|
|
int no_conditionals;
|
|
struct source_line *within_conditionals[MAX_CONDITIONAL_COMPILATION_STACK];
|
|
MEMORY_MANAGEMENT
|
|
} function;
|
|
#line 104 "inweb/Chapter 4/InC Support.w"
|
|
typedef struct preform_nonterminal {
|
|
struct text_stream *nt_name; /* e.g., |<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 function */
|
|
int voracious; /* a voracious nonterminal: see "The English Syntax of Inform" */
|
|
int min_word_count; /* for internals only */
|
|
int max_word_count;
|
|
int takes_pointer_result; /* right-hand formula defines |*XP|, not |*X| */
|
|
struct source_line *where_defined;
|
|
struct preform_nonterminal *next_pnt_alphabetically;
|
|
MEMORY_MANAGEMENT
|
|
} preform_nonterminal;
|
|
#line 279 "inweb/Chapter 4/InC Support.w"
|
|
typedef struct nonterminal_variable {
|
|
struct text_stream *ntv_name; /* e.g., |"num"| */
|
|
struct text_stream *ntv_type; /* e.g., |"int"| */
|
|
struct text_stream *ntv_identifier; /* e.g., |"num_NTMV"| */
|
|
struct source_line *first_mention; /* first usage */
|
|
MEMORY_MANAGEMENT
|
|
} nonterminal_variable;
|
|
#line 331 "inweb/Chapter 4/InC Support.w"
|
|
typedef struct text_literal {
|
|
struct text_stream *tl_identifier;
|
|
struct text_stream *tl_content;
|
|
MEMORY_MANAGEMENT
|
|
} text_literal;
|
|
#line 11 "inweb/Chapter 5/Weave Formats.w"
|
|
typedef struct weave_format {
|
|
struct text_stream *format_name;
|
|
struct text_stream *woven_extension;
|
|
METHOD_CALLS
|
|
MEMORY_MANAGEMENT
|
|
} weave_format;
|
|
#line 377 "inweb/Chapter 5/HTML Formats.w"
|
|
typedef struct HTML_figure_state {
|
|
struct text_stream *OUT;
|
|
struct programming_language *colour_as;
|
|
struct weave_target *wv;
|
|
struct hash_table *keywords;
|
|
} HTML_figure_state;
|
|
#line 42 "inweb/Chapter 5/Running Through TeX.w"
|
|
typedef struct tex_results {
|
|
int overfull_hbox_count;
|
|
int tex_error_count;
|
|
int page_count;
|
|
int pdf_size;
|
|
struct filename *PDF_filename;
|
|
MEMORY_MANAGEMENT
|
|
} tex_results;
|
|
#line 9 "inweb/Chapter 6/Makefiles.w"
|
|
typedef struct makefile_state {
|
|
struct web *for_web;
|
|
struct text_stream to_makefile;
|
|
struct text_stream *repeat_block; /* a "repeatblock" body being scanned */
|
|
int inside_block; /* scanning a "repeatblock" into that text? */
|
|
int last_line_was_blank; /* used to suppress runs of multiple blank lines */
|
|
int allow_commands; /* permit the prototype to use special commands */
|
|
int repeat_scope; /* during a repeat, either |MAKEFILE_TOOL_MOM| or |MAKEFILE_MODULE_MOM| */
|
|
struct text_stream *repeat_tag;
|
|
struct dictionary *tools_dictionary;
|
|
struct dictionary *webs_dictionary;
|
|
struct dictionary *modules_dictionary;
|
|
struct module_search *search_path;
|
|
} makefile_state;
|
|
#line 9 "inweb/Chapter 6/Git Support.w"
|
|
typedef struct gitignore_state {
|
|
struct web *for_web;
|
|
struct text_stream to_gitignore;
|
|
int last_line_was_blank; /* used to suppress runs of multiple blank lines */
|
|
} gitignore_state;
|
|
#line 12 "inweb/Chapter 6/Readme Writeme.w"
|
|
typedef struct write_state {
|
|
struct text_stream *OUT;
|
|
struct linked_list *known_macros; /* of |macro| */
|
|
struct macro *current_definition;
|
|
struct macro_tokens *stack_frame;
|
|
} write_state;
|
|
#line 91 "inweb/Chapter 6/Readme Writeme.w"
|
|
typedef struct macro_tokens {
|
|
struct macro *bound_to;
|
|
struct text_stream *pars[8];
|
|
int no_pars;
|
|
struct macro_tokens *down;
|
|
MEMORY_MANAGEMENT
|
|
} macro_tokens;
|
|
#line 76 "inweb/Chapter 6/Readme Writeme.w"
|
|
typedef struct macro {
|
|
struct text_stream *name;
|
|
struct text_stream *content;
|
|
struct macro_tokens tokens;
|
|
MEMORY_MANAGEMENT
|
|
} macro;
|
|
#line 254 "inweb/Chapter 6/Readme Writeme.w"
|
|
typedef struct writeme_asset {
|
|
struct text_stream *name;
|
|
struct web_md *if_web;
|
|
struct text_stream *date;
|
|
struct text_stream *version;
|
|
int next_is_version;
|
|
MEMORY_MANAGEMENT
|
|
} writeme_asset;
|
|
typedef long int pointer_sized_int;
|
|
typedef void (*writer_function)(text_stream *, char *, void *);
|
|
typedef void (*writer_function_I)(text_stream *, char *, int);
|
|
typedef void (*log_function)(text_stream *, void *);
|
|
typedef void (*log_function_I)(text_stream *, int);
|
|
typedef char string[MAX_STRING_LENGTH+1];
|
|
#line 88 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
void Foundation__start(void) ;
|
|
#line 167 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
void Foundation__end(void) ;
|
|
#ifdef PLATFORM_POSIX
|
|
#line 90 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
char * Platform__getenv(const char *name) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_LINUX
|
|
#ifdef PLATFORM_POSIX
|
|
#line 103 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__where_am_i(wchar_t *p, size_t length) ;
|
|
#endif /* PLATFORM_LINUX */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_UNIX
|
|
#ifdef PLATFORM_POSIX
|
|
#line 154 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__where_am_i(wchar_t *p, size_t length) ;
|
|
#endif /* PLATFORM_UNIX */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_ANDROID
|
|
#ifdef PLATFORM_POSIX
|
|
#line 161 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__where_am_i(wchar_t *p, size_t length) ;
|
|
#endif /* PLATFORM_ANDROID */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifndef PLATFORM_MACOS
|
|
#ifdef PLATFORM_POSIX
|
|
#line 174 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
int Platform__system(const char *cmd) ;
|
|
#endif /* PLATFORM_MACOS */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_MACOS
|
|
#ifdef PLATFORM_POSIX
|
|
#line 204 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
int Platform__system(const char *cmd) ;
|
|
#endif /* PLATFORM_MACOS */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 221 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
int Platform__mkdir(char *transcoded_pathname) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 229 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void * Platform__opendir(char *path_to_folder) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 234 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
int Platform__readdir(void *folder, char *path_to_folder, char *leafname) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 249 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__closedir(void *folder) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 262 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
time_t Platform__never_time(void) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 266 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
time_t Platform__timestamp(char *transcoded_filename) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 280 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__rsync(char *transcoded_source, char *transcoded_dest) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 289 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__quote_text(char *quoted, char *raw, int terminate) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 305 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__sleep(int seconds) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_MACOS
|
|
#ifdef PLATFORM_POSIX
|
|
#line 321 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__notification(text_stream *text, int happy) ;
|
|
#endif /* PLATFORM_MACOS */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifndef PLATFORM_MACOS
|
|
#ifdef PLATFORM_POSIX
|
|
#line 334 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__notification(text_stream *text, int happy) ;
|
|
#endif /* PLATFORM_MACOS */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 346 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
int Platform__create_thread(foundation_thread *pt, const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 351 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
int Platform__join_thread(pthread_t pt, void** rv) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 355 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__init_thread(pthread_attr_t* pa, size_t size) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 360 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
size_t Platform__get_thread_stack_size(pthread_attr_t* pa) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 43 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
int Platform__Windows_isdigit(int c) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 74 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
void Platform__where_am_i(wchar_t *p, size_t length) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 126 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
int Platform__mkdir(char *transcoded_pathname) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 134 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
void * Platform__opendir(char *path_to_folder) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 139 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
int Platform__readdir(void *folder, char *path_to_folder, char *leafname) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 156 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
void Platform__closedir(void *folder) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 173 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
void Platform__notification(text_stream *text, int happy) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 191 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
unsigned long __stdcall Platform__Win32_Thread_Func(unsigned long param) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 198 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
int Platform__create_thread(foundation_thread *pt, const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 213 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
int Platform__join_thread(pthread_t pt, void** rv) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 217 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
void Platform__init_thread(pthread_attr_t* pa, size_t size) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 220 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
size_t Platform__get_thread_stack_size(pthread_attr_t* pa) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 232 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
time_t Platform__never_time(void) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#ifdef PLATFORM_WINDOWS
|
|
#line 236 "inweb/foundation-module/Chapter 1/Windows Platform.w"
|
|
time_t Platform__timestamp(char *transcoded_filename) ;
|
|
#endif /* PLATFORM_WINDOWS */
|
|
#line 64 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__declare_aspect(int a, wchar_t *name, int def, int alt) ;
|
|
#line 111 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
filename * Log__get_debug_log_filename(void) ;
|
|
#line 115 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__set_debug_log_filename(filename *F) ;
|
|
#line 119 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
int Log__open(void) ;
|
|
#line 131 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
int Log__open_alternative(filename *F, text_stream *at) ;
|
|
#line 140 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__close(void) ;
|
|
#line 155 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__new_phase(char *p, text_stream *q) ;
|
|
#line 164 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__new_stage(text_stream *p) ;
|
|
#line 178 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
int Log__aspect_switched_on(int aspect) ;
|
|
#line 185 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__set_aspect(int aspect, int state) ;
|
|
#line 192 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__set_all_aspects(int new_state) ;
|
|
#line 210 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
int Log__set_aspect_from_command_line(text_stream *name, int give_error) ;
|
|
#line 241 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__tracing_on(int starred, text_stream *heading) ;
|
|
#line 261 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__show_debugging_settings_with_state(int state) ;
|
|
#line 274 "inweb/foundation-module/Chapter 2/Debugging Log.w"
|
|
void Log__show_debugging_contents(void) ;
|
|
#line 107 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__start(void) ;
|
|
#line 185 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__allocate_another_block(void) ;
|
|
#line 230 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__free(void) ;
|
|
#line 275 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__check_memory_integrity(void) ;
|
|
#line 286 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__debug_memory_frames(int from, int to) ;
|
|
#line 303 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void * Memory__allocate(int mem_type, int extent) ;
|
|
#line 576 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__name_fundamental_reasons(void) ;
|
|
#line 589 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__reason_name(int r, char *reason) ;
|
|
#line 594 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
char * Memory__description_of_reason(int r) ;
|
|
#line 619 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void * Memory__I7_calloc(int how_many, int size_in_bytes, int reason) ;
|
|
#line 622 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void * Memory__I7_malloc(int size_in_bytes, int reason) ;
|
|
#line 629 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void * Memory__I7_alloc(int N, int S, int R) ;
|
|
#line 680 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__I7_free(void *pointer, int R, int bytes_freed) ;
|
|
#line 690 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__I7_array_free(void *pointer, int R, int num_cells, size_t cell_size) ;
|
|
#line 713 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
char * Memory__new_string(char *from) ;
|
|
#line 733 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__free_ssas(void) ;
|
|
#line 743 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
int Memory__log_usage(int total) ;
|
|
#line 762 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void Memory__log_statistics(void) ;
|
|
#line 832 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
int Memory__compare_usage(const void *ent1, const void *ent2) ;
|
|
#line 842 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
int Memory__proportion(int bytes, int total) ;
|
|
#line 849 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
void * Memory__paranoid_calloc(size_t N, size_t S) ;
|
|
#line 884 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
general_pointer Memory__store_gp_null(void) ;
|
|
#line 890 "inweb/foundation-module/Chapter 2/Memory.w"
|
|
int Memory__test_gp_null(general_pointer gp) ;
|
|
#line 272 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__initialise(text_stream *stream, int from) ;
|
|
#line 290 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__enable_XML_escapes(text_stream *stream) ;
|
|
#line 294 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__disable_XML_escapes(text_stream *stream) ;
|
|
#line 300 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__enable_I6_escapes(text_stream *stream) ;
|
|
#line 305 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__disable_I6_escapes(text_stream *stream) ;
|
|
#line 311 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__I6_escapes_enabled(text_stream *stream) ;
|
|
#line 315 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__enable_debugging(text_stream *stream) ;
|
|
#line 319 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__disable_debugging(text_stream *stream) ;
|
|
#line 324 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__mark_as_read_only(text_stream *stream) ;
|
|
#line 328 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__declare_as_HTML(text_stream *stream, HTML_file_state *hs) ;
|
|
#line 332 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
HTML_file_state * Streams__get_HTML_file_state(text_stream *stream) ;
|
|
#line 339 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__log(OUTPUT_STREAM, void *vS) ;
|
|
#line 362 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
text_stream * Streams__get_stdout(void) ;
|
|
#line 380 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
text_stream * Streams__get_stderr(void) ;
|
|
#line 399 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__open_to_file(text_stream *stream, filename *name, int encoding) ;
|
|
#line 418 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__open_to_file_append(text_stream *stream, filename *name, int encoding) ;
|
|
#line 439 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__open_to_memory(text_stream *stream, int capacity) ;
|
|
#line 458 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
text_stream Streams__new_buffer(int capacity, wchar_t *at) ;
|
|
#line 476 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__open_from_wide_string(text_stream *stream, wchar_t *c_string) ;
|
|
#line 484 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_wide_string(text_stream *stream, wchar_t *c_string) ;
|
|
#line 492 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__open_from_ISO_string(text_stream *stream, char *c_string) ;
|
|
#line 500 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_ISO_string(text_stream *stream, char *c_string) ;
|
|
#line 507 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__open_from_UTF8_string(text_stream *stream, char *c_string) ;
|
|
#line 515 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_UTF8_string(text_stream *stream, char *c_string) ;
|
|
#line 534 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_as_wide_string(wchar_t *C_string, text_stream *stream, int buffer_size) ;
|
|
#line 553 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_as_ISO_string(char *C_string, text_stream *stream, int buffer_size) ;
|
|
#line 570 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_as_UTF8_string(char *C_string, text_stream *stream, int buffer_size) ;
|
|
#line 601 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__open_from_locale_string(text_stream *stream, char *C_string) ;
|
|
#line 610 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_as_locale_string(char *C_string, text_stream *stream, int buffer_size) ;
|
|
#line 619 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__write_locale_string(text_stream *stream, char *C_string) ;
|
|
#line 633 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__flush(text_stream *stream) ;
|
|
#line 641 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__close(text_stream *stream) ;
|
|
#line 692 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__putc(int c_int, text_stream *stream) ;
|
|
#line 788 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__literal(text_stream *stream, char *p) ;
|
|
#line 802 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__indent(text_stream *stream) ;
|
|
#line 807 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__outdent(text_stream *stream) ;
|
|
#line 816 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__set_indentation(text_stream *stream, int N) ;
|
|
#line 830 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__get_position(text_stream *stream) ;
|
|
#line 844 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__latest(text_stream *stream) ;
|
|
#line 860 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
wchar_t Streams__get_char_at_index(text_stream *stream, int position) ;
|
|
#line 872 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__put_char_at_index(text_stream *stream, int position, wchar_t C) ;
|
|
#line 898 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__set_position(text_stream *stream, int position) ;
|
|
#line 922 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__copy(text_stream *to, text_stream *from) ;
|
|
#line 938 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__writer(OUTPUT_STREAM, char *format_string, void *vS) ;
|
|
#line 51 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
|
|
void Writers__log_escape_usage(void) ;
|
|
#line 67 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
|
|
void Writers__register_writer(int esc, void (*f)(text_stream *, char *, void *)) ;
|
|
#line 70 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
|
|
void Writers__register_logger(int esc, void (*f)(text_stream *, void *)) ;
|
|
#line 73 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
|
|
void Writers__register_writer_I(int esc, void (*f)(text_stream *, char *, int)) ;
|
|
#line 76 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
|
|
void Writers__register_logger_I(int esc, void (*f)(text_stream *, int)) ;
|
|
#line 87 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
|
|
void Writers__register_writer_p(int set, int esc, void *f, int cat) ;
|
|
#line 129 "inweb/foundation-module/Chapter 2/Writers and Loggers.w"
|
|
void Writers__printf(text_stream *stream, char *fmt, ...) ;
|
|
#line 41 "inweb/foundation-module/Chapter 2/Methods.w"
|
|
method_set * Methods__new_set(void) ;
|
|
#line 85 "inweb/foundation-module/Chapter 2/Methods.w"
|
|
void Methods__add(method_set *S, int ID, void *function) ;
|
|
#line 99 "inweb/foundation-module/Chapter 2/Methods.w"
|
|
int Methods__provided(method_set *S, int ID) ;
|
|
#line 29 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
linked_list * LinkedLists__new(void) ;
|
|
#line 41 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
void LinkedLists__add(linked_list *L, void *P, int to_end) ;
|
|
#line 70 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
void * LinkedLists__remove_from_front(linked_list *L) ;
|
|
#line 83 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
void * LinkedLists__delete(int N, linked_list *L) ;
|
|
#line 106 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
int LinkedLists__len(linked_list *L) ;
|
|
#line 109 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
linked_list_item * LinkedLists__first(linked_list *L) ;
|
|
#line 112 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
void * LinkedLists__entry(int N, linked_list *L) ;
|
|
#line 119 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
linked_list_item * LinkedLists__last(linked_list *L) ;
|
|
#line 122 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
linked_list_item * LinkedLists__next(linked_list_item *I) ;
|
|
#line 125 "inweb/foundation-module/Chapter 2/Linked Lists and Stacks.w"
|
|
void * LinkedLists__content(linked_list_item *I) ;
|
|
#line 33 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
dictionary * Dictionaries__new(int S, int textual) ;
|
|
#line 51 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void Dictionaries__log(OUTPUT_STREAM, dictionary *D) ;
|
|
#line 71 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
int Dictionaries__hash(text_stream *K, int N) ;
|
|
#line 85 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
dict_entry * Dictionaries__find(dictionary *D, text_stream *K) ;
|
|
#line 88 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
dict_entry * Dictionaries__create(dictionary *D, text_stream *K) ;
|
|
#line 91 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void Dictionaries__destroy(dictionary *D, text_stream *K) ;
|
|
#line 100 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
dict_entry * Dictionaries__find_literal(dictionary *D, wchar_t *lit) ;
|
|
#line 107 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
dict_entry * Dictionaries__create_literal(dictionary *D, wchar_t *lit) ;
|
|
#line 114 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void Dictionaries__destroy_literal(dictionary *D, wchar_t *lit) ;
|
|
#line 125 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
dict_entry * Dictionaries__find_p(dictionary *D, text_stream *K, int change) ;
|
|
#line 202 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void * Dictionaries__read_value(dictionary *D, text_stream *key) ;
|
|
#line 210 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void * Dictionaries__read_value_literal(dictionary *D, wchar_t *key) ;
|
|
#line 219 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void Dictionaries__write_value(dictionary *D, text_stream *key, void *val) ;
|
|
#line 227 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void Dictionaries__write_value_literal(dictionary *D, wchar_t *key, void *val) ;
|
|
#line 240 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
text_stream * Dictionaries__create_text(dictionary *D, text_stream *key) ;
|
|
#line 246 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
text_stream * Dictionaries__create_text_literal(dictionary *D, wchar_t *lit) ;
|
|
#line 257 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
text_stream * Dictionaries__get_text(dictionary *D, text_stream *key) ;
|
|
#line 265 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
text_stream * Dictionaries__get_text_literal(dictionary *D, wchar_t *lit) ;
|
|
#line 278 "inweb/foundation-module/Chapter 2/Dictionaries.w"
|
|
void Dictionaries__dispose_of(dictionary *D) ;
|
|
#line 13 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__set_handler(int (*f)(text_stream *, int)) ;
|
|
#line 16 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__set_internal_handler(void (*f)(void *, char *, char *, int)) ;
|
|
#line 21 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
int Errors__have_occurred(void) ;
|
|
#line 26 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__issue(text_stream *message, int fatality) ;
|
|
#line 41 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__fatal(char *message) ;
|
|
#line 48 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__fatal_with_C_string(char *message, char *parameter) ;
|
|
#line 57 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__fatal_with_text(char *message, text_stream *parameter) ;
|
|
#line 66 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__fatal_with_file(char *message, filename *F) ;
|
|
#line 73 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__fatal_with_path(char *message, pathname *P) ;
|
|
#line 85 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__internal_error_handler(void *p, char *message, char *f, int lc) ;
|
|
#line 99 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__enter_debugger_mode(void) ;
|
|
#line 104 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__die(void) ;
|
|
#line 120 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__nowhere(char *message) ;
|
|
#line 124 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__in_text_file(char *message, text_file_position *here) ;
|
|
#line 131 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__in_text_file_S(text_stream *message, text_file_position *here) ;
|
|
#line 141 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__at_position(char *message, filename *file, int line) ;
|
|
#line 150 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__at_position_S(text_stream *message, filename *file, int line) ;
|
|
#line 162 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__with_file(char *message, filename *F) ;
|
|
#line 169 "inweb/foundation-module/Chapter 3/Error Messages.w"
|
|
void Errors__with_text(char *message, text_stream *T) ;
|
|
#line 65 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__begin_group(int id, text_stream *name) ;
|
|
#line 71 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__end_group(void) ;
|
|
#line 74 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
command_line_switch * CommandLine__declare_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal) ;
|
|
#line 80 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
command_line_switch * CommandLine__declare_switch_p(int id, text_stream *name, int val, text_stream *help_literal) ;
|
|
#line 117 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
command_line_switch * CommandLine__declare_boolean_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal, int active) ;
|
|
#line 136 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__declare_numerical_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal) ;
|
|
#line 143 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__declare_textual_switch(int id, wchar_t *name_literal, int val, wchar_t *help_literal) ;
|
|
#line 179 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
int CommandLine__read(int argc, char **argv, void *state, void (*f)(int, int, text_stream *, void *), void (*g)(int, text_stream *, void *)) ;
|
|
#line 189 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__read_array(clf_reader_state *crs, int argc, char **argv) ;
|
|
#line 216 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__also_read_file(filename *F) ;
|
|
#line 227 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__record_log(text_stream *line) ;
|
|
#line 233 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__play_back_log(void) ;
|
|
#line 250 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__read_file(clf_reader_state *crs) ;
|
|
#line 262 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__read_file_helper(text_stream *text, text_file_position *tfp, void *state) ;
|
|
#line 291 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__read_one(clf_reader_state *crs, text_stream *opt) ;
|
|
#line 299 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
int CommandLine__read_pair(clf_reader_state *crs, text_stream *opt, text_stream *arg) ;
|
|
#line 323 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
int CommandLine__read_pair_p(text_stream *opt, text_stream *opt_val, int N, text_stream *arg, void *state, void (*f)(int, int, text_stream *, void *), int *substantive) ;
|
|
#line 414 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__declare_heading(wchar_t *heading_text_literal) ;
|
|
#line 418 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
void CommandLine__write_help(OUTPUT_STREAM) ;
|
|
#line 476 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
int CommandLine__compare_names(const void *ent1, const void *ent2) ;
|
|
#line 51 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
void Pathnames__start(void) ;
|
|
#line 64 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
void Pathnames__set_installation_path(pathname *P) ;
|
|
#line 67 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
pathname * Pathnames__installation_path(const char *V, text_stream *def) ;
|
|
#line 96 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
pathname * Pathnames__subfolder(pathname *P, text_stream *folder_name) ;
|
|
#line 100 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
pathname * Pathnames__primitive(text_stream *str, int from, int to, pathname *par) ;
|
|
#line 120 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
pathname * Pathnames__from_text(text_stream *path) ;
|
|
#line 124 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
pathname * Pathnames__from_text_relative(pathname *P, text_stream *path) ;
|
|
#line 141 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
void Pathnames__writer(OUTPUT_STREAM, char *format_string, void *vP) ;
|
|
#line 148 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
void Pathnames__writer_r(OUTPUT_STREAM, pathname *P, int divider) ;
|
|
#line 175 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
void Pathnames__to_text_relative(OUTPUT_STREAM, pathname *P, pathname *R) ;
|
|
#line 189 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
pathname * Pathnames__up(pathname *P) ;
|
|
#line 194 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
text_stream * Pathnames__directory_name(pathname *P) ;
|
|
#line 204 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
int Pathnames__create_in_file_system(pathname *P) ;
|
|
#line 222 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
void Pathnames__rsync(pathname *source, pathname *dest) ;
|
|
#line 24 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename * Filenames__in_folder(pathname *P, text_stream *file_name) ;
|
|
#line 28 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename * Filenames__primitive(text_stream *S, int from, int to, pathname *P) ;
|
|
#line 44 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename * Filenames__from_text(text_stream *path) ;
|
|
#line 60 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename * Filenames__from_text_relative(pathname *from, text_stream *path) ;
|
|
#line 77 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
void Filenames__writer(OUTPUT_STREAM, char *format_string, void *vF) ;
|
|
#line 93 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
void Filenames__to_text_relative(OUTPUT_STREAM, filename *F, pathname *P) ;
|
|
#line 110 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
pathname * Filenames__get_path_to(filename *F) ;
|
|
#line 118 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename * Filenames__without_path(filename *F) ;
|
|
#line 122 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
text_stream * Filenames__get_leafname(filename *F) ;
|
|
#line 127 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
void Filenames__write_unextended_leafname(OUTPUT_STREAM, filename *F) ;
|
|
#line 143 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
void Filenames__write_extension(OUTPUT_STREAM, filename *F) ;
|
|
#line 152 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename * Filenames__set_extension(filename *F, char *extension) ;
|
|
#line 185 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
int Filenames__guess_format(filename *F) ;
|
|
#line 229 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
FILE * Filenames__fopen(filename *F, char *usage) ;
|
|
#line 238 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
FILE * Filenames__fopen_caseless(filename *F, char *usage) ;
|
|
#line 253 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
int Filenames__eq(filename *F1, filename *F2) ;
|
|
#line 268 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
time_t Filenames__timestamp(filename *F) ;
|
|
#ifdef PLATFORM_POSIX
|
|
#line 50 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
FILE * CIFilingSystem__fopen(const char *path, const char *mode) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#line 212 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
int CIFilingSystem__match_in_directory(void *vd, char *name, char *last_match) ;
|
|
#ifndef PLATFORM_POSIX
|
|
#line 232 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
FILE * CIFilingSystem__fopen(const char *path, const char *mode) ;
|
|
#endif /* PLATFORM_POSIX */
|
|
#line 14 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__quote_path(OUTPUT_STREAM, pathname *P) ;
|
|
#line 21 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__quote_file(OUTPUT_STREAM, filename *F) ;
|
|
#line 28 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__plain(OUTPUT_STREAM, char *raw) ;
|
|
#line 32 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__plain_text(OUTPUT_STREAM, text_stream *raw) ;
|
|
#line 36 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__quote_text(OUTPUT_STREAM, text_stream *raw) ;
|
|
#line 50 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__apply(char *command, filename *F) ;
|
|
#line 58 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__apply_S(text_stream *command, filename *F) ;
|
|
#line 70 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__rm(filename *F) ;
|
|
#line 74 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__copy(filename *F, pathname *T, char *options) ;
|
|
#line 89 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__redirect(OUTPUT_STREAM, filename *F) ;
|
|
#line 106 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__verbose(void) ;
|
|
#line 110 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
int Shell__run(OUTPUT_STREAM) ;
|
|
#line 19 "inweb/foundation-module/Chapter 3/Directories.w"
|
|
scan_directory * Directories__open(pathname *P) ;
|
|
#line 30 "inweb/foundation-module/Chapter 3/Directories.w"
|
|
int Directories__next(scan_directory *D, text_stream *leafname) ;
|
|
#line 42 "inweb/foundation-module/Chapter 3/Directories.w"
|
|
void Directories__close(scan_directory *D) ;
|
|
#line 13 "inweb/foundation-module/Chapter 3/Time.w"
|
|
void Time__begin(void) ;
|
|
#line 26 "inweb/foundation-module/Chapter 3/Time.w"
|
|
void Time__fix(void) ;
|
|
#line 35 "inweb/foundation-module/Chapter 3/Time.w"
|
|
int Time__fixed(void) ;
|
|
#line 84 "inweb/foundation-module/Chapter 3/Time.w"
|
|
int Time__feast(void) ;
|
|
#line 8 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
wchar_t Characters__tolower(wchar_t c) ;
|
|
#line 11 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
wchar_t Characters__toupper(wchar_t c) ;
|
|
#line 14 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__isalpha(wchar_t c) ;
|
|
#line 17 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__isdigit(wchar_t c) ;
|
|
#line 20 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__isupper(wchar_t c) ;
|
|
#line 23 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__islower(wchar_t c) ;
|
|
#line 26 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__isalnum(wchar_t c) ;
|
|
#line 29 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__vowel(wchar_t c) ;
|
|
#line 37 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__is_space_or_tab(int c) ;
|
|
#line 41 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__is_whitespace(int c) ;
|
|
#line 51 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__is_babel_whitespace(int c) ;
|
|
#line 62 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__combine_accent(int accent, int letter) ;
|
|
#line 116 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__make_filename_safe(int charcode) ;
|
|
#line 125 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__remove_accent(int charcode) ;
|
|
#line 25 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__strlen_unbounded(const char *p) ;
|
|
#line 35 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__check_len(int n) ;
|
|
#line 44 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__len(char *str) ;
|
|
#line 55 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
void CStrings__copy(char *to, char *from) ;
|
|
#line 65 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__ne(char *A, char *B) ;
|
|
#line 72 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__cmp(char *A, char *B) ;
|
|
#line 85 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
void CStrings__transcode_ISO_string_to_UTF8(char *p, char *dest) ;
|
|
#line 106 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
void CStrings__truncated_strcpy(char *to, char *from, int max) ;
|
|
#line 14 "inweb/foundation-module/Chapter 4/Wide Strings.w"
|
|
int Wide__len(wchar_t *p) ;
|
|
#line 21 "inweb/foundation-module/Chapter 4/Wide Strings.w"
|
|
int Wide__cmp(wchar_t *A, wchar_t *B) ;
|
|
#line 26 "inweb/foundation-module/Chapter 4/Wide Strings.w"
|
|
int Wide__atoi(wchar_t *p) ;
|
|
#line 38 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__new(void) ;
|
|
#line 42 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__new_with_capacity(int c) ;
|
|
#line 48 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__dispose_of(text_stream *text) ;
|
|
#line 57 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__duplicate(text_stream *E) ;
|
|
#line 73 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__new_from_wide_string(wchar_t *C_string) ;
|
|
#line 79 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__new_from_ISO_string(char *C_string) ;
|
|
#line 85 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__new_from_UTF8_string(char *C_string) ;
|
|
#line 91 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__new_from_locale_string(char *C_string) ;
|
|
#line 100 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__from_wide_string(text_stream *S, wchar_t *c_string) ;
|
|
#line 105 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__from_locale_string(text_stream *S, char *c_string) ;
|
|
#line 113 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_to_ISO_string(char *C_string, text_stream *S, int buffer_size) ;
|
|
#line 117 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_to_UTF8_string(char *C_string, text_stream *S, int buffer_size) ;
|
|
#line 121 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_to_wide_string(wchar_t *C_string, text_stream *S, int buffer_size) ;
|
|
#line 125 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_to_locale_string(char *C_string, text_stream *S, int buffer_size) ;
|
|
#line 132 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__atoi(text_stream *S, int index) ;
|
|
#line 146 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__len(text_stream *S) ;
|
|
#line 167 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
string_position Str__start(text_stream *S) ;
|
|
#line 171 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
string_position Str__at(text_stream *S, int i) ;
|
|
#line 177 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
string_position Str__end(text_stream *S) ;
|
|
#line 184 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
string_position Str__back(string_position P) ;
|
|
#line 188 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
string_position Str__forward(string_position P) ;
|
|
#line 192 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
string_position Str__plus(string_position P, int increment) ;
|
|
#line 196 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__width_between(string_position P1, string_position P2) ;
|
|
#line 201 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__in_range(string_position P) ;
|
|
#line 206 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__index(string_position P) ;
|
|
#line 222 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
wchar_t Str__get(string_position P) ;
|
|
#line 227 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
wchar_t Str__get_at(text_stream *S, int index) ;
|
|
#line 232 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
wchar_t Str__get_first_char(text_stream *S) ;
|
|
#line 236 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
wchar_t Str__get_last_char(text_stream *S) ;
|
|
#line 243 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__put(string_position P, wchar_t C) ;
|
|
#line 255 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__put_at(text_stream *S, int index, wchar_t C) ;
|
|
#line 262 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__clear(text_stream *S) ;
|
|
#line 266 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__truncate(text_stream *S, int len) ;
|
|
#line 274 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__concatenate(text_stream *S1, text_stream *S2) ;
|
|
#line 278 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy(text_stream *S1, text_stream *S2) ;
|
|
#line 284 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_tail(text_stream *S1, text_stream *S2, int from) ;
|
|
#line 295 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_ISO_string(text_stream *S, char *C_string) ;
|
|
#line 300 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_UTF8_string(text_stream *S, char *C_string) ;
|
|
#line 305 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__copy_wide_string(text_stream *S, wchar_t *C_string) ;
|
|
#line 314 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__eq(text_stream *S1, text_stream *S2) ;
|
|
#line 319 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__eq_insensitive(text_stream *S1, text_stream *S2) ;
|
|
#line 324 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__ne(text_stream *S1, text_stream *S2) ;
|
|
#line 329 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__ne_insensitive(text_stream *S1, text_stream *S2) ;
|
|
#line 338 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__cmp(text_stream *S1, text_stream *S2) ;
|
|
#line 348 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__cmp_insensitive(text_stream *S1, text_stream *S2) ;
|
|
#line 369 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__prefix_eq(text_stream *S1, text_stream *S2, int N) ;
|
|
#line 378 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__suffix_eq(text_stream *S1, text_stream *S2, int N) ;
|
|
#line 387 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__begins_with_wide_string(text_stream *S, wchar_t *prefix) ;
|
|
#line 396 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__ends_with_wide_string(text_stream *S, wchar_t *suffix) ;
|
|
#line 406 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__eq_wide_string(text_stream *S1, wchar_t *S2) ;
|
|
#line 416 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__eq_narrow_string(text_stream *S1, char *S2) ;
|
|
#line 426 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__ne_wide_string(text_stream *S1, wchar_t *S2) ;
|
|
#line 433 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__is_whitespace(text_stream *S) ;
|
|
#line 443 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__trim_white_space(text_stream *S) ;
|
|
#line 472 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__trim_white_space_at_end(text_stream *S) ;
|
|
#line 483 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__trim_all_white_space_at_end(text_stream *S) ;
|
|
#line 497 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__delete_first_character(text_stream *S) ;
|
|
#line 501 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__delete_last_character(text_stream *S) ;
|
|
#line 506 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__delete_nth_character(text_stream *S, int n) ;
|
|
#line 511 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__delete_n_characters(text_stream *S, int n) ;
|
|
#line 524 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
void Str__substr(OUTPUT_STREAM, string_position from, string_position to) ;
|
|
#line 530 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__includes_character(text_stream *S, wchar_t c) ;
|
|
#line 538 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__includes_wide_string_at(text_stream *S, wchar_t *prefix, int j) ;
|
|
#line 547 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__includes_wide_string_at_insensitive(text_stream *S, wchar_t *prefix, int j) ;
|
|
#line 556 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
int Str__includes(text_stream *S, text_stream *T) ;
|
|
#line 584 "inweb/foundation-module/Chapter 4/String Manipulation.w"
|
|
text_stream * Str__literal(wchar_t *wide_C_string) ;
|
|
#line 15 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
int TextFiles__exists(filename *F) ;
|
|
#line 39 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
int TextFiles__get_line_count(text_file_position *tfp) ;
|
|
#line 47 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
text_file_position TextFiles__nowhere(void) ;
|
|
#line 64 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
int TextFiles__read(filename *F, int escape_oddities, char *message, int serious, void (iterator)(text_stream *, text_file_position *, void *), text_file_position *start_at, void *state) ;
|
|
#line 156 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
void TextFiles__read_line(OUTPUT_STREAM, int escape_oddities, text_file_position *tfp) ;
|
|
#line 180 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
void TextFiles__lose_interest(text_file_position *tfp) ;
|
|
#line 213 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
unicode_file_buffer TextFiles__create_ufb(void) ;
|
|
#line 219 "inweb/foundation-module/Chapter 4/Text Files.w"
|
|
int TextFiles__utf8_fgetc(FILE *from, char **or_from, int escape_oddities, unicode_file_buffer *ufb) ;
|
|
#line 77 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
wchar_t * Tries__search(match_trie *T, text_stream *p, wchar_t *add_outcome) ;
|
|
#line 237 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
int Tries__matches(match_trie *pos, int c) ;
|
|
#line 257 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
int Tries__is_ambiguous(match_trie *pos) ;
|
|
#line 267 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
match_trie * Tries__new(int mc) ;
|
|
#line 293 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
match_avinue * Tries__new_avinue(int from_start) ;
|
|
#line 300 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
void Tries__add_to_avinue(match_avinue *mt, text_stream *from, wchar_t *to) ;
|
|
#line 309 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
match_avinue * Tries__duplicate_avinue(match_avinue *A) ;
|
|
#line 327 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
wchar_t * Tries__search_avinue(match_avinue *T, text_stream *p) ;
|
|
#line 339 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
void Tries__log_avinue(OUTPUT_STREAM, void *vA) ;
|
|
#line 352 "inweb/foundation-module/Chapter 4/Tries and Avinues.w"
|
|
void Tries__log(OUTPUT_STREAM, match_trie *T) ;
|
|
#line 10 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__white_space(int c) ;
|
|
#line 20 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__identifier_char(int c) ;
|
|
#line 35 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__find_expansion(text_stream *text, wchar_t on1, wchar_t on2, wchar_t off1, wchar_t off2, int *len) ;
|
|
#line 51 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__find_open_brace(text_stream *text) ;
|
|
#line 62 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__string_is_white_space(text_stream *text) ;
|
|
#line 143 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
match_results Regexp__create_mr(void) ;
|
|
#line 151 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
void Regexp__dispose_of(match_results *mr) ;
|
|
#line 165 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__match(match_results *mr, text_stream *text, wchar_t *pattern) ;
|
|
#line 172 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
void Regexp__prepare(match_results *mr) ;
|
|
#line 187 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__match_r(match_results *mr, text_stream *text, wchar_t *pattern, match_position *scan_from, int allow_partial) ;
|
|
#line 315 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__get_cclass(wchar_t *pattern, int ppos, int *len, int *from, int *to, int *reverse) ;
|
|
#line 344 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__test_cclass(int c, int chcl, int range_from, int range_to, wchar_t *drawn_from, int reverse) ;
|
|
#line 388 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__replace(text_stream *text, wchar_t *pattern, wchar_t *replacement, int options) ;
|
|
#line 28 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__declare_as_HTML(OUTPUT_STREAM, int XHTML) ;
|
|
#line 49 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
int HTML__push_tag(OUTPUT_STREAM, char *tag) ;
|
|
#line 62 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__pop_tag(OUTPUT_STREAM, char *tag) ;
|
|
#line 83 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__completed(OUTPUT_STREAM) ;
|
|
#line 123 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__tag(OUTPUT_STREAM, char *tag, text_stream *details) ;
|
|
#line 132 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__tag_sc(OUTPUT_STREAM, char *tag, text_stream *details) ;
|
|
#line 139 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
int HTML__tag_formatting(char *tag) ;
|
|
#line 148 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__open(OUTPUT_STREAM, char *tag, text_stream *details) ;
|
|
#line 157 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__close(OUTPUT_STREAM, char *tag) ;
|
|
#line 166 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
int HTML__pair_formatting(char *tag) ;
|
|
#line 188 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_head(OUTPUT_STREAM, filename *CSS_file) ;
|
|
#line 206 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__end_head(OUTPUT_STREAM) ;
|
|
#line 211 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__title(OUTPUT_STREAM, text_stream *title) ;
|
|
#line 220 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__open_javascript(OUTPUT_STREAM, int define_project) ;
|
|
#line 234 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__close_javascript(OUTPUT_STREAM) ;
|
|
#line 238 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__incorporate_javascript(OUTPUT_STREAM, int define_project, filename *M) ;
|
|
#line 249 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__open_CSS(OUTPUT_STREAM) ;
|
|
#line 254 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__close_CSS(OUTPUT_STREAM) ;
|
|
#line 259 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__incorporate_CSS(OUTPUT_STREAM, filename *M) ;
|
|
#line 268 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__incorporate_HTML(OUTPUT_STREAM, filename *M) ;
|
|
#line 276 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__incorporate_helper(text_stream *line_of_template, text_file_position *tfp, void *OUT) ;
|
|
#line 284 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_body(OUTPUT_STREAM, text_stream *class) ;
|
|
#line 289 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__end_body(OUTPUT_STREAM) ;
|
|
#line 297 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_div_with_id(OUTPUT_STREAM, char *id) ;
|
|
#line 301 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_div_with_class(OUTPUT_STREAM, char *cl) ;
|
|
#line 305 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_div_with_class_and_id(OUTPUT_STREAM, char *cl, char *id, int hide) ;
|
|
#line 310 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_div_with_id_S(OUTPUT_STREAM, text_stream *id) ;
|
|
#line 317 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_div_with_class_S(OUTPUT_STREAM, text_stream *cl) ;
|
|
#line 324 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_div_with_class_and_id_S(OUTPUT_STREAM, text_stream *cl, text_stream *id, int hide) ;
|
|
#line 332 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__end_div(OUTPUT_STREAM) ;
|
|
#line 339 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__image(OUTPUT_STREAM, filename *F) ;
|
|
#line 346 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__anchor(OUTPUT_STREAM, text_stream *id) ;
|
|
#line 350 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_link(OUTPUT_STREAM, text_stream *to) ;
|
|
#line 354 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_link_with_class(OUTPUT_STREAM, text_stream *cl, text_stream *to) ;
|
|
#line 358 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_link_with_class_title(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *ti) ;
|
|
#line 362 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_link_with_class_onclick(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *on) ;
|
|
#line 366 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_link_with_class_title_onclick(OUTPUT_STREAM, text_stream *cl, text_stream *to, text_stream *ti, text_stream *on) ;
|
|
#line 374 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__end_link(OUTPUT_STREAM) ;
|
|
#line 382 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_plain_html_table(OUTPUT_STREAM) ;
|
|
#line 386 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_wide_html_table(OUTPUT_STREAM) ;
|
|
#line 393 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_html_table(OUTPUT_STREAM, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width) ;
|
|
#line 410 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_html_table_bg(OUTPUT_STREAM, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width, char *bg) ;
|
|
#line 423 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__first_html_column(OUTPUT_STREAM, int width) ;
|
|
#line 428 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__first_html_column_nowrap(OUTPUT_STREAM, int width, char *colour) ;
|
|
#line 436 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__first_html_column_spaced(OUTPUT_STREAM, int width) ;
|
|
#line 444 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__first_html_column_coloured(OUTPUT_STREAM, int width, char *colour, int cs) ;
|
|
#line 453 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column(OUTPUT_STREAM, int width) ;
|
|
#line 459 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column_centred(OUTPUT_STREAM, int width) ;
|
|
#line 465 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) ;
|
|
#line 471 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) ;
|
|
#line 477 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) ;
|
|
#line 483 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column_nw(OUTPUT_STREAM, int width) ;
|
|
#line 489 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column_w(OUTPUT_STREAM, int width) ;
|
|
#line 495 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) ;
|
|
#line 500 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__end_html_row(OUTPUT_STREAM) ;
|
|
#line 504 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__end_html_table(OUTPUT_STREAM) ;
|
|
#line 515 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__open_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ;
|
|
#line 535 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__close_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ;
|
|
#line 553 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__box_corner(OUTPUT_STREAM, char *html_colour, char *corner) ;
|
|
#line 563 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__comment(OUTPUT_STREAM, text_stream *text) ;
|
|
#line 567 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__heading(OUTPUT_STREAM, char *tag, text_stream *text) ;
|
|
#line 574 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__hr(OUTPUT_STREAM, char *class) ;
|
|
#line 739 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
wchar_t * HTML__translate_colour_name(wchar_t *original) ;
|
|
#line 747 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__begin_colour(OUTPUT_STREAM, text_stream *col) ;
|
|
#line 750 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__end_colour(OUTPUT_STREAM) ;
|
|
#line 106 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
ebook * Epub__new(text_stream *title, char *prefix) ;
|
|
#line 122 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
void Epub__use_CSS_throughout(ebook *B, filename *F) ;
|
|
#line 126 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
void Epub__use_CSS(ebook_volume *V, filename *F) ;
|
|
#line 130 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
text_stream * Epub__attach_metadata(ebook *B, wchar_t *K, text_stream *V) ;
|
|
#line 144 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
text_stream * Epub__get_metadata(ebook *B, wchar_t *K) ;
|
|
#line 152 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
text_stream * Epub__ensure_metadata(ebook *B, wchar_t *K) ;
|
|
#line 158 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
ebook_page * Epub__note_page(ebook *B, filename *F, text_stream *title, text_stream *type) ;
|
|
#line 178 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
void Epub__note_image(ebook *B, filename *F) ;
|
|
#line 186 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
ebook_volume * Epub__starts_volume(ebook *B, ebook_page *P, text_stream *title) ;
|
|
#line 197 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
ebook_chapter * Epub__starts_chapter(ebook *B, ebook_page *P, text_stream *title, text_stream *URL) ;
|
|
#line 210 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
void Epub__set_mark_in_chapter(ebook_chapter *C, text_stream *text, text_stream *URL) ;
|
|
#line 223 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
pathname * Epub__begin_construction(ebook *B, pathname *P, filename *cover_image) ;
|
|
#line 307 "inweb/foundation-module/Chapter 5/Epub Ebooks.w"
|
|
void Epub__end_construction(ebook *B) ;
|
|
#line 10 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__read_int8(FILE *binary_file, unsigned int *result) ;
|
|
#line 18 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__read_int16(FILE *binary_file, unsigned int *result) ;
|
|
#line 29 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__read_int32(FILE *binary_file, unsigned int *result) ;
|
|
#line 44 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__read_int64(FILE *binary_file, unsigned long long *result) ;
|
|
#line 70 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__write_int32(FILE *binary_file, unsigned int val) ;
|
|
#line 87 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
void BinaryFiles__swap_bytes32(unsigned int *value) ;
|
|
#line 95 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
void BinaryFiles__swap_bytes64(unsigned long long *value) ;
|
|
#line 113 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__read_variable_length_integer(FILE *binary_file, unsigned int *result) ;
|
|
#line 130 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__read_float80(FILE *binary_file, unsigned int *result) ;
|
|
#line 155 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__read_string(FILE *binary_file, char *string, unsigned int length) ;
|
|
#line 167 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
long int BinaryFiles__size(filename *F) ;
|
|
#line 184 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
FILE * BinaryFiles__open_for_reading(filename *F) ;
|
|
#line 190 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
FILE * BinaryFiles__try_to_open_for_reading(filename *F) ;
|
|
#line 194 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
FILE * BinaryFiles__open_for_writing(filename *F) ;
|
|
#line 200 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
FILE * BinaryFiles__try_to_open_for_writing(filename *F) ;
|
|
#line 204 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
void BinaryFiles__close(FILE *handle) ;
|
|
#line 213 "inweb/foundation-module/Chapter 6/Binary Files.w"
|
|
int BinaryFiles__copy(filename *from, filename *to, int suppress_error) ;
|
|
#line 24 "inweb/foundation-module/Chapter 6/Image Dimensions.w"
|
|
int ImageFiles__get_JPEG_dimensions(FILE *JPEG_file, unsigned int *width, unsigned int *height) ;
|
|
#line 77 "inweb/foundation-module/Chapter 6/Image Dimensions.w"
|
|
int ImageFiles__get_PNG_dimensions(FILE *PNG_file, unsigned int *width, unsigned int *height) ;
|
|
#line 12 "inweb/foundation-module/Chapter 6/Sound Durations.w"
|
|
int SoundFiles__get_AIFF_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
|
|
#line 59 "inweb/foundation-module/Chapter 6/Sound Durations.w"
|
|
int SoundFiles__get_OggVorbis_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
|
|
#line 181 "inweb/foundation-module/Chapter 6/Sound Durations.w"
|
|
int SoundFiles__get_MIDI_information(FILE *pFile, unsigned int *pType, unsigned int *pNumTracks) ;
|
|
#line 78 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
semantic_version_number VersionNumbers__null(void) ;
|
|
#line 89 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__is_null(semantic_version_number V) ;
|
|
#line 103 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
void VersionNumbers__to_text(OUTPUT_STREAM, semantic_version_number V) ;
|
|
#line 126 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
void VersionNumbers__writer(OUTPUT_STREAM, char *format_string, void *vE) ;
|
|
#line 144 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
semantic_version_number VersionNumbers__from_text(text_stream *T) ;
|
|
#line 215 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__le(semantic_version_number V1, semantic_version_number V2) ;
|
|
#line 251 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__floor(int N) ;
|
|
#line 261 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__strict_atoi(text_stream *T) ;
|
|
#line 277 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__eq(semantic_version_number V1, semantic_version_number V2) ;
|
|
#line 283 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__ne(semantic_version_number V1, semantic_version_number V2) ;
|
|
#line 287 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__gt(semantic_version_number V1, semantic_version_number V2) ;
|
|
#line 291 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__ge(semantic_version_number V1, semantic_version_number V2) ;
|
|
#line 295 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__lt(semantic_version_number V1, semantic_version_number V2) ;
|
|
#line 302 "inweb/foundation-module/Chapter 7/Version Numbers.w"
|
|
int VersionNumbers__cmp(semantic_version_number V1, semantic_version_number V2) ;
|
|
#line 39 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
void VersionNumberRanges__write_range(OUTPUT_STREAM, semver_range *R) ;
|
|
#line 58 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
semver_range * VersionNumberRanges__any_range(void) ;
|
|
#line 67 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
int VersionNumberRanges__is_any_range(semver_range *R) ;
|
|
#line 87 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
semver_range * VersionNumberRanges__compatibility_range(semantic_version_number V) ;
|
|
#line 106 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
semver_range * VersionNumberRanges__at_least_range(semantic_version_number V) ;
|
|
#line 113 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
semver_range * VersionNumberRanges__at_most_range(semantic_version_number V) ;
|
|
#line 123 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
int VersionNumberRanges__version_ge_end(semantic_version_number V, range_end E) ;
|
|
#line 139 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
int VersionNumberRanges__version_le_end(semantic_version_number V, range_end E) ;
|
|
#line 158 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
int VersionNumberRanges__in_range(semantic_version_number V, semver_range *R) ;
|
|
#line 178 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
int VersionNumberRanges__stricter(range_end E1, range_end E2, int lower) ;
|
|
#line 202 "inweb/foundation-module/Chapter 7/Version Number Ranges.w"
|
|
int VersionNumberRanges__intersect_range(semver_range *R1, semver_range *R2) ;
|
|
#line 87 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
web_md * WebMetadata__get_without_modules(pathname *P, filename *alt_F) ;
|
|
#line 91 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
web_md * WebMetadata__get(pathname *P, filename *alt_F, int syntax_version, module_search *I, int verbosely, int including_modules, pathname *path_to_inweb) ;
|
|
#line 172 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
void WebMetadata__read_contents_page(web_md *Wm, module *of_module, module_search *import_path, int verbosely, int including_modules, pathname *path, pathname *X) ;
|
|
#line 227 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
void WebMetadata__read_contents_line(text_stream *line, text_file_position *tfp, void *X) ;
|
|
#line 553 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
int WebMetadata__directory_looks_like_a_web(pathname *P) ;
|
|
#line 557 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
filename * WebMetadata__contents_filename(pathname *P) ;
|
|
#line 564 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
int WebMetadata__chapter_count(web_md *Wm) ;
|
|
#line 570 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
int WebMetadata__section_count(web_md *Wm) ;
|
|
#line 29 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
int Bibliographic__datum_can_be_declared(web_md *Wm, text_stream *key) ;
|
|
#line 35 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
int Bibliographic__datum_on_or_off(web_md *Wm, text_stream *key) ;
|
|
#line 45 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
void Bibliographic__initialise_data(web_md *Wm) ;
|
|
#line 77 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
void Bibliographic__check_required_data(web_md *Wm) ;
|
|
#line 90 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
text_stream * Bibliographic__get_datum(web_md *Wm, text_stream *key) ;
|
|
#line 96 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
int Bibliographic__data_exists(web_md *Wm, text_stream *key) ;
|
|
#line 102 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
web_bibliographic_datum * Bibliographic__look_up_datum(web_md *Wm, text_stream *key) ;
|
|
#line 117 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
web_bibliographic_datum * Bibliographic__set_datum(web_md *Wm, text_stream *key, text_stream *val) ;
|
|
#line 30 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module * WebModules__new(text_stream *name, pathname *at, int m) ;
|
|
#line 50 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module * WebModules__create_main_module(web_md *WS) ;
|
|
#line 61 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
void WebModules__dependency(module *A, module *B) ;
|
|
#line 77 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module_search * WebModules__make_search_path(pathname *ext_path) ;
|
|
#line 87 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module * WebModules__find(web_md *WS, module_search *ms, text_stream *name, pathname *X) ;
|
|
#line 116 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
int WebModules__exists(pathname *P) ;
|
|
#line 10 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
filename * BuildFiles__build_file_for_web(web_md *WS) ;
|
|
#line 30 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
build_file_data BuildFiles__read(filename *F) ;
|
|
#line 40 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__build_file_helper(text_stream *text, text_file_position *tfp, void *state) ;
|
|
#line 59 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__write(build_file_data bfd, filename *F) ;
|
|
#line 77 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__set_bibliographic_data_for(web_md *WS) ;
|
|
#line 99 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__deduce_semver(web_md *WS) ;
|
|
#line 129 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__advance_for_web(web_md *WS) ;
|
|
#line 135 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__advance(filename *F) ;
|
|
#line 148 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
int BuildFiles__dated_today(text_stream *dateline) ;
|
|
#line 174 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__increment(text_stream *T) ;
|
|
#line 63 "inweb/Chapter 1/Program Control.w"
|
|
int main(int argc, char **argv) ;
|
|
#line 90 "inweb/Chapter 1/Program Control.w"
|
|
void Main__follow_instructions(inweb_instructions *ins) ;
|
|
#line 281 "inweb/Chapter 1/Program Control.w"
|
|
void Main__error_in_web(text_stream *message, source_line *sl) ;
|
|
#line 60 "inweb/Chapter 1/Configuration.w"
|
|
inweb_instructions Configuration__read(int argc, char **argv) ;
|
|
#line 244 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__switch(int id, int val, text_stream *arg, void *state) ;
|
|
#line 338 "inweb/Chapter 1/Configuration.w"
|
|
breadcrumb_request * Configuration__breadcrumb(text_stream *arg) ;
|
|
#line 358 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__bareword(int id, text_stream *opt, void *state) ;
|
|
#line 373 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__set_range(inweb_instructions *args, text_stream *opt) ;
|
|
#line 405 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__set_fundamental_mode(inweb_instructions *args, int new_material) ;
|
|
#line 37 "inweb/Chapter 1/Patterns.w"
|
|
weave_pattern * Patterns__find(web *W, text_stream *name) ;
|
|
#line 87 "inweb/Chapter 1/Patterns.w"
|
|
void Patterns__scan_pattern_line(text_stream *line, text_file_position *tfp, void *X) ;
|
|
#line 158 "inweb/Chapter 1/Patterns.w"
|
|
int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) ;
|
|
#line 176 "inweb/Chapter 1/Patterns.w"
|
|
filename * Patterns__obtain_filename(weave_pattern *pattern, text_stream *leafname) ;
|
|
#line 192 "inweb/Chapter 1/Patterns.w"
|
|
void Patterns__copy_payloads_into_weave(web *W, weave_pattern *pattern) ;
|
|
#line 213 "inweb/Chapter 1/Patterns.w"
|
|
void Patterns__copy_file_into_weave(web *W, filename *F) ;
|
|
#line 218 "inweb/Chapter 1/Patterns.w"
|
|
void Patterns__copy_up_file_into_weave(web *W, filename *F) ;
|
|
#line 98 "inweb/Chapter 2/The Reader.w"
|
|
web_md * Reader__load_web_md(pathname *P, filename *alt_F, module_search *I, int verbosely, int including_modules) ;
|
|
#line 104 "inweb/Chapter 2/The Reader.w"
|
|
web * Reader__load_web(pathname *P, filename *alt_F, module_search *I, int verbosely, int including_modules) ;
|
|
#line 207 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__read_web(web *W, int verbosely) ;
|
|
#line 221 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__read_file(web *W, chapter *C, filename *F, text_stream *titling_line, section *S, int verbosely, int disregard_top) ;
|
|
#line 264 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__scan_source_line(text_stream *line, text_file_position *tfp, void *state) ;
|
|
#line 296 "inweb/Chapter 2/The Reader.w"
|
|
pathname * Reader__woven_folder(web *W) ;
|
|
#line 302 "inweb/Chapter 2/The Reader.w"
|
|
pathname * Reader__tangled_folder(web *W) ;
|
|
#line 317 "inweb/Chapter 2/The Reader.w"
|
|
chapter * Reader__get_chapter_for_range(web *W, text_stream *range) ;
|
|
#line 326 "inweb/Chapter 2/The Reader.w"
|
|
section * Reader__get_section_for_range(web *W, text_stream *range) ;
|
|
#line 340 "inweb/Chapter 2/The Reader.w"
|
|
section * Reader__section_by_filename(web *W, text_stream *filename) ;
|
|
#line 362 "inweb/Chapter 2/The Reader.w"
|
|
int Reader__range_within(text_stream *range1, text_stream *range2) ;
|
|
#line 391 "inweb/Chapter 2/The Reader.w"
|
|
tangle_target * Reader__add_tangle_target(web *W, programming_language *language) ;
|
|
#line 415 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__add_imported_header(web *W, filename *HF) ;
|
|
#line 422 "inweb/Chapter 2/The Reader.w"
|
|
int Reader__web_has_one_section(web *W) ;
|
|
#line 430 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__print_web_statistics(web *W) ;
|
|
#line 43 "inweb/Chapter 2/Line Categories.w"
|
|
source_line * Lines__new_source_line(text_stream *line, text_file_position *tfp) ;
|
|
#line 104 "inweb/Chapter 2/Line Categories.w"
|
|
char * Lines__category_name(int cat) ;
|
|
#line 17 "inweb/Chapter 2/The Parser.w"
|
|
void Parser__parse_web(web *W, int inweb_mode, int sequential) ;
|
|
#line 697 "inweb/Chapter 2/The Parser.w"
|
|
text_stream * Parser__extract_purpose(text_stream *prologue, source_line *XL, section *S, source_line **adjust) ;
|
|
#line 718 "inweb/Chapter 2/The Parser.w"
|
|
void Parser__wrong_version(int using, source_line *L, char *feature, int need) ;
|
|
#line 20 "inweb/Chapter 2/Paragraph Macros.w"
|
|
para_macro * Macros__create(section *S, paragraph *P, source_line *L, text_stream *name) ;
|
|
#line 38 "inweb/Chapter 2/Paragraph Macros.w"
|
|
para_macro * Macros__find_by_name(text_stream *name, section *scope) ;
|
|
#line 22 "inweb/Chapter 2/Tags.w"
|
|
theme_tag * Tags__find_by_name(text_stream *name, int creating_if_necessary) ;
|
|
#line 56 "inweb/Chapter 2/Tags.w"
|
|
void Tags__add_to_paragraph(paragraph *P, theme_tag *tag, text_stream *caption) ;
|
|
#line 71 "inweb/Chapter 2/Tags.w"
|
|
theme_tag * Tags__add_by_name(paragraph *P, text_stream *text) ;
|
|
#line 91 "inweb/Chapter 2/Tags.w"
|
|
text_stream * Tags__retrieve_caption(paragraph *P, theme_tag *tag) ;
|
|
#line 107 "inweb/Chapter 2/Tags.w"
|
|
int Tags__tagged_with(paragraph *P, theme_tag *tag) ;
|
|
#line 119 "inweb/Chapter 2/Tags.w"
|
|
void Tags__open_ifdefs(OUTPUT_STREAM, paragraph *P) ;
|
|
#line 127 "inweb/Chapter 2/Tags.w"
|
|
void Tags__close_ifdefs(OUTPUT_STREAM, paragraph *P) ;
|
|
#line 135 "inweb/Chapter 2/Tags.w"
|
|
void Tags__show_endnote_on_ifdefs(OUTPUT_STREAM, weave_target *wv, paragraph *P) ;
|
|
#line 27 "inweb/Chapter 2/Enumerated Constants.w"
|
|
enumeration_set * Enumerations__find(text_stream *post) ;
|
|
#line 40 "inweb/Chapter 2/Enumerated Constants.w"
|
|
void Enumerations__define(OUTPUT_STREAM, text_stream *symbol, text_stream *from, source_line *L) ;
|
|
#line 95 "inweb/Chapter 2/Enumerated Constants.w"
|
|
void Enumerations__define_extents(OUTPUT_STREAM, tangle_target *target, programming_language *lang) ;
|
|
#line 19 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
void Numbering__number_web(web *W) ;
|
|
#line 146 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
void Numbering__settle_paragraph_number(paragraph *P) ;
|
|
#line 11 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__scan_line_categories(web *W, text_stream *range) ;
|
|
#line 52 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__catalogue_the_sections(web *W, text_stream *range, int form) ;
|
|
#line 107 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__analyse_code(web *W) ;
|
|
#line 185 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__analyse_as_code(web *W, source_line *L, text_stream *text, int mask, int transf) ;
|
|
#line 227 "inweb/Chapter 3/The Analyser.w"
|
|
int Analyser__hash_code_from_word(text_stream *text) ;
|
|
#line 271 "inweb/Chapter 3/The Analyser.w"
|
|
hash_table_entry * Analyser__find_hash_entry(hash_table *HT, text_stream *text, int create) ;
|
|
#line 296 "inweb/Chapter 3/The Analyser.w"
|
|
hash_table_entry * Analyser__find_hash_entry_for_section(section *S, text_stream *text, int create) ;
|
|
#line 304 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) ;
|
|
#line 309 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) ;
|
|
#line 313 "inweb/Chapter 3/The Analyser.w"
|
|
int Analyser__is_reserved_word(hash_table *HT, text_stream *p, int e) ;
|
|
#line 319 "inweb/Chapter 3/The Analyser.w"
|
|
int Analyser__is_reserved_word_for_section(section *S, text_stream *p, int e) ;
|
|
#line 340 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__analyse_find(web *W, source_line *L, text_stream *identifier, int u) ;
|
|
#line 362 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__write_makefile(web *W, filename *F, module_search *I) ;
|
|
#line 369 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__write_gitignore(web *W, filename *F) ;
|
|
#line 20 "inweb/Chapter 3/The Swarm.w"
|
|
void Swarm__weave(web *W, text_stream *range, int swarm_mode, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, int docs_mode, linked_list *breadcrumbs, filename *navigation) ;
|
|
#line 52 "inweb/Chapter 3/The Swarm.w"
|
|
weave_target * Swarm__weave_subset(web *W, text_stream *range, int open_afterwards, theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, int docs_mode, linked_list *breadcrumbs, filename *navigation) ;
|
|
#line 172 "inweb/Chapter 3/The Swarm.w"
|
|
void Swarm__weave_index_templates(web *W, text_stream *range, weave_pattern *pattern, int self_contained, pathname *into, filename *F, linked_list *crumbs, int docs) ;
|
|
#line 11 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__cover_sheet_maker(OUTPUT_STREAM, web *W, text_stream *unextended_leafname, weave_target *wt, int halves) ;
|
|
#line 49 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__scan_cover_line(text_stream *line, text_file_position *tfp, void *v_state) ;
|
|
#line 131 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__nav_column(OUTPUT_STREAM, pathname *P, web *W, text_stream *range, weave_pattern *pattern, filename *nav) ;
|
|
#line 181 "inweb/Chapter 3/The Indexer.w"
|
|
contents_processor Indexer__new_processor(text_stream *range) ;
|
|
#line 194 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__run(web *W, text_stream *range, filename *template_filename, text_stream *contents_page_leafname, text_stream *write_to, weave_pattern *pattern, pathname *P, filename *nav_file, linked_list *crumbs, int docs) ;
|
|
#line 257 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__save_template_line(text_stream *line, text_file_position *tfp, void *void_cp) ;
|
|
#line 409 "inweb/Chapter 3/The Indexer.w"
|
|
linked_list_item * Indexer__heading_topmost_on_stack(contents_processor *cp, int level) ;
|
|
#line 420 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__start_CI_loop(contents_processor *cp, int level, linked_list_item *from, linked_list_item *to, int pos) ;
|
|
#line 430 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__end_CI_loop(contents_processor *cp) ;
|
|
#line 566 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__list_module(OUTPUT_STREAM, module *M, int list_this) ;
|
|
#line 583 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__transcribe_CSS(OUTPUT_STREAM, filename *CSS_file) ;
|
|
#line 590 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__copy_CSS(text_stream *line, text_file_position *tfp, void *X) ;
|
|
#line 16 "inweb/Chapter 3/The Weaver.w"
|
|
int Weaver__weave_source(web *W, weave_target *wv) ;
|
|
#line 659 "inweb/Chapter 3/The Weaver.w"
|
|
void Weaver__show_endnotes_on_previous_paragraph(OUTPUT_STREAM, weave_target *wv, paragraph *P) ;
|
|
#line 796 "inweb/Chapter 3/The Weaver.w"
|
|
int Weaver__weave_table_of_contents(OUTPUT_STREAM, weave_target *wv, section *S) ;
|
|
#line 14 "inweb/Chapter 3/The Tangler.w"
|
|
void Tangler__go(web *W, tangle_target *target, filename *dest_file) ;
|
|
#line 109 "inweb/Chapter 3/The Tangler.w"
|
|
void Tangler__tangle_paragraph(OUTPUT_STREAM, paragraph *P) ;
|
|
#line 144 "inweb/Chapter 3/The Tangler.w"
|
|
void Tangler__tangle_code(OUTPUT_STREAM, text_stream *original, section *S, source_line *L) ;
|
|
#line 241 "inweb/Chapter 3/The Tangler.w"
|
|
tangle_target * Tangler__primary_target(web *W) ;
|
|
#line 10 "inweb/Chapter 4/Programming Languages.w"
|
|
programming_language * Languages__find_by_name(text_stream *lname) ;
|
|
#line 39 "inweb/Chapter 4/Programming Languages.w"
|
|
programming_language * Languages__default(void) ;
|
|
#line 43 "inweb/Chapter 4/Programming Languages.w"
|
|
void Languages__show(OUTPUT_STREAM) ;
|
|
#line 53 "inweb/Chapter 4/Programming Languages.w"
|
|
void Languages__read_definitions(pathname *P) ;
|
|
#line 67 "inweb/Chapter 4/Programming Languages.w"
|
|
pathname * Languages__default_directory(void) ;
|
|
#line 127 "inweb/Chapter 4/Programming Languages.w"
|
|
programming_language * Languages__read_definition(filename *F) ;
|
|
#line 190 "inweb/Chapter 4/Programming Languages.w"
|
|
void Languages__read_definition_line(text_stream *line, text_file_position *tfp, void *v_state) ;
|
|
#line 344 "inweb/Chapter 4/Programming Languages.w"
|
|
colouring_language_block * Languages__new_block(colouring_language_block *within, int r) ;
|
|
#line 388 "inweb/Chapter 4/Programming Languages.w"
|
|
colouring_rule * Languages__new_rule(colouring_language_block *within) ;
|
|
#line 405 "inweb/Chapter 4/Programming Languages.w"
|
|
void Languages__parse_rule(language_reader_state *state, text_stream *premiss, text_stream *action, text_file_position *tfp) ;
|
|
#line 475 "inweb/Chapter 4/Programming Languages.w"
|
|
reserved_word * Languages__reserved(programming_language *pl, text_stream *W, int C, text_file_position *tfp) ;
|
|
#line 511 "inweb/Chapter 4/Programming Languages.w"
|
|
int Languages__colour(text_stream *T, text_file_position *tfp) ;
|
|
#line 536 "inweb/Chapter 4/Programming Languages.w"
|
|
int Languages__boolean(text_stream *T, text_file_position *tfp) ;
|
|
#line 550 "inweb/Chapter 4/Programming Languages.w"
|
|
text_stream * Languages__text(text_stream *T, text_file_position *tfp) ;
|
|
#line 39 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__further_parsing(web *W, programming_language *pl) ;
|
|
#line 52 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__subcategorise_line(programming_language *pl, source_line *L) ;
|
|
#line 66 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__parse_comment(programming_language *pl, text_stream *line, text_stream *before, text_stream *within) ;
|
|
#line 85 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__shebang(OUTPUT_STREAM, programming_language *pl, web *W, tangle_target *target) ;
|
|
#line 96 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__disclaimer(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ;
|
|
#line 110 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__additional_early_matter(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) ;
|
|
#line 129 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__start_definition(OUTPUT_STREAM, programming_language *pl, text_stream *term, text_stream *start, section *S, source_line *L) ;
|
|
#line 137 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__prolong_definition(OUTPUT_STREAM, programming_language *pl, text_stream *more, section *S, source_line *L) ;
|
|
#line 145 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__end_definition(OUTPUT_STREAM, programming_language *pl, section *S, source_line *L) ;
|
|
#line 158 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__additional_predeclarations(OUTPUT_STREAM, programming_language *pl, web *W) ;
|
|
#line 171 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__allow_expansion(programming_language *pl, text_stream *material) ;
|
|
#line 186 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__special_tangle_command(OUTPUT_STREAM, programming_language *pl, text_stream *data) ;
|
|
#line 203 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__will_insert_in_tangle(programming_language *pl, source_line *L) ;
|
|
#line 208 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__insert_in_tangle(OUTPUT_STREAM, programming_language *pl, source_line *L) ;
|
|
#line 221 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__insert_line_marker(OUTPUT_STREAM, programming_language *pl, source_line *L) ;
|
|
#line 235 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__before_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ;
|
|
#line 238 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__after_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) ;
|
|
#line 252 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__open_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ;
|
|
#line 255 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__close_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) ;
|
|
#line 265 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__comment(OUTPUT_STREAM, programming_language *pl, text_stream *comm) ;
|
|
#line 277 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__tangle_code(OUTPUT_STREAM, programming_language *pl, text_stream *original) ;
|
|
#line 289 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__gnabehs(OUTPUT_STREAM, programming_language *pl, web *W) ;
|
|
#line 301 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__additional_tangling(programming_language *pl, web *W, tangle_target *target) ;
|
|
#line 313 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__begin_weave(section *S, weave_target *wv) ;
|
|
#line 323 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__skip_in_weaving(programming_language *pl, weave_target *wv, source_line *L) ;
|
|
#line 338 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__reset_syntax_colouring(programming_language *pl) ;
|
|
#line 351 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__syntax_colour(OUTPUT_STREAM, programming_language *pl, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) ;
|
|
#line 372 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__weave_code_line(OUTPUT_STREAM, programming_language *pl, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
|
|
#line 385 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__new_tag_declared(theme_tag *tag) ;
|
|
#line 403 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__catalogue(programming_language *pl, section *S, int functions_too) ;
|
|
#line 419 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__early_preweave_analysis(programming_language *pl, web *W) ;
|
|
#line 422 "inweb/Chapter 4/Language Methods.w"
|
|
void LanguageMethods__late_preweave_analysis(programming_language *pl, web *W) ;
|
|
#line 433 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__share_element(programming_language *pl, text_stream *element_name) ;
|
|
#line 442 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__supports_definitions(programming_language *pl) ;
|
|
#line 16 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__add_fallbacks(programming_language *pl) ;
|
|
#line 54 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__expand(OUTPUT_STREAM, text_stream *prototype, text_stream *S, int N, filename *F) ;
|
|
#line 78 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__shebang(programming_language *pl, text_stream *OUT, web *W, tangle_target *target) ;
|
|
#line 83 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__before_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ;
|
|
#line 88 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__after_macro_expansion(programming_language *pl, OUTPUT_STREAM, para_macro *pmac) ;
|
|
#line 93 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__start_definition(programming_language *pl, text_stream *OUT, text_stream *term, text_stream *start, section *S, source_line *L) ;
|
|
#line 102 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__prolong_definition(programming_language *pl, text_stream *OUT, text_stream *more, section *S, source_line *L) ;
|
|
#line 111 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__end_definition(programming_language *pl, text_stream *OUT, section *S, source_line *L) ;
|
|
#line 119 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__I6_open_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ;
|
|
#line 125 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__I6_close_ifdef(programming_language *pl, text_stream *OUT, text_stream *symbol, int sense) ;
|
|
#line 131 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__insert_line_marker(programming_language *pl, text_stream *OUT, source_line *L) ;
|
|
#line 137 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__comment(programming_language *pl, text_stream *OUT, text_stream *comm) ;
|
|
#line 153 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__parse_comment(programming_language *pl, text_stream *line, text_stream *part_before_comment, text_stream *part_within_comment) ;
|
|
#line 208 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__text_at(text_stream *line, int i, text_stream *pattern) ;
|
|
#line 222 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__suppress_disclaimer(programming_language *pl) ;
|
|
#line 229 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__begin_weave(programming_language *pl, section *S, weave_target *wv) ;
|
|
#line 238 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__reset_syntax_colouring(programming_language *pl) ;
|
|
#line 242 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__syntax_colour(programming_language *pl, text_stream *OUT, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) ;
|
|
#line 16 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__reset_syntax_colouring(programming_language *pl) ;
|
|
#line 36 "inweb/Chapter 4/The Painter.w"
|
|
int Painter__syntax_colour(programming_language *pl, text_stream *OUT, hash_table *HT, text_stream *matter, text_stream *colouring, int with_comments) ;
|
|
#line 56 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__syntax_colour_inner(programming_language *pl, text_stream *OUT, hash_table *HT, text_stream *matter, text_stream *colouring, int from, int to) ;
|
|
#line 166 "inweb/Chapter 4/The Painter.w"
|
|
int Painter__identifier_at(programming_language *pl, text_stream *matter, text_stream *colouring, int i) ;
|
|
#line 199 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__execute(hash_table *HT, colouring_language_block *block, text_stream *matter, text_stream *colouring, int from, int to) ;
|
|
#line 250 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__execute_rule(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to) ;
|
|
#line 267 "inweb/Chapter 4/The Painter.w"
|
|
int Painter__satisfies(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to) ;
|
|
#line 315 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__follow(hash_table *HT, colouring_rule *rule, text_stream *matter, text_stream *colouring, int from, int to) ;
|
|
#line 9 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__make_c_like(programming_language *pl) ;
|
|
#line 41 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__further_parsing(programming_language *self, web *W) ;
|
|
#line 459 "inweb/Chapter 4/C-Like Languages.w"
|
|
c_structure * CLike__find_structure(web *W, text_stream *name) ;
|
|
#line 473 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__subcategorise_code(programming_language *self, source_line *L) ;
|
|
#line 502 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__additional_early_matter(programming_language *self, text_stream *OUT, web *W, tangle_target *target) ;
|
|
#line 521 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) ;
|
|
#line 559 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__tangle_structure(OUTPUT_STREAM, programming_language *self, c_structure *str) ;
|
|
#line 626 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__catalogue(programming_language *self, section *S, int functions_too) ;
|
|
#line 643 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__analyse_code(programming_language *self, web *W) ;
|
|
#line 665 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__post_analysis(programming_language *self, web *W) ;
|
|
#line 10 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__add_features(programming_language *pl) ;
|
|
#line 41 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__further_parsing(programming_language *self, web *W) ;
|
|
#line 367 "inweb/Chapter 4/InC Support.w"
|
|
int InCSupport__suppress_expansion(programming_language *self, text_stream *material) ;
|
|
#line 391 "inweb/Chapter 4/InC Support.w"
|
|
int InCSupport__special_tangle_command(programming_language *me, OUTPUT_STREAM, text_stream *data) ;
|
|
#line 415 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) ;
|
|
#line 444 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__gnabehs(programming_language *self, text_stream *OUT, web *W) ;
|
|
#line 478 "inweb/Chapter 4/InC Support.w"
|
|
int InCSupport__will_insert_in_tangle(programming_language *self, source_line *L) ;
|
|
#line 499 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__insert_in_tangle(programming_language *self, text_stream *OUT, source_line *L) ;
|
|
#line 636 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__tangle_code(programming_language *self, text_stream *OUT, text_stream *original) ;
|
|
#line 756 "inweb/Chapter 4/InC Support.w"
|
|
preform_nonterminal * InCSupport__nonterminal_by_name(text_stream *name) ;
|
|
#line 770 "inweb/Chapter 4/InC Support.w"
|
|
text_stream * InCSupport__nonterminal_variable_identifier(text_stream *name) ;
|
|
#line 791 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__additional_tangling(programming_language *self, web *W, tangle_target *target) ;
|
|
#line 853 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__weave_grammar_index(OUTPUT_STREAM) ;
|
|
#line 931 "inweb/Chapter 4/InC Support.w"
|
|
int InCSupport__skip_in_weaving(programming_language *self, weave_target *wv, source_line *L) ;
|
|
#line 946 "inweb/Chapter 4/InC Support.w"
|
|
int InCSupport__weave_code_line(programming_language *self, text_stream *OUT, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
|
|
#line 960 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__new_tag_declared(programming_language *self, theme_tag *tag) ;
|
|
#line 967 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__analyse_code(programming_language *self, web *W) ;
|
|
#line 974 "inweb/Chapter 4/InC Support.w"
|
|
int InCSupport__share_element(programming_language *self, text_stream *elname) ;
|
|
#line 18 "inweb/Chapter 5/Weave Formats.w"
|
|
weave_format * Formats__create_weave_format(text_stream *name, text_stream *ext) ;
|
|
#line 26 "inweb/Chapter 5/Weave Formats.w"
|
|
weave_format * Formats__find_by_name(text_stream *name) ;
|
|
#line 40 "inweb/Chapter 5/Weave Formats.w"
|
|
text_stream * Formats__file_extension(weave_format *wf) ;
|
|
#line 48 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__create_weave_formats(void) ;
|
|
#line 71 "inweb/Chapter 5/Weave Formats.w"
|
|
int Formats__begin_weaving(web *W, weave_pattern *pattern) ;
|
|
#line 77 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__end_weaving(web *W, weave_pattern *pattern) ;
|
|
#line 92 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__top(OUTPUT_STREAM, weave_target *wv, text_stream *comment) ;
|
|
#line 110 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__toc(OUTPUT_STREAM, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ;
|
|
#line 124 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__chapter_title_page(OUTPUT_STREAM, weave_target *wv, chapter *C) ;
|
|
#line 145 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__subheading(OUTPUT_STREAM, weave_target *wv, int level, text_stream *heading, text_stream *addendum) ;
|
|
#line 170 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__paragraph_heading(OUTPUT_STREAM, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ;
|
|
#line 190 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__source_code(OUTPUT_STREAM, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ;
|
|
#line 206 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__source_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) ;
|
|
#line 223 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__display_line(OUTPUT_STREAM, weave_target *wv, text_stream *from) ;
|
|
#line 245 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__item(OUTPUT_STREAM, weave_target *wv, int depth, text_stream *label) ;
|
|
#line 257 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__bar(OUTPUT_STREAM, weave_target *wv) ;
|
|
#line 271 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__figure(OUTPUT_STREAM, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) ;
|
|
#line 286 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__para_macro(OUTPUT_STREAM, weave_target *wv, para_macro *pmac, int defn) ;
|
|
#line 299 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__pagebreak(OUTPUT_STREAM, weave_target *wv) ;
|
|
#line 314 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__blank_line(OUTPUT_STREAM, weave_target *wv, int in_comment) ;
|
|
#line 328 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__after_definitions(OUTPUT_STREAM, weave_target *wv) ;
|
|
#line 344 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__change_material(OUTPUT_STREAM, weave_target *wv, int old_material, int new_material, int content) ;
|
|
#line 360 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__change_colour(OUTPUT_STREAM, weave_target *wv, int col, int in_code) ;
|
|
#line 371 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__text(OUTPUT_STREAM, weave_target *wv, text_stream *id) ;
|
|
#line 375 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__text_r(OUTPUT_STREAM, weave_target *wv, text_stream *id, int within) ;
|
|
#line 412 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__text_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) ;
|
|
#line 433 "inweb/Chapter 5/Weave Formats.w"
|
|
int Formats__preform_document(OUTPUT_STREAM, weave_target *wv, web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
|
|
#line 451 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__endnote(OUTPUT_STREAM, weave_target *wv, int end) ;
|
|
#line 466 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__locale(OUTPUT_STREAM, weave_target *wv, paragraph *par1, paragraph *par2) ;
|
|
#line 479 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__tail(OUTPUT_STREAM, weave_target *wv, text_stream *comment, section *S) ;
|
|
#line 495 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__post_process_weave(weave_target *wv, int open_afterwards) ;
|
|
#line 506 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__report_on_post_processing(weave_target *wv) ;
|
|
#line 518 "inweb/Chapter 5/Weave Formats.w"
|
|
int Formats__index_pdfs(text_stream *format) ;
|
|
#line 534 "inweb/Chapter 5/Weave Formats.w"
|
|
int Formats__substitute_post_processing_data(OUTPUT_STREAM, weave_target *wv, text_stream *detail, weave_pattern *pattern) ;
|
|
#line 9 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__create(void) ;
|
|
#line 32 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ;
|
|
#line 38 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) ;
|
|
#line 45 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ;
|
|
#line 56 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv, chapter *C) ;
|
|
#line 66 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ;
|
|
#line 79 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ;
|
|
#line 96 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *from) ;
|
|
#line 102 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ;
|
|
#line 109 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__bar(weave_format *self, text_stream *OUT, weave_target *wv) ;
|
|
#line 114 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ;
|
|
#line 122 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ;
|
|
#line 128 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ;
|
|
#line 134 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ;
|
|
#line 140 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ;
|
|
#line 147 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) ;
|
|
#line 9 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__create(void) ;
|
|
#line 67 "inweb/Chapter 5/TeX Format.w"
|
|
int TeX__yes(weave_format *self) ;
|
|
#line 72 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ;
|
|
#line 96 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) ;
|
|
#line 112 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ;
|
|
#line 134 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv, chapter *C) ;
|
|
#line 148 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ;
|
|
#line 180 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ;
|
|
#line 222 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) ;
|
|
#line 228 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__change_colour_PDF(weave_format *self, text_stream *OUT, weave_target *wv, int col, int in_code) ;
|
|
#line 245 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *text) ;
|
|
#line 251 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ;
|
|
#line 263 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__bar(weave_format *self, text_stream *OUT, weave_target *wv) ;
|
|
#line 275 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__figure_PDF(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) ;
|
|
#line 297 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__para_macro_PDF_1(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ;
|
|
#line 306 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ;
|
|
#line 315 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__para_macro_PDF_2(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ;
|
|
#line 324 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) ;
|
|
#line 329 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ;
|
|
#line 336 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__after_definitions(weave_format *self, text_stream *OUT, weave_target *wv) ;
|
|
#line 341 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ;
|
|
#line 351 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ;
|
|
#line 374 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ;
|
|
#line 381 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__change_material(weave_format *self, text_stream *OUT, weave_target *wv, int old_material, int new_material, int content) ;
|
|
#line 407 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *S) ;
|
|
#line 417 "inweb/Chapter 5/TeX Format.w"
|
|
int TeX__preform_document(weave_format *self, text_stream *OUT, web *W, weave_target *wv, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) ;
|
|
#line 496 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__post_process_PDF(weave_format *self, weave_target *wv, int open) ;
|
|
#line 499 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__post_process_DVI(weave_format *self, weave_target *wv, int open) ;
|
|
#line 504 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__post_process_report(weave_format *self, weave_target *wv) ;
|
|
#line 509 "inweb/Chapter 5/TeX Format.w"
|
|
int TeX__post_process_substitute(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *detail, weave_pattern *pattern) ;
|
|
#line 522 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__remove_math_mode(OUTPUT_STREAM, text_stream *text) ;
|
|
#line 529 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) ;
|
|
#line 6 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__create(void) ;
|
|
#line 58 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__p(OUTPUT_STREAM, char *class) ;
|
|
#line 64 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__cp(OUTPUT_STREAM) ;
|
|
#line 69 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__pre(OUTPUT_STREAM, char *class) ;
|
|
#line 76 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__cpre(OUTPUT_STREAM) ;
|
|
#line 85 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__go_to_depth(OUTPUT_STREAM, int depth) ;
|
|
#line 110 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__exit_current_paragraph(OUTPUT_STREAM) ;
|
|
#line 122 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__breadcrumb(OUTPUT_STREAM, text_stream *text, text_stream *link) ;
|
|
#line 142 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ;
|
|
#line 156 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__top_EPUB(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) ;
|
|
#line 165 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__subheading(weave_format *self, text_stream *OUT, weave_target *wv, int level, text_stream *comment, text_stream *head) ;
|
|
#line 182 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage, text_stream *text1, text_stream *text2, paragraph *P) ;
|
|
#line 217 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight) ;
|
|
#line 271 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__drop_initial_breadcrumbs(OUTPUT_STREAM, linked_list *crumbs, int docs_mode) ;
|
|
#line 282 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__source_code(weave_format *self, text_stream *OUT, weave_target *wv, int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter, text_stream *colouring, text_stream *concluding_comment, int starts, int finishes, int code_mode) ;
|
|
#line 340 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__inline_code(weave_format *self, text_stream *OUT, weave_target *wv, int enter) ;
|
|
#line 351 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__display_line(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *from) ;
|
|
#line 362 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth, text_stream *label) ;
|
|
#line 371 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__bar(weave_format *self, text_stream *OUT, weave_target *wv) ;
|
|
#line 384 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__figure(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *figname, int w, int h, programming_language *pl) ;
|
|
#line 416 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__text_file_helper(text_stream *text, text_file_position *tfp, void *state) ;
|
|
#line 430 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__para_macro(weave_format *self, text_stream *OUT, weave_target *wv, para_macro *pmac, int defn) ;
|
|
#line 445 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) ;
|
|
#line 450 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__blank_line(weave_format *self, text_stream *OUT, weave_target *wv, int in_comment) ;
|
|
#line 463 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__change_material(weave_format *self, text_stream *OUT, weave_target *wv, int old_material, int new_material, int content) ;
|
|
#line 531 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__change_colour(weave_format *self, text_stream *OUT, weave_target *wv, int col, int in_code) ;
|
|
#line 552 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) ;
|
|
#line 562 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *id) ;
|
|
#line 583 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__locale(weave_format *self, text_stream *OUT, weave_target *wv, paragraph *par1, paragraph *par2) ;
|
|
#line 597 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__xref(OUTPUT_STREAM, weave_target *wv, paragraph *P, section *from, int a_link) ;
|
|
#line 618 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__tail(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment, section *this_S) ;
|
|
#line 665 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__sref(OUTPUT_STREAM, weave_target *wv, section *S) ;
|
|
#line 678 "inweb/Chapter 5/HTML Formats.w"
|
|
int HTMLFormat__begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ;
|
|
#line 693 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__end_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) ;
|
|
#line 22 "inweb/Chapter 5/Running Through TeX.w"
|
|
void RunningTeX__post_process_weave(weave_target *wv, int open_afterwards, int to_DVI) ;
|
|
#line 109 "inweb/Chapter 5/Running Through TeX.w"
|
|
void RunningTeX__scan_console_line(text_stream *line, text_file_position *tfp, void *res_V) ;
|
|
#line 129 "inweb/Chapter 5/Running Through TeX.w"
|
|
void RunningTeX__report_on_post_processing(weave_target *wv) ;
|
|
#line 143 "inweb/Chapter 5/Running Through TeX.w"
|
|
int RunningTeX__substitute_post_processing_data(text_stream *to, weave_target *wv, text_stream *detail) ;
|
|
#line 24 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I) ;
|
|
#line 49 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__scan_makefile_line(text_stream *line, text_file_position *tfp, void *X) ;
|
|
#line 260 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) ;
|
|
#line 271 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) ;
|
|
#line 310 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__repeat(OUTPUT_STREAM, text_stream *prefix, int every_time, text_stream *matter, int as_lines, text_stream *suffix, text_file_position *tfp, makefile_state *MS, int over, text_stream *tag) ;
|
|
#line 15 "inweb/Chapter 6/Git Support.w"
|
|
void Git__write_gitignore(web *W, filename *prototype, filename *F) ;
|
|
#line 31 "inweb/Chapter 6/Git Support.w"
|
|
void Git__copy_gitignore_line(text_stream *line, text_file_position *tfp, void *X) ;
|
|
#line 19 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__write(filename *from, filename *to) ;
|
|
#line 44 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__write_helper(text_stream *text, text_file_position *tfp, void *state) ;
|
|
#line 83 "inweb/Chapter 6/Readme Writeme.w"
|
|
macro * Readme__new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) ;
|
|
#line 100 "inweb/Chapter 6/Readme Writeme.w"
|
|
macro_tokens Readme__parse_token_list(text_stream *chunk, text_file_position *tfp) ;
|
|
#line 149 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__expand_material(write_state *ws, text_stream *OUT, text_stream *text, text_file_position *tfp) ;
|
|
#line 172 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__expand_at(write_state *ws, text_stream *OUT, text_stream *macro_name, text_file_position *tfp) ;
|
|
#line 204 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__expand_macro(write_state *ws, text_stream *OUT, macro *M, text_file_position *tfp) ;
|
|
#line 263 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) ;
|
|
#line 273 "inweb/Chapter 6/Readme Writeme.w"
|
|
writeme_asset * Readme__find_asset(text_stream *program) ;
|
|
#line 324 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) ;
|
|
#line 336 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) ;
|
|
#line 350 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) ;
|
|
#line 366 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) ;
|
|
void register_tangled_nonterminals(void);
|
|
text_stream *TL_IS_0 = NULL;
|
|
text_stream *TL_IS_1 = NULL;
|
|
text_stream *TL_IS_2 = NULL;
|
|
text_stream *TL_IS_3 = NULL;
|
|
text_stream *TL_IS_4 = NULL;
|
|
text_stream *TL_IS_5 = NULL;
|
|
text_stream *TL_IS_6 = NULL;
|
|
text_stream *TL_IS_7 = NULL;
|
|
text_stream *TL_IS_8 = NULL;
|
|
text_stream *TL_IS_9 = NULL;
|
|
text_stream *TL_IS_10 = NULL;
|
|
text_stream *TL_IS_11 = NULL;
|
|
text_stream *TL_IS_12 = NULL;
|
|
text_stream *TL_IS_13 = NULL;
|
|
text_stream *TL_IS_14 = NULL;
|
|
text_stream *TL_IS_15 = NULL;
|
|
text_stream *TL_IS_16 = NULL;
|
|
text_stream *TL_IS_17 = NULL;
|
|
text_stream *TL_IS_18 = NULL;
|
|
text_stream *TL_IS_19 = NULL;
|
|
text_stream *TL_IS_20 = NULL;
|
|
text_stream *TL_IS_21 = NULL;
|
|
text_stream *TL_IS_22 = NULL;
|
|
text_stream *TL_IS_23 = NULL;
|
|
text_stream *TL_IS_24 = NULL;
|
|
text_stream *TL_IS_25 = NULL;
|
|
text_stream *TL_IS_26 = NULL;
|
|
text_stream *TL_IS_27 = NULL;
|
|
text_stream *TL_IS_28 = NULL;
|
|
text_stream *TL_IS_29 = NULL;
|
|
text_stream *TL_IS_30 = NULL;
|
|
text_stream *TL_IS_31 = NULL;
|
|
text_stream *TL_IS_32 = NULL;
|
|
text_stream *TL_IS_33 = NULL;
|
|
text_stream *TL_IS_34 = NULL;
|
|
text_stream *TL_IS_35 = NULL;
|
|
text_stream *TL_IS_36 = NULL;
|
|
text_stream *TL_IS_37 = NULL;
|
|
text_stream *TL_IS_38 = NULL;
|
|
text_stream *TL_IS_39 = NULL;
|
|
text_stream *TL_IS_40 = NULL;
|
|
text_stream *TL_IS_41 = NULL;
|
|
text_stream *TL_IS_42 = NULL;
|
|
text_stream *TL_IS_43 = NULL;
|
|
text_stream *TL_IS_44 = NULL;
|
|
text_stream *TL_IS_45 = NULL;
|
|
text_stream *TL_IS_46 = NULL;
|
|
text_stream *TL_IS_47 = NULL;
|
|
text_stream *TL_IS_48 = NULL;
|
|
text_stream *TL_IS_49 = NULL;
|
|
text_stream *TL_IS_50 = NULL;
|
|
text_stream *TL_IS_51 = NULL;
|
|
text_stream *TL_IS_52 = NULL;
|
|
text_stream *TL_IS_53 = NULL;
|
|
text_stream *TL_IS_54 = NULL;
|
|
text_stream *TL_IS_55 = NULL;
|
|
text_stream *TL_IS_56 = NULL;
|
|
text_stream *TL_IS_57 = NULL;
|
|
text_stream *TL_IS_58 = NULL;
|
|
text_stream *TL_IS_59 = NULL;
|
|
text_stream *TL_IS_60 = NULL;
|
|
text_stream *TL_IS_61 = NULL;
|
|
text_stream *TL_IS_62 = NULL;
|
|
text_stream *TL_IS_63 = NULL;
|
|
text_stream *TL_IS_64 = NULL;
|
|
text_stream *TL_IS_65 = NULL;
|
|
text_stream *TL_IS_66 = NULL;
|
|
text_stream *TL_IS_67 = NULL;
|
|
text_stream *TL_IS_68 = NULL;
|
|
text_stream *TL_IS_69 = NULL;
|
|
text_stream *TL_IS_70 = NULL;
|
|
text_stream *TL_IS_71 = NULL;
|
|
text_stream *TL_IS_72 = NULL;
|
|
text_stream *TL_IS_73 = NULL;
|
|
text_stream *TL_IS_74 = NULL;
|
|
text_stream *TL_IS_75 = NULL;
|
|
text_stream *TL_IS_76 = NULL;
|
|
text_stream *TL_IS_77 = NULL;
|
|
text_stream *TL_IS_78 = NULL;
|
|
text_stream *TL_IS_79 = NULL;
|
|
text_stream *TL_IS_80 = NULL;
|
|
text_stream *TL_IS_81 = NULL;
|
|
text_stream *TL_IS_82 = NULL;
|
|
text_stream *TL_IS_83 = NULL;
|
|
text_stream *TL_IS_84 = NULL;
|
|
text_stream *TL_IS_85 = NULL;
|
|
text_stream *TL_IS_86 = NULL;
|
|
text_stream *TL_IS_87 = NULL;
|
|
text_stream *TL_IS_88 = NULL;
|
|
text_stream *TL_IS_89 = NULL;
|
|
text_stream *TL_IS_90 = NULL;
|
|
text_stream *TL_IS_91 = NULL;
|
|
text_stream *TL_IS_92 = NULL;
|
|
text_stream *TL_IS_93 = NULL;
|
|
text_stream *TL_IS_94 = NULL;
|
|
text_stream *TL_IS_95 = NULL;
|
|
text_stream *TL_IS_96 = NULL;
|
|
text_stream *TL_IS_97 = NULL;
|
|
text_stream *TL_IS_98 = NULL;
|
|
text_stream *TL_IS_99 = NULL;
|
|
text_stream *TL_IS_100 = NULL;
|
|
text_stream *TL_IS_101 = NULL;
|
|
text_stream *TL_IS_102 = NULL;
|
|
text_stream *TL_IS_103 = NULL;
|
|
text_stream *TL_IS_104 = NULL;
|
|
text_stream *TL_IS_105 = NULL;
|
|
text_stream *TL_IS_106 = NULL;
|
|
text_stream *TL_IS_107 = NULL;
|
|
text_stream *TL_IS_108 = NULL;
|
|
text_stream *TL_IS_109 = NULL;
|
|
text_stream *TL_IS_110 = NULL;
|
|
text_stream *TL_IS_111 = NULL;
|
|
text_stream *TL_IS_112 = NULL;
|
|
text_stream *TL_IS_113 = NULL;
|
|
text_stream *TL_IS_114 = NULL;
|
|
text_stream *TL_IS_115 = NULL;
|
|
text_stream *TL_IS_116 = NULL;
|
|
text_stream *TL_IS_117 = NULL;
|
|
text_stream *TL_IS_118 = NULL;
|
|
text_stream *TL_IS_119 = NULL;
|
|
text_stream *TL_IS_120 = NULL;
|
|
text_stream *TL_IS_121 = NULL;
|
|
text_stream *TL_IS_122 = NULL;
|
|
text_stream *TL_IS_123 = NULL;
|
|
text_stream *TL_IS_124 = NULL;
|
|
text_stream *TL_IS_125 = NULL;
|
|
text_stream *TL_IS_126 = NULL;
|
|
text_stream *TL_IS_127 = NULL;
|
|
text_stream *TL_IS_128 = NULL;
|
|
text_stream *TL_IS_129 = NULL;
|
|
text_stream *TL_IS_130 = NULL;
|
|
text_stream *TL_IS_131 = NULL;
|
|
text_stream *TL_IS_132 = NULL;
|
|
text_stream *TL_IS_133 = NULL;
|
|
text_stream *TL_IS_134 = NULL;
|
|
text_stream *TL_IS_135 = NULL;
|
|
text_stream *TL_IS_136 = NULL;
|
|
text_stream *TL_IS_137 = NULL;
|
|
text_stream *TL_IS_138 = NULL;
|
|
text_stream *TL_IS_139 = NULL;
|
|
text_stream *TL_IS_140 = NULL;
|
|
text_stream *TL_IS_141 = NULL;
|
|
text_stream *TL_IS_142 = NULL;
|
|
text_stream *TL_IS_143 = NULL;
|
|
text_stream *TL_IS_144 = NULL;
|
|
text_stream *TL_IS_145 = NULL;
|
|
text_stream *TL_IS_146 = NULL;
|
|
text_stream *TL_IS_147 = NULL;
|
|
text_stream *TL_IS_148 = NULL;
|
|
text_stream *TL_IS_149 = NULL;
|
|
text_stream *TL_IS_150 = NULL;
|
|
text_stream *TL_IS_151 = NULL;
|
|
text_stream *TL_IS_152 = NULL;
|
|
text_stream *TL_IS_153 = NULL;
|
|
text_stream *TL_IS_154 = NULL;
|
|
text_stream *TL_IS_155 = NULL;
|
|
text_stream *TL_IS_156 = NULL;
|
|
text_stream *TL_IS_157 = NULL;
|
|
text_stream *TL_IS_158 = NULL;
|
|
text_stream *TL_IS_159 = NULL;
|
|
text_stream *TL_IS_160 = NULL;
|
|
text_stream *TL_IS_161 = NULL;
|
|
text_stream *TL_IS_162 = NULL;
|
|
text_stream *TL_IS_163 = NULL;
|
|
text_stream *TL_IS_164 = NULL;
|
|
text_stream *TL_IS_165 = NULL;
|
|
text_stream *TL_IS_166 = NULL;
|
|
text_stream *TL_IS_167 = NULL;
|
|
text_stream *TL_IS_168 = NULL;
|
|
text_stream *TL_IS_169 = NULL;
|
|
text_stream *TL_IS_170 = NULL;
|
|
text_stream *TL_IS_171 = NULL;
|
|
text_stream *TL_IS_172 = NULL;
|
|
text_stream *TL_IS_173 = NULL;
|
|
text_stream *TL_IS_174 = NULL;
|
|
text_stream *TL_IS_175 = NULL;
|
|
text_stream *TL_IS_176 = NULL;
|
|
text_stream *TL_IS_177 = NULL;
|
|
text_stream *TL_IS_178 = NULL;
|
|
text_stream *TL_IS_179 = NULL;
|
|
text_stream *TL_IS_180 = NULL;
|
|
text_stream *TL_IS_181 = NULL;
|
|
text_stream *TL_IS_182 = NULL;
|
|
text_stream *TL_IS_183 = NULL;
|
|
text_stream *TL_IS_184 = NULL;
|
|
text_stream *TL_IS_185 = NULL;
|
|
text_stream *TL_IS_186 = NULL;
|
|
text_stream *TL_IS_187 = NULL;
|
|
text_stream *TL_IS_188 = NULL;
|
|
text_stream *TL_IS_189 = NULL;
|
|
text_stream *TL_IS_190 = NULL;
|
|
text_stream *TL_IS_191 = NULL;
|
|
text_stream *TL_IS_192 = NULL;
|
|
text_stream *TL_IS_193 = NULL;
|
|
text_stream *TL_IS_194 = NULL;
|
|
text_stream *TL_IS_195 = NULL;
|
|
text_stream *TL_IS_196 = NULL;
|
|
text_stream *TL_IS_197 = NULL;
|
|
text_stream *TL_IS_198 = NULL;
|
|
text_stream *TL_IS_199 = NULL;
|
|
text_stream *TL_IS_200 = NULL;
|
|
text_stream *TL_IS_201 = NULL;
|
|
text_stream *TL_IS_202 = NULL;
|
|
text_stream *TL_IS_203 = NULL;
|
|
text_stream *TL_IS_204 = NULL;
|
|
text_stream *TL_IS_205 = NULL;
|
|
text_stream *TL_IS_206 = NULL;
|
|
text_stream *TL_IS_207 = NULL;
|
|
text_stream *TL_IS_208 = NULL;
|
|
text_stream *TL_IS_209 = NULL;
|
|
text_stream *TL_IS_210 = NULL;
|
|
text_stream *TL_IS_211 = NULL;
|
|
text_stream *TL_IS_212 = NULL;
|
|
text_stream *TL_IS_213 = NULL;
|
|
text_stream *TL_IS_214 = NULL;
|
|
text_stream *TL_IS_215 = NULL;
|
|
text_stream *TL_IS_216 = NULL;
|
|
text_stream *TL_IS_217 = NULL;
|
|
text_stream *TL_IS_218 = NULL;
|
|
text_stream *TL_IS_219 = NULL;
|
|
text_stream *TL_IS_220 = NULL;
|
|
text_stream *TL_IS_221 = NULL;
|
|
text_stream *TL_IS_222 = NULL;
|
|
text_stream *TL_IS_223 = NULL;
|
|
text_stream *TL_IS_224 = NULL;
|
|
text_stream *TL_IS_225 = NULL;
|
|
text_stream *TL_IS_226 = NULL;
|
|
text_stream *TL_IS_227 = NULL;
|
|
text_stream *TL_IS_228 = NULL;
|
|
text_stream *TL_IS_229 = NULL;
|
|
text_stream *TL_IS_230 = NULL;
|
|
text_stream *TL_IS_231 = NULL;
|
|
text_stream *TL_IS_232 = NULL;
|
|
text_stream *TL_IS_233 = NULL;
|
|
text_stream *TL_IS_234 = NULL;
|
|
text_stream *TL_IS_235 = NULL;
|
|
text_stream *TL_IS_236 = NULL;
|
|
text_stream *TL_IS_237 = NULL;
|
|
text_stream *TL_IS_238 = NULL;
|
|
text_stream *TL_IS_239 = NULL;
|
|
text_stream *TL_IS_240 = NULL;
|
|
text_stream *TL_IS_241 = NULL;
|
|
text_stream *TL_IS_242 = NULL;
|
|
text_stream *TL_IS_243 = NULL;
|
|
text_stream *TL_IS_244 = NULL;
|
|
text_stream *TL_IS_245 = NULL;
|
|
text_stream *TL_IS_246 = NULL;
|
|
text_stream *TL_IS_247 = NULL;
|
|
text_stream *TL_IS_248 = NULL;
|
|
text_stream *TL_IS_249 = NULL;
|
|
text_stream *TL_IS_250 = NULL;
|
|
text_stream *TL_IS_251 = NULL;
|
|
text_stream *TL_IS_252 = NULL;
|
|
text_stream *TL_IS_253 = NULL;
|
|
text_stream *TL_IS_254 = NULL;
|
|
text_stream *TL_IS_255 = NULL;
|
|
text_stream *TL_IS_256 = NULL;
|
|
text_stream *TL_IS_257 = NULL;
|
|
text_stream *TL_IS_258 = NULL;
|
|
text_stream *TL_IS_259 = NULL;
|
|
text_stream *TL_IS_260 = NULL;
|
|
text_stream *TL_IS_261 = NULL;
|
|
text_stream *TL_IS_262 = NULL;
|
|
text_stream *TL_IS_263 = NULL;
|
|
text_stream *TL_IS_264 = NULL;
|
|
text_stream *TL_IS_265 = NULL;
|
|
text_stream *TL_IS_266 = NULL;
|
|
text_stream *TL_IS_267 = NULL;
|
|
text_stream *TL_IS_268 = NULL;
|
|
text_stream *TL_IS_269 = NULL;
|
|
text_stream *TL_IS_270 = NULL;
|
|
text_stream *TL_IS_271 = NULL;
|
|
text_stream *TL_IS_272 = NULL;
|
|
text_stream *TL_IS_273 = NULL;
|
|
text_stream *TL_IS_274 = NULL;
|
|
text_stream *TL_IS_275 = NULL;
|
|
text_stream *TL_IS_276 = NULL;
|
|
text_stream *TL_IS_277 = NULL;
|
|
text_stream *TL_IS_278 = NULL;
|
|
text_stream *TL_IS_279 = NULL;
|
|
text_stream *TL_IS_280 = NULL;
|
|
text_stream *TL_IS_281 = NULL;
|
|
text_stream *TL_IS_282 = NULL;
|
|
text_stream *TL_IS_283 = NULL;
|
|
text_stream *TL_IS_284 = NULL;
|
|
text_stream *TL_IS_285 = NULL;
|
|
text_stream *TL_IS_286 = NULL;
|
|
text_stream *TL_IS_287 = NULL;
|
|
text_stream *TL_IS_288 = NULL;
|
|
text_stream *TL_IS_289 = NULL;
|
|
text_stream *TL_IS_290 = NULL;
|
|
text_stream *TL_IS_291 = NULL;
|
|
text_stream *TL_IS_292 = NULL;
|
|
text_stream *TL_IS_293 = NULL;
|
|
text_stream *TL_IS_294 = NULL;
|
|
text_stream *TL_IS_295 = NULL;
|
|
text_stream *TL_IS_296 = NULL;
|
|
text_stream *TL_IS_297 = NULL;
|
|
text_stream *TL_IS_298 = NULL;
|
|
text_stream *TL_IS_299 = NULL;
|
|
text_stream *TL_IS_300 = NULL;
|
|
text_stream *TL_IS_301 = NULL;
|
|
text_stream *TL_IS_302 = NULL;
|
|
text_stream *TL_IS_303 = NULL;
|
|
text_stream *TL_IS_304 = NULL;
|
|
text_stream *TL_IS_305 = NULL;
|
|
text_stream *TL_IS_306 = NULL;
|
|
text_stream *TL_IS_307 = NULL;
|
|
text_stream *TL_IS_308 = NULL;
|
|
text_stream *TL_IS_309 = NULL;
|
|
text_stream *TL_IS_310 = NULL;
|
|
text_stream *TL_IS_311 = NULL;
|
|
text_stream *TL_IS_312 = NULL;
|
|
text_stream *TL_IS_313 = NULL;
|
|
text_stream *TL_IS_314 = NULL;
|
|
text_stream *TL_IS_315 = NULL;
|
|
text_stream *TL_IS_316 = NULL;
|
|
text_stream *TL_IS_317 = NULL;
|
|
text_stream *TL_IS_318 = NULL;
|
|
text_stream *TL_IS_319 = NULL;
|
|
text_stream *TL_IS_320 = NULL;
|
|
text_stream *TL_IS_321 = NULL;
|
|
text_stream *TL_IS_322 = NULL;
|
|
text_stream *TL_IS_323 = NULL;
|
|
text_stream *TL_IS_324 = NULL;
|
|
text_stream *TL_IS_325 = NULL;
|
|
text_stream *TL_IS_326 = NULL;
|
|
text_stream *TL_IS_327 = NULL;
|
|
text_stream *TL_IS_328 = NULL;
|
|
text_stream *TL_IS_329 = NULL;
|
|
text_stream *TL_IS_330 = NULL;
|
|
text_stream *TL_IS_331 = NULL;
|
|
text_stream *TL_IS_332 = NULL;
|
|
text_stream *TL_IS_333 = NULL;
|
|
text_stream *TL_IS_334 = NULL;
|
|
text_stream *TL_IS_335 = NULL;
|
|
text_stream *TL_IS_336 = NULL;
|
|
text_stream *TL_IS_337 = NULL;
|
|
text_stream *TL_IS_338 = NULL;
|
|
text_stream *TL_IS_339 = NULL;
|
|
text_stream *TL_IS_340 = NULL;
|
|
text_stream *TL_IS_341 = NULL;
|
|
text_stream *TL_IS_342 = NULL;
|
|
text_stream *TL_IS_343 = NULL;
|
|
text_stream *TL_IS_344 = NULL;
|
|
text_stream *TL_IS_345 = NULL;
|
|
text_stream *TL_IS_346 = NULL;
|
|
text_stream *TL_IS_347 = NULL;
|
|
text_stream *TL_IS_348 = NULL;
|
|
text_stream *TL_IS_349 = NULL;
|
|
text_stream *TL_IS_350 = NULL;
|
|
text_stream *TL_IS_351 = NULL;
|
|
text_stream *TL_IS_352 = NULL;
|
|
text_stream *TL_IS_353 = NULL;
|
|
text_stream *TL_IS_354 = NULL;
|
|
text_stream *TL_IS_355 = NULL;
|
|
text_stream *TL_IS_356 = NULL;
|
|
text_stream *TL_IS_357 = NULL;
|
|
text_stream *TL_IS_358 = NULL;
|
|
text_stream *TL_IS_359 = NULL;
|
|
text_stream *TL_IS_360 = NULL;
|
|
text_stream *TL_IS_361 = NULL;
|
|
text_stream *TL_IS_362 = NULL;
|
|
text_stream *TL_IS_363 = NULL;
|
|
text_stream *TL_IS_364 = NULL;
|
|
text_stream *TL_IS_365 = NULL;
|
|
text_stream *TL_IS_366 = NULL;
|
|
text_stream *TL_IS_367 = NULL;
|
|
text_stream *TL_IS_368 = NULL;
|
|
text_stream *TL_IS_369 = NULL;
|
|
text_stream *TL_IS_370 = NULL;
|
|
text_stream *TL_IS_371 = NULL;
|
|
text_stream *TL_IS_372 = NULL;
|
|
text_stream *TL_IS_373 = NULL;
|
|
text_stream *TL_IS_374 = NULL;
|
|
text_stream *TL_IS_375 = NULL;
|
|
text_stream *TL_IS_376 = NULL;
|
|
text_stream *TL_IS_377 = NULL;
|
|
text_stream *TL_IS_378 = NULL;
|
|
text_stream *TL_IS_379 = NULL;
|
|
text_stream *TL_IS_380 = NULL;
|
|
text_stream *TL_IS_381 = NULL;
|
|
text_stream *TL_IS_382 = NULL;
|
|
text_stream *TL_IS_383 = NULL;
|
|
text_stream *TL_IS_384 = NULL;
|
|
text_stream *TL_IS_385 = NULL;
|
|
text_stream *TL_IS_386 = NULL;
|
|
text_stream *TL_IS_387 = NULL;
|
|
text_stream *TL_IS_388 = NULL;
|
|
text_stream *TL_IS_389 = NULL;
|
|
text_stream *TL_IS_390 = NULL;
|
|
text_stream *TL_IS_391 = NULL;
|
|
text_stream *TL_IS_392 = NULL;
|
|
text_stream *TL_IS_393 = NULL;
|
|
text_stream *TL_IS_394 = NULL;
|
|
text_stream *TL_IS_395 = NULL;
|
|
text_stream *TL_IS_396 = NULL;
|
|
text_stream *TL_IS_397 = NULL;
|
|
text_stream *TL_IS_398 = NULL;
|
|
text_stream *TL_IS_399 = NULL;
|
|
text_stream *TL_IS_400 = NULL;
|
|
text_stream *TL_IS_401 = NULL;
|
|
text_stream *TL_IS_402 = NULL;
|
|
text_stream *TL_IS_403 = NULL;
|
|
text_stream *TL_IS_404 = NULL;
|
|
text_stream *TL_IS_405 = NULL;
|
|
text_stream *TL_IS_406 = NULL;
|
|
text_stream *TL_IS_407 = NULL;
|
|
text_stream *TL_IS_408 = NULL;
|
|
text_stream *TL_IS_409 = NULL;
|
|
text_stream *TL_IS_410 = NULL;
|
|
text_stream *TL_IS_411 = NULL;
|
|
text_stream *TL_IS_412 = NULL;
|
|
text_stream *TL_IS_413 = NULL;
|
|
text_stream *TL_IS_414 = NULL;
|
|
text_stream *TL_IS_415 = NULL;
|
|
text_stream *TL_IS_416 = NULL;
|
|
text_stream *TL_IS_417 = NULL;
|
|
text_stream *TL_IS_418 = NULL;
|
|
text_stream *TL_IS_419 = NULL;
|
|
text_stream *TL_IS_420 = NULL;
|
|
text_stream *TL_IS_421 = NULL;
|
|
text_stream *TL_IS_422 = NULL;
|
|
text_stream *TL_IS_423 = NULL;
|
|
text_stream *TL_IS_424 = NULL;
|
|
text_stream *TL_IS_425 = NULL;
|
|
text_stream *TL_IS_426 = NULL;
|
|
text_stream *TL_IS_427 = NULL;
|
|
text_stream *TL_IS_428 = NULL;
|
|
text_stream *TL_IS_429 = NULL;
|
|
text_stream *TL_IS_430 = NULL;
|
|
text_stream *TL_IS_431 = NULL;
|
|
text_stream *TL_IS_432 = NULL;
|
|
text_stream *TL_IS_433 = NULL;
|
|
text_stream *TL_IS_434 = NULL;
|
|
text_stream *TL_IS_435 = NULL;
|
|
text_stream *TL_IS_436 = NULL;
|
|
text_stream *TL_IS_437 = NULL;
|
|
void register_tangled_text_literals(void);
|
|
#line 57 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
#define WRITE(args...) Writers__printf(OUT, args)
|
|
|
|
#define PRINT(args...) Writers__printf(STDOUT, args)
|
|
|
|
#define WRITE_TO(stream, args...) Writers__printf(stream, args)
|
|
|
|
#define LOG(args...) Writers__printf(DL, args)
|
|
|
|
#define LOGIF(aspect, args...) { \
|
|
if (Log__aspect_switched_on(aspect##_DA)) Writers__printf(DL, args); \
|
|
}
|
|
|
|
#line 50 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
text_stream *DL = NULL; /* Current destination of debugging text: kept |NULL| until opened */
|
|
|
|
#line 79 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
|
|
#line 88 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
void Foundation__start(void) {
|
|
Memory__start();
|
|
|
|
{
|
|
#line 105 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
Writers__register_writer('f', &Filenames__writer);
|
|
Writers__register_writer('p', &Pathnames__writer);
|
|
Writers__register_writer('v', &VersionNumbers__writer);
|
|
Writers__register_writer('S', &Streams__writer);
|
|
|
|
}
|
|
#line 90 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
;
|
|
register_tangled_text_literals();
|
|
;
|
|
Time__begin();
|
|
Pathnames__start();
|
|
|
|
{
|
|
#line 116 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
Log__declare_aspect(DEBUGGING_LOG_INCLUSIONS_DA, L"debugging log inclusions", FALSE, FALSE);
|
|
Log__declare_aspect(SHELL_USAGE_DA, L"shell usage", FALSE, FALSE);
|
|
Log__declare_aspect(MEMORY_USAGE_DA, L"memory usage", FALSE, FALSE);
|
|
Log__declare_aspect(TEXT_FILES_DA, L"text files", FALSE, FALSE);
|
|
|
|
}
|
|
#line 94 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
;
|
|
|
|
{
|
|
#line 127 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
Writers__register_logger('a', &Tries__log_avinue);
|
|
Writers__register_logger('S', &Streams__log);
|
|
|
|
}
|
|
#line 95 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
;
|
|
|
|
{
|
|
#line 146 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
CommandLine__begin_group(FOUNDATION_CLSG, NULL);
|
|
CommandLine__declare_switch(LOG_CLSW, L"log", 2,
|
|
L"write the debugging log to include diagnostics on X");
|
|
CommandLine__declare_switch(VERSION_CLSW, L"version", 1,
|
|
L"print out version number");
|
|
CommandLine__declare_boolean_switch(CRASH_CLSW, L"crash", 1,
|
|
L"intentionally crash on internal errors, for backtracing", FALSE);
|
|
CommandLine__declare_switch(HELP_CLSW, L"help", 1,
|
|
L"print this help information");
|
|
CommandLine__declare_boolean_switch(FIXTIME_CLSW, L"fixtime", 1,
|
|
L"pretend the time is 11 a.m. on 28 March 2016 for testing", FALSE);
|
|
CommandLine__declare_switch(AT_CLSW, L"at", 2,
|
|
L"specify that this tool is installed at X");
|
|
CommandLine__end_group();
|
|
|
|
}
|
|
#line 96 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
;
|
|
}
|
|
|
|
#line 144 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
|
|
#line 167 "inweb/foundation-module/Chapter 1/Foundation.w"
|
|
void Foundation__end(void) {
|
|
if (Log__aspect_switched_on(MEMORY_USAGE_DA)) Memory__log_statistics();
|
|
Log__close();
|
|
Memory__free();
|
|
}
|
|
|
|
#ifdef PLATFORM_POSIX
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_MACOS
|
|
#ifdef PLATFORM_POSIX
|
|
#endif /* PLATFORM_MACOS */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 81 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
#ifndef LOCALE_IS_ISO
|
|
#ifndef LOCALE_IS_UTF8
|
|
#define LOCALE_IS_UTF8 1
|
|
#endif
|
|
#endif
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_POSIX
|
|
#line 90 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
char *Platform__getenv(const char *name) {
|
|
return getenv(name);
|
|
}
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_LINUX
|
|
#ifdef PLATFORM_POSIX
|
|
#line 103 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__where_am_i(wchar_t *p, size_t length) {
|
|
char buffer[PATH_MAX + 1];
|
|
|
|
{
|
|
#ifdef PLATFORM_POSIX
|
|
#line 115 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
ssize_t link_len = readlink("/proc/self/exe", buffer, PATH_MAX);
|
|
if (link_len < 0)
|
|
{
|
|
#ifdef PLATFORM_POSIX
|
|
#line 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
p[0] = '\0';
|
|
return;
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
}
|
|
#line 116 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
; // unable to find
|
|
buffer[link_len] = '\0';
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
}
|
|
#line 105 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
;
|
|
|
|
{
|
|
#ifdef PLATFORM_POSIX
|
|
#line 124 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
size_t convert_len = mbstowcs(p, buffer, length);
|
|
if (convert_len == (size_t)-1)
|
|
{
|
|
#ifdef PLATFORM_POSIX
|
|
#line 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
p[0] = '\0';
|
|
return;
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
}
|
|
#line 125 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
; // wouldn't fit
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
}
|
|
#line 106 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
;
|
|
}
|
|
|
|
#endif /* PLATFORM_LINUX */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_UNIX
|
|
#ifdef PLATFORM_POSIX
|
|
#line 154 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__where_am_i(wchar_t *p, size_t length) {
|
|
|
|
{
|
|
#ifdef PLATFORM_POSIX
|
|
#line 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
p[0] = '\0';
|
|
return;
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
}
|
|
#line 155 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
;
|
|
}
|
|
|
|
#endif /* PLATFORM_UNIX */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_ANDROID
|
|
#ifdef PLATFORM_POSIX
|
|
#line 161 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
void Platform__where_am_i(wchar_t *p, size_t length) {
|
|
|
|
{
|
|
#ifdef PLATFORM_POSIX
|
|
#line 168 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
p[0] = '\0';
|
|
return;
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
}
|
|
#line 162 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
;
|
|
}
|
|
|
|
#endif /* PLATFORM_ANDROID */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifndef PLATFORM_MACOS
|
|
#ifdef PLATFORM_POSIX
|
|
#line 174 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
int Platform__system(const char *cmd) {
|
|
return system(cmd);
|
|
}
|
|
|
|
#endif /* PLATFORM_MACOS */
|
|
#endif /* PLATFORM_POSIX */
|
|
#ifdef PLATFORM_MACOS
|
|
#ifdef PLATFORM_POSIX
|
|
#line 199 "inweb/foundation-module/Chapter 1/POSIX Platforms.w"
|
|
#include <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, "&"); return;
|
|
case '<': Streams__literal(stream, "<"); return;
|
|
case '>': Streams__literal(stream, ">"); return;
|
|
}
|
|
}
|
|
while (stream->stream_continues) stream = stream->stream_continues;
|
|
|
|
{
|
|
#line 768 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
if (stream->chars_written + SPACE_AT_END_OF_STREAM >= stream->chars_capacity) {
|
|
if (stream->write_to_file) return; /* write nothing further */
|
|
if (stream->write_to_memory) {
|
|
int offset = (32 + 2*(stream->chars_capacity))*((int) sizeof(wchar_t));
|
|
int needed = offset + ((int) sizeof(text_stream)) + 32;
|
|
void *further_allocation = Memory__I7_malloc(needed, STREAM_MREASON);
|
|
if (further_allocation == NULL) Errors__fatal("Out of memory");
|
|
text_stream *continuation = (text_stream *) (further_allocation + offset);
|
|
Streams__initialise(continuation, FOR_CO_STRF);
|
|
continuation->write_to_memory = further_allocation;
|
|
continuation->chars_capacity = 2*stream->chars_capacity;
|
|
(continuation->write_to_memory)[0] = 0;
|
|
stream->stream_continues = continuation;
|
|
stream = continuation;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 708 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
;
|
|
if (stream->write_to_file) {
|
|
if (stream->stream_flags & FILE_ENCODING_UTF8_STRF)
|
|
|
|
{
|
|
#line 731 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
if (c >= 0x800) {
|
|
fputc(0xE0 + (c >> 12), stream->write_to_file);
|
|
fputc(0x80 + ((c >> 6) & 0x3f), stream->write_to_file);
|
|
fputc(0x80 + (c & 0x3f), stream->write_to_file);
|
|
} else if (c >= 0x80) {
|
|
fputc(0xC0 + (c >> 6), stream->write_to_file);
|
|
fputc(0x80 + (c & 0x3f), stream->write_to_file);
|
|
} else fputc((int) c, stream->write_to_file);
|
|
|
|
}
|
|
#line 711 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
|
|
else if (stream->stream_flags & FILE_ENCODING_ISO_STRF) {
|
|
if (c >= 0x100) c = '?';
|
|
fputc((int) c, stream->write_to_file);
|
|
} else internal_error("stream has unknown text encoding");
|
|
} else if (stream->write_to_memory) {
|
|
if ((c >= 0x0300) && (c <= 0x036F) && (stream->chars_written > 0)) {
|
|
c = (unsigned int) Characters__combine_accent(
|
|
(int) c, (stream->write_to_memory)[stream->chars_written - 1]);
|
|
stream->chars_written--;
|
|
}
|
|
(stream->write_to_memory)[stream->chars_written] = (wchar_t) c;
|
|
}
|
|
if (c == '\n') first_stream->stream_flags |= INDENT_PENDING_STRF;
|
|
stream->chars_written++;
|
|
}
|
|
|
|
#line 788 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__literal(text_stream *stream, char *p) {
|
|
if (stream == NULL) return;
|
|
int i, x = ((stream->stream_flags) & USES_XML_ESCAPES_STRF);
|
|
if (x) stream->stream_flags -= USES_XML_ESCAPES_STRF;
|
|
for (i=0; p[i]; i++) Streams__putc((int) p[i], stream);
|
|
if (x) stream->stream_flags += USES_XML_ESCAPES_STRF;
|
|
}
|
|
|
|
#line 802 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__indent(text_stream *stream) {
|
|
if (stream == NULL) return;
|
|
stream->stream_flags += INDENTATION_BASE_STRF;
|
|
}
|
|
|
|
void Streams__outdent(text_stream *stream) {
|
|
if (stream == NULL) return;
|
|
if ((stream->stream_flags & INDENTATION_MASK_STRF) == 0) {
|
|
if (Errors__have_occurred() == FALSE) internal_error("stream indentation negative");
|
|
return;
|
|
}
|
|
stream->stream_flags -= INDENTATION_BASE_STRF;
|
|
}
|
|
|
|
void Streams__set_indentation(text_stream *stream, int N) {
|
|
if (stream == NULL) return;
|
|
int B = stream->stream_flags & INDENTATION_MASK_STRF;
|
|
stream->stream_flags -= B;
|
|
stream->stream_flags += N*INDENTATION_BASE_STRF;
|
|
}
|
|
|
|
#line 830 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__get_position(text_stream *stream) {
|
|
int t = 0;
|
|
while (stream) {
|
|
t += stream->chars_written;
|
|
stream = stream->stream_continues;
|
|
}
|
|
return t;
|
|
}
|
|
|
|
#line 844 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
int Streams__latest(text_stream *stream) {
|
|
if (stream == NULL) return 0;
|
|
if (stream->write_to_file) internal_error("stream_latest on file stream");
|
|
while ((stream->stream_continues) && (stream->stream_continues->chars_written > 0))
|
|
stream = stream->stream_continues;
|
|
if (stream->write_to_memory) {
|
|
if (stream->chars_written > 0)
|
|
return (int) ((stream->write_to_memory)[stream->chars_written - 1]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#line 860 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
wchar_t Streams__get_char_at_index(text_stream *stream, int position) {
|
|
if (stream == NULL) internal_error("examining null stream");
|
|
if (stream->write_to_file) internal_error("examining file stream");
|
|
while (position >= stream->chars_written) {
|
|
position = position - stream->chars_written;
|
|
stream = stream->stream_continues;
|
|
if (stream == NULL) return 0;
|
|
}
|
|
if (stream->write_to_memory == NULL) return 0;
|
|
return (stream->write_to_memory)[position];
|
|
}
|
|
|
|
void Streams__put_char_at_index(text_stream *stream, int position, wchar_t C) {
|
|
if (stream == NULL) internal_error("modifying null stream");
|
|
if (stream->write_to_file) internal_error("modifying file stream");
|
|
if (stream->stream_flags & READ_ONLY_STRF) internal_error("modifying read-only stream");
|
|
while (position >= stream->chars_written) {
|
|
position = position - stream->chars_written;
|
|
stream = stream->stream_continues;
|
|
if (stream == NULL) internal_error("overrun memory stream");
|
|
}
|
|
(stream->write_to_memory)[position] = C;
|
|
if (C == 0) {
|
|
stream->chars_written = position;
|
|
if (stream->stream_continues) {
|
|
Streams__close(stream->stream_continues);
|
|
stream->stream_continues = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 898 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__set_position(text_stream *stream, int position) {
|
|
if (stream == NULL) return;
|
|
if (position < 0) position = 0; /* to simplify the implementation of backspacing */
|
|
if (stream->write_to_file) internal_error("stream_set_position on file stream");
|
|
if (stream->stream_flags & READ_ONLY_STRF) internal_error("modifying read-only stream");
|
|
if (stream->write_to_memory) {
|
|
while (position > stream->chars_written) {
|
|
position = position - stream->chars_written;
|
|
stream = stream->stream_continues;
|
|
if (stream == NULL) internal_error("can't set position forwards");
|
|
}
|
|
stream->chars_written = position;
|
|
(stream->write_to_memory)[stream->chars_written] = 0;
|
|
if (stream->stream_continues) {
|
|
Streams__close(stream->stream_continues);
|
|
stream->stream_continues = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 922 "inweb/foundation-module/Chapter 2/Streams.w"
|
|
void Streams__copy(text_stream *to, text_stream *from) {
|
|
if ((from == NULL) || (to == NULL)) return;
|
|
if (from->write_to_file) internal_error("stream_copy from file stream");
|
|
if (from->write_to_memory) {
|
|
for (int i=0; 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";
|
|
if (svn[0]) PRINT(" version %s", svn);
|
|
char *vname = "Escape to Danger";
|
|
if (vname[0]) PRINT(" '%s'", vname);
|
|
char *d = "5 April 2020";
|
|
if (d[0]) PRINT(" (%s)", d);
|
|
PRINT("\n");
|
|
innocuous = TRUE; break;
|
|
}
|
|
case HELP_CLSW: CommandLine__write_help(STDOUT); innocuous = TRUE; break;
|
|
case FIXTIME_CLSW:
|
|
if (cls->form == BOOLEAN_ON_CLSF) Time__fix();
|
|
break;
|
|
case AT_CLSW: Pathnames__set_installation_path(Pathnames__from_text(arg)); break;
|
|
default:
|
|
if (f) {
|
|
int par = -1;
|
|
switch (cls->form) {
|
|
case BOOLEAN_ON_CLSF: par = TRUE; break;
|
|
case BOOLEAN_OFF_CLSF: par = FALSE; break;
|
|
case NUMERICAL_CLSF: par = N; break;
|
|
case TEXTUAL_CLSF: arg = opt_val; break;
|
|
}
|
|
if (cls->valency == 1) (*f)(cls->switch_id, par, arg, state);
|
|
else (*f)(cls->switch_id, par, arg, state);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
#line 344 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
;
|
|
if ((innocuous == FALSE) && (substantive)) *substantive = TRUE;
|
|
return cls->valency;
|
|
}
|
|
|
|
#line 412 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
text_stream *cls_heading = NULL;
|
|
|
|
void CommandLine__declare_heading(wchar_t *heading_text_literal) {
|
|
cls_heading = Str__new_from_wide_string(heading_text_literal);
|
|
}
|
|
|
|
void CommandLine__write_help(OUTPUT_STREAM) {
|
|
command_line_switch *cls;
|
|
int max = 0, N = 0;
|
|
LOOP_OVER(cls, command_line_switch) {
|
|
int L = Str__len(cls->switch_name);
|
|
if (L > max) max = L;
|
|
N++;
|
|
}
|
|
command_line_switch **sorted_table =
|
|
Memory__I7_calloc(N, (int) sizeof(command_line_switch *), CLS_SORTING_MREASON);
|
|
int i=0; LOOP_OVER(cls, command_line_switch) sorted_table[i++] = cls;
|
|
qsort(sorted_table, (size_t) N, sizeof(command_line_switch *), CommandLine__compare_names);
|
|
|
|
if (Str__len(cls_heading) > 0) WRITE("%S\n", cls_heading);
|
|
int filter = NO_CLSG, new_para_needed = FALSE;
|
|
|
|
{
|
|
#line 444 "inweb/foundation-module/Chapter 3/Command Line Arguments.w"
|
|
if (new_para_needed) {
|
|
WRITE("\n");
|
|
new_para_needed = FALSE;
|
|
}
|
|
for (int i=0; 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 204 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
int Pathnames__create_in_file_system(pathname *P) {
|
|
if (P == NULL) return TRUE; /* the root of the file system always exists */
|
|
if (P->known_to_exist) return TRUE;
|
|
char transcoded_pathname[4*MAX_FILENAME_LENGTH];
|
|
TEMPORARY_TEXT(pn);
|
|
WRITE_TO(pn, "%p", P);
|
|
Str__copy_to_locale_string(transcoded_pathname, pn, 4*MAX_FILENAME_LENGTH);
|
|
DISCARD_TEXT(pn);
|
|
P->known_to_exist = Platform__mkdir(transcoded_pathname);
|
|
return P->known_to_exist;
|
|
}
|
|
|
|
#line 222 "inweb/foundation-module/Chapter 3/Pathnames.w"
|
|
void Pathnames__rsync(pathname *source, pathname *dest) {
|
|
char transcoded_source[4*MAX_FILENAME_LENGTH];
|
|
TEMPORARY_TEXT(pn);
|
|
WRITE_TO(pn, "%p", source);
|
|
Str__copy_to_locale_string(transcoded_source, pn, 4*MAX_FILENAME_LENGTH);
|
|
DISCARD_TEXT(pn);
|
|
char transcoded_dest[4*MAX_FILENAME_LENGTH];
|
|
TEMPORARY_TEXT(pn2);
|
|
WRITE_TO(pn2, "%p", dest);
|
|
Str__copy_to_locale_string(transcoded_dest, pn2, 4*MAX_FILENAME_LENGTH);
|
|
DISCARD_TEXT(pn2);
|
|
Platform__rsync(transcoded_source, transcoded_dest);
|
|
}
|
|
|
|
#line 19 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
|
|
#line 24 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename *Filenames__in_folder(pathname *P, text_stream *file_name) {
|
|
return Filenames__primitive(file_name, 0, Str__len(file_name), P);
|
|
}
|
|
|
|
filename *Filenames__primitive(text_stream *S, int from, int to, pathname *P) {
|
|
filename *F = CREATE(filename);
|
|
F->pathname_of_location = P;
|
|
if (to-from <= 0)
|
|
internal_error("empty intermediate pathname");
|
|
F->leafname = Str__new_with_capacity(to-from+1);
|
|
string_position pos = Str__at(S, from);
|
|
for (int i = from; i < to; i++, pos = Str__forward(pos))
|
|
PUT_TO(F->leafname, Str__get(pos));
|
|
return F;
|
|
}
|
|
|
|
#line 44 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
filename *Filenames__from_text(text_stream *path) {
|
|
int i = 0, pos = -1;
|
|
LOOP_THROUGH_TEXT(at, path) {
|
|
if (Str__get(at) == FOLDER_SEPARATOR) pos = i;
|
|
i++;
|
|
}
|
|
pathname *P = NULL;
|
|
if (pos >= 0) {
|
|
TEMPORARY_TEXT(PT);
|
|
Str__substr(PT, Str__at(path, 0), Str__at(path, pos));
|
|
P = Pathnames__from_text(PT);
|
|
DISCARD_TEXT(PT);
|
|
}
|
|
return Filenames__primitive(path, pos+1, Str__len(path), P);
|
|
}
|
|
|
|
filename *Filenames__from_text_relative(pathname *from, text_stream *path) {
|
|
filename *F = Filenames__from_text(path);
|
|
if (from) {
|
|
if (F->pathname_of_location == NULL) F->pathname_of_location = from;
|
|
else {
|
|
pathname *P = F->pathname_of_location;
|
|
while ((P) && (P->pathname_of_parent)) P = P->pathname_of_parent;
|
|
P->pathname_of_parent = from;
|
|
}
|
|
}
|
|
return F;
|
|
}
|
|
|
|
#line 77 "inweb/foundation-module/Chapter 3/Filenames.w"
|
|
void Filenames__writer(OUTPUT_STREAM, char *format_string, void *vF) {
|
|
filename *F = (filename *) vF;
|
|
if (F == NULL) WRITE("<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 176 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
char *p;
|
|
size_t extdirindex = 0, extindex = 0, namelen = 0, dirlen = 0;
|
|
|
|
p = strrchr(path, FOLDER_SEPARATOR);
|
|
if (p) {
|
|
extindex = (size_t) (p - path);
|
|
namelen = length - extindex - 1;
|
|
strncpy(ciextname, path + extindex + 1, namelen);
|
|
}
|
|
ciextname[namelen] = 0;
|
|
|
|
strncpy(workstring, path, extindex);
|
|
workstring[extindex] = 0;
|
|
p = strrchr(workstring, FOLDER_SEPARATOR);
|
|
if (p) {
|
|
extdirindex = (size_t) (p - workstring);
|
|
strncpy(topdirpath, path, extdirindex);
|
|
}
|
|
topdirpath[extdirindex] = 0;
|
|
|
|
dirlen = extindex - extdirindex;
|
|
if (dirlen > 0) dirlen -= 1;
|
|
strncpy(ciextdirpath, path + extdirindex + 1, dirlen);
|
|
ciextdirpath[dirlen] = 0;
|
|
|
|
}
|
|
#line 61 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
|
|
topdir = opendir(topdirpath); /* whose pathname is assumed case-correct... */
|
|
if (topdir == NULL)
|
|
{
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return NULL;
|
|
|
|
}
|
|
#line 64 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
; /* ...so that failure is fatal; |errno| is set by |opendir| */
|
|
|
|
sprintf(workstring, "%s%c%s", topdirpath, FOLDER_SEPARATOR, ciextdirpath);
|
|
extdir = opendir(workstring); /* try with supplied extension directory name */
|
|
if (extdir == NULL)
|
|
{
|
|
#line 83 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
int rc = CIFilingSystem__match_in_directory(topdir, ciextdirpath, workstring);
|
|
switch (rc) {
|
|
case 0:
|
|
errno = ENOENT;
|
|
{
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return NULL;
|
|
|
|
}
|
|
#line 86 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
case 1:
|
|
sprintf(cistring, "%s%c%s", topdirpath, FOLDER_SEPARATOR, workstring);
|
|
extdir = opendir(cistring);
|
|
if (extdir == NULL) {
|
|
errno = ENOENT;
|
|
{
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return NULL;
|
|
|
|
}
|
|
#line 91 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
}
|
|
break;
|
|
default:
|
|
errno = EBADF;
|
|
{
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return NULL;
|
|
|
|
}
|
|
#line 95 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
}
|
|
|
|
}
|
|
#line 68 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
else strcpy(cistring, workstring);
|
|
|
|
sprintf(workstring, "%s%c%s", cistring, FOLDER_SEPARATOR, ciextname);
|
|
handle = fopen(workstring, mode); /* try with supplied name */
|
|
if (handle)
|
|
{
|
|
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return handle;
|
|
|
|
}
|
|
#line 73 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
|
|
|
|
{
|
|
#line 102 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
int rc = CIFilingSystem__match_in_directory(extdir, ciextname, workstring);
|
|
|
|
switch (rc) {
|
|
case 0:
|
|
errno = ENOENT;
|
|
{
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return NULL;
|
|
|
|
}
|
|
#line 106 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
case 1:
|
|
sprintf(workstring2, "%s%c%s", cistring, FOLDER_SEPARATOR, workstring);
|
|
workstring2[length] = 0;
|
|
handle = fopen(workstring2, mode);
|
|
if (handle)
|
|
{
|
|
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 137 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return handle;
|
|
|
|
}
|
|
#line 111 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
errno = ENOENT;
|
|
{
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return NULL;
|
|
|
|
}
|
|
#line 112 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
default:
|
|
errno = EBADF;
|
|
{
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
|
|
{
|
|
#line 147 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
if (workstring) free(workstring);
|
|
if (workstring2) free(workstring2);
|
|
if (topdirpath) free(topdirpath);
|
|
if (ciextdirpath) free(ciextdirpath);
|
|
if (cistring) free(cistring);
|
|
if (ciextname) free(ciextname);
|
|
if (topdir) closedir(topdir);
|
|
if (extdir) closedir(extdir);
|
|
|
|
}
|
|
#line 143 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
return NULL;
|
|
|
|
}
|
|
#line 114 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
}
|
|
|
|
}
|
|
#line 75 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
;
|
|
}
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
#line 212 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
int CIFilingSystem__match_in_directory(void *vd,
|
|
char *name, char *last_match) {
|
|
DIR *d = (DIR *) vd;
|
|
struct dirent *dirp;
|
|
int rc = 0;
|
|
|
|
last_match[0] = 0;
|
|
while ((dirp = readdir(d)) != NULL) {
|
|
if (strcasecmp(name, dirp->d_name) == 0) {
|
|
rc++;
|
|
strcpy(last_match, dirp->d_name);
|
|
}
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
#ifndef PLATFORM_POSIX
|
|
#line 232 "inweb/foundation-module/Chapter 3/Case-Insensitive Filenames.w"
|
|
FILE *CIFilingSystem__fopen(const char *path, const char *mode) {
|
|
return fopen(path, mode);
|
|
}
|
|
|
|
#endif /* PLATFORM_POSIX */
|
|
#line 14 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__quote_path(OUTPUT_STREAM, pathname *P) {
|
|
TEMPORARY_TEXT(FN);
|
|
WRITE_TO(FN, "%p", P);
|
|
Shell__quote_text(OUT, FN);
|
|
DISCARD_TEXT(FN);
|
|
}
|
|
|
|
void Shell__quote_file(OUTPUT_STREAM, filename *F) {
|
|
TEMPORARY_TEXT(FN);
|
|
WRITE_TO(FN, "%f", F);
|
|
Shell__quote_text(OUT, FN);
|
|
DISCARD_TEXT(FN);
|
|
}
|
|
|
|
void Shell__plain(OUTPUT_STREAM, char *raw) {
|
|
WRITE("%s", raw);
|
|
}
|
|
|
|
void Shell__plain_text(OUTPUT_STREAM, text_stream *raw) {
|
|
WRITE("%S", raw);
|
|
}
|
|
|
|
void Shell__quote_text(OUTPUT_STREAM, text_stream *raw) {
|
|
PUT(SHELL_QUOTE_CHARACTER);
|
|
LOOP_THROUGH_TEXT(pos, raw) {
|
|
wchar_t c = Str__get(pos);
|
|
if (c == SHELL_QUOTE_CHARACTER) PUT('\\');
|
|
PUT(c);
|
|
}
|
|
PUT(SHELL_QUOTE_CHARACTER);
|
|
PUT(' ');
|
|
}
|
|
|
|
#line 50 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__apply(char *command, filename *F) {
|
|
TEMPORARY_TEXT(COMMAND)
|
|
Shell__plain(COMMAND, command);
|
|
Shell__plain(COMMAND, " ");
|
|
Shell__quote_file(COMMAND, F);
|
|
Shell__run(COMMAND);
|
|
DISCARD_TEXT(COMMAND)
|
|
}
|
|
void Shell__apply_S(text_stream *command, filename *F) {
|
|
TEMPORARY_TEXT(COMMAND)
|
|
Shell__plain_text(COMMAND, command);
|
|
Shell__plain(COMMAND, " ");
|
|
Shell__quote_file(COMMAND, F);
|
|
Shell__run(COMMAND);
|
|
DISCARD_TEXT(COMMAND)
|
|
}
|
|
|
|
#line 70 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__rm(filename *F) {
|
|
Shell__apply("rm", F);
|
|
}
|
|
|
|
void Shell__copy(filename *F, pathname *T, char *options) {
|
|
TEMPORARY_TEXT(COMMAND)
|
|
Shell__plain(COMMAND, "cp ");
|
|
Shell__plain(COMMAND, options);
|
|
Shell__plain(COMMAND, " ");
|
|
Shell__quote_file(COMMAND, F);
|
|
Shell__quote_path(COMMAND, T);
|
|
Shell__run(COMMAND);
|
|
DISCARD_TEXT(COMMAND)
|
|
}
|
|
|
|
#line 89 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
void Shell__redirect(OUTPUT_STREAM, filename *F) {
|
|
Shell__plain(OUT, ">");
|
|
Shell__quote_file(OUT, F);
|
|
Shell__plain(OUT, "2>&1");
|
|
}
|
|
|
|
#line 105 "inweb/foundation-module/Chapter 3/Shell.w"
|
|
int shell_verbosity = FALSE;
|
|
void Shell__verbose(void) {
|
|
shell_verbosity = TRUE;
|
|
}
|
|
|
|
int Shell__run(OUTPUT_STREAM) {
|
|
if (shell_verbosity) PRINT("shell: %S\n", OUT);
|
|
LOGIF(SHELL_USAGE, "shell: %S\n", OUT);
|
|
char spool[SPOOL_LENGTH];
|
|
Streams__write_as_locale_string(spool, OUT, SPOOL_LENGTH);
|
|
int rv = Platform__system(spool);
|
|
if (rv == -1) {
|
|
WRITE_TO(STDERR, "shell: %S\n", OUT);
|
|
internal_error("OS shell error");
|
|
}
|
|
if (rv == 127) {
|
|
WRITE_TO(STDERR, "shell: %S\n", OUT);
|
|
internal_error("Execution of the shell failed");
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
#line 13 "inweb/foundation-module/Chapter 3/Directories.w"
|
|
|
|
#line 19 "inweb/foundation-module/Chapter 3/Directories.w"
|
|
scan_directory *Directories__open(pathname *P) {
|
|
scan_directory *D = CREATE(scan_directory);
|
|
TEMPORARY_TEXT(pn);
|
|
WRITE_TO(pn, "%p", P);
|
|
Str__copy_to_locale_string(D->directory_name_written_out, pn, 4*MAX_FILENAME_LENGTH);
|
|
DISCARD_TEXT(pn);
|
|
D->directory_handle = Platform__opendir(D->directory_name_written_out);
|
|
if (D->directory_handle == NULL) return NULL;
|
|
return D;
|
|
}
|
|
|
|
int Directories__next(scan_directory *D, text_stream *leafname) {
|
|
char leafname_Cs[MAX_FILENAME_LENGTH];
|
|
int rv = TRUE;
|
|
while (rv) {
|
|
rv = Platform__readdir(D->directory_handle, D->directory_name_written_out, leafname_Cs);
|
|
if (leafname_Cs[0] != '.') break;
|
|
}
|
|
Str__clear(leafname);
|
|
if (rv) Streams__write_locale_string(leafname, leafname_Cs);
|
|
return rv;
|
|
}
|
|
|
|
void Directories__close(scan_directory *D) {
|
|
Platform__closedir(D->directory_handle);
|
|
}
|
|
|
|
#line 9 "inweb/foundation-module/Chapter 3/Time.w"
|
|
time_t right_now;
|
|
struct tm *the_present = NULL;
|
|
int fix_time_mode = FALSE;
|
|
|
|
void Time__begin(void) {
|
|
time_t right_now = time(NULL);
|
|
the_present = localtime(&right_now);
|
|
fix_time_mode = FALSE;
|
|
}
|
|
|
|
#line 26 "inweb/foundation-module/Chapter 3/Time.w"
|
|
void Time__fix(void) {
|
|
struct tm start;
|
|
start.tm_sec = 0; start.tm_min = 0; start.tm_hour = 11;
|
|
start.tm_mday = 28; start.tm_mon = 3; start.tm_year = 116; start.tm_isdst = -1;
|
|
time_t pretend_time = mktime(&start);
|
|
the_present = localtime(&pretend_time);
|
|
fix_time_mode = TRUE;
|
|
}
|
|
|
|
int Time__fixed(void) {
|
|
return fix_time_mode;
|
|
}
|
|
|
|
#line 84 "inweb/foundation-module/Chapter 3/Time.w"
|
|
int Time__feast(void) {
|
|
int this_month = the_present->tm_mon + 1;
|
|
int this_day = the_present->tm_mday;
|
|
int this_year = the_present->tm_year + 1900;
|
|
|
|
int c, y, k, i, n, j, l, m, d;
|
|
y = this_year;
|
|
c = y/100;
|
|
n = y-19*(y/19);
|
|
k = (c-17)/25;
|
|
i = c-c/4-(c-k)/3+19*n+15;
|
|
i = i-30*(i/30);
|
|
i = i-(i/28)*(1-(i/28)*(29/(i+1))*((21-n)/11));
|
|
j = y+y/4+i+2-c+c/4;
|
|
j = j-7*(j/7);
|
|
l = i-j;
|
|
m = 3+(l+40)/44;
|
|
d = l+28-31*(m/4);
|
|
|
|
if ((this_month == m) && (this_day >= d-2) && (this_day <= d+1))
|
|
return EASTER_FEAST; /* that is, Good Friday to Easter Monday */
|
|
if ((this_year == 2018) && (this_month == 3) && (this_day >= 30))
|
|
return EASTER_FEAST; /* Easter Sunday falls on 1 April in 2018 */
|
|
|
|
if ((this_month == 12) && (this_day >= 25))
|
|
return CHRISTMAS_FEAST; /* that is, Christmas Day to New Year's Eve */
|
|
|
|
return NON_FEAST;
|
|
}
|
|
|
|
#line 8 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
wchar_t Characters__tolower(wchar_t c) {
|
|
return (wchar_t) tolower((int) c);
|
|
}
|
|
wchar_t Characters__toupper(wchar_t c) {
|
|
return (wchar_t) toupper((int) c);
|
|
}
|
|
int Characters__isalpha(wchar_t c) {
|
|
return isalpha((int) c);
|
|
}
|
|
int Characters__isdigit(wchar_t c) {
|
|
return isdigit((int) c);
|
|
}
|
|
int Characters__isupper(wchar_t c) {
|
|
return isupper((int) c);
|
|
}
|
|
int Characters__islower(wchar_t c) {
|
|
return islower((int) c);
|
|
}
|
|
int Characters__isalnum(wchar_t c) {
|
|
return isalnum((int) c);
|
|
}
|
|
int Characters__vowel(wchar_t c) {
|
|
if ((c == 'a') || (c == 'e') || (c == 'i') || (c == 'o') || (c == 'u')) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
#line 37 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__is_space_or_tab(int c) {
|
|
if ((c == ' ') || (c == '\t')) return TRUE;
|
|
return FALSE;
|
|
}
|
|
int Characters__is_whitespace(int c) {
|
|
if ((c == ' ') || (c == '\t') || (c == '\n')) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
#line 51 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__is_babel_whitespace(int c) {
|
|
if ((c == ' ') || (c == '\t') || (c == '\x0a')
|
|
|| (c == '\x0d') || (c == NEWLINE_IN_STRING)) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
#line 62 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__combine_accent(int accent, int letter) {
|
|
switch(accent) {
|
|
case 0x0300: /* Unicode combining grave */
|
|
switch(letter) {
|
|
case 'a': return 0xE0; case 'e': return 0xE8; case 'i': return 0xEC;
|
|
case 'o': return 0xF2; case 'u': return 0xF9;
|
|
case 'A': return 0xC0; case 'E': return 0xC8; case 'I': return 0xCC;
|
|
case 'O': return 0xD2; case 'U': return 0xD9;
|
|
}
|
|
break;
|
|
case 0x0301: /* Unicode combining acute */
|
|
switch(letter) {
|
|
case 'a': return 0xE1; case 'e': return 0xE9; case 'i': return 0xED;
|
|
case 'o': return 0xF3; case 'u': return 0xFA; case 'y': return 0xFF;
|
|
case 'A': return 0xC1; case 'E': return 0xC9; case 'I': return 0xCD;
|
|
case 'O': return 0xD3; case 'U': return 0xDA;
|
|
}
|
|
break;
|
|
case 0x0302: /* Unicode combining circumflex */
|
|
switch(letter) {
|
|
case 'a': return 0xE2; case 'e': return 0xEA; case 'i': return 0xEE;
|
|
case 'o': return 0xF4; case 'u': return 0xFB;
|
|
case 'A': return 0xC2; case 'E': return 0xCA; case 'I': return 0xCE;
|
|
case 'O': return 0xD4; case 'U': return 0xDB;
|
|
}
|
|
break;
|
|
case 0x0303: /* Unicode combining tilde */
|
|
switch(letter) {
|
|
case 'a': return 0xE3; case 'n': return 0xF1; case 'o': return 0xF5;
|
|
case 'A': return 0xC3; case 'N': return 0xD1; case 'O': return 0xD5;
|
|
}
|
|
break;
|
|
case 0x0308: /* Unicode combining diaeresis */
|
|
switch(letter) {
|
|
case 'a': return 0xE4; case 'e': return 0xEB; case 'u': return 0xFC;
|
|
case 'o': return 0xF6; case 'i': return 0xEF;
|
|
case 'A': return 0xC4; case 'E': return 0xCB; case 'U': return 0xDC;
|
|
case 'O': return 0xD6; case 'I': return 0xCF;
|
|
}
|
|
break;
|
|
case 0x0327: /* Unicode combining cedilla */
|
|
switch(letter) {
|
|
case 'c': return 0xE7; case 'C': return 0xC7;
|
|
}
|
|
break;
|
|
}
|
|
return '?';
|
|
}
|
|
|
|
#line 116 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__make_filename_safe(int charcode) {
|
|
charcode = Characters__remove_accent(charcode);
|
|
if (charcode >= 128) charcode = '-';
|
|
return charcode;
|
|
}
|
|
|
|
#line 125 "inweb/foundation-module/Chapter 4/Characters.w"
|
|
int Characters__remove_accent(int charcode) {
|
|
switch (charcode) {
|
|
case 0xC0: case 0xC1: case 0xC2: case 0xC3:
|
|
case 0xC4: case 0xC5: charcode = 'A'; break;
|
|
case 0xE0: case 0xE1: case 0xE2: case 0xE3:
|
|
case 0xE4: case 0xE5: charcode = 'a'; break;
|
|
case 0xC8: case 0xC9: case 0xCA: case 0xCB: charcode = 'E'; break;
|
|
case 0xE8: case 0xE9: case 0xEA: case 0xEB: charcode = 'e'; break;
|
|
case 0xCC: case 0xCD: case 0xCE: case 0xCF: charcode = 'I'; break;
|
|
case 0xEC: case 0xED: case 0xEE: case 0xEF: charcode = 'i'; break;
|
|
case 0xD2: case 0xD3: case 0xD4: case 0xD5:
|
|
case 0xD6: case 0xD8: charcode = 'O'; break;
|
|
case 0xF2: case 0xF3: case 0xF4: case 0xF5:
|
|
case 0xF6: case 0xF8: charcode = 'o'; break;
|
|
case 0xD9: case 0xDA: case 0xDB: case 0xDC: charcode = 'U'; break;
|
|
case 0xF9: case 0xFA: case 0xFB: case 0xFC: charcode = 'u'; break;
|
|
case 0xDD: charcode = 'Y'; break;
|
|
case 0xFD: charcode = 'y'; break;
|
|
case 0xD1: charcode = 'N'; break;
|
|
case 0xF1: charcode = 'n'; break;
|
|
case 0xC7: charcode = 'C'; break;
|
|
case 0xE7: charcode = 'c'; break;
|
|
case 0xDF: charcode = 's'; break;
|
|
}
|
|
return charcode;
|
|
}
|
|
|
|
#line 21 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
|
|
#line 25 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__strlen_unbounded(const char *p) {
|
|
return (int) strlen(p);
|
|
}
|
|
|
|
#line 35 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__check_len(int n) {
|
|
if ((n > MAX_STRING_LENGTH) || (n < 0)) Errors__fatal("String overflow\n");
|
|
return n;
|
|
}
|
|
|
|
#line 44 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__len(char *str) {
|
|
for (int i=0; i<=MAX_STRING_LENGTH; i++)
|
|
if (str[i] == 0) return i;
|
|
str[MAX_STRING_LENGTH] = 0;
|
|
return MAX_STRING_LENGTH;
|
|
}
|
|
|
|
#line 55 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
void CStrings__copy(char *to, char *from) {
|
|
CStrings__check_len(CStrings__len(from));
|
|
int i;
|
|
for (i=0; ((from[i]) && (i < MAX_STRING_LENGTH)); i++) to[i] = from[i];
|
|
to[i] = 0;
|
|
}
|
|
|
|
#line 65 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__ne(char *A, char *B) {
|
|
return (CStrings__cmp(A, B) == 0)?FALSE:TRUE;
|
|
}
|
|
|
|
#line 72 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
int CStrings__cmp(char *A, char *B) {
|
|
if ((A == NULL) || (A[0] == 0)) {
|
|
if ((B == NULL) || (B[0] == 0)) return 0;
|
|
return -1;
|
|
}
|
|
if ((B == NULL) || (B[0] == 0)) return 1;
|
|
return strcmp(A, B);
|
|
}
|
|
|
|
#line 85 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
void CStrings__transcode_ISO_string_to_UTF8(char *p, char *dest) {
|
|
int i, j;
|
|
for (i=0, j=0; p[i]; i++) {
|
|
int charcode = (int) (((unsigned char *)p)[i]);
|
|
if (charcode >= 128) {
|
|
dest[j++] = (char) (0xC0 + (charcode >> 6));
|
|
dest[j++] = (char) (0x80 + (charcode & 0x3f));
|
|
} else {
|
|
dest[j++] = p[i];
|
|
}
|
|
}
|
|
dest[j] = 0;
|
|
}
|
|
|
|
#line 106 "inweb/foundation-module/Chapter 4/C Strings.w"
|
|
void CStrings__truncated_strcpy(char *to, char *from, int max) {
|
|
int i;
|
|
for (i=0; ((from[i]) && (i<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;
|
|
}
|
|
|
|
#line 582 "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 594 "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 588 "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 135 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
|
|
#line 143 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
match_results Regexp__create_mr(void) {
|
|
match_results mr;
|
|
mr.no_matched_texts = 0;
|
|
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++)
|
|
mr.exp[i] = NULL;
|
|
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 165 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__match(match_results *mr, text_stream *text, wchar_t *pattern) {
|
|
if (mr) Regexp__prepare(mr);
|
|
int rv = (Regexp__match_r(mr, text, pattern, NULL, FALSE) >= 0)?TRUE:FALSE;
|
|
if ((mr) && (rv == FALSE)) Regexp__dispose_of(mr);
|
|
return rv;
|
|
}
|
|
|
|
void Regexp__prepare(match_results *mr) {
|
|
if (mr) {
|
|
mr->no_matched_texts = 0;
|
|
for (int i=0; i<MAX_BRACKETED_SUBEXPRESSIONS; i++) {
|
|
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 187 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__match_r(match_results *mr, text_stream *text, wchar_t *pattern,
|
|
match_position *scan_from, int allow_partial) {
|
|
match_position at;
|
|
if (scan_from) at = *scan_from;
|
|
else { at.tpos = 0; at.ppos = 0; at.bc = 0; at.bl = 0; }
|
|
|
|
while ((Str__get_at(text, at.tpos)) || (pattern[at.ppos])) {
|
|
if ((allow_partial) && (pattern[at.ppos] == 0)) break;
|
|
|
|
{
|
|
#line 222 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
if (pattern[at.ppos] == '(') {
|
|
if (at.bl < MAX_BRACKETED_SUBEXPRESSIONS) at.bracket_nesting[at.bl] = -1;
|
|
if (at.bc < MAX_BRACKETED_SUBEXPRESSIONS) {
|
|
at.bracket_nesting[at.bl] = at.bc;
|
|
at.brackets_start[at.bc] = at.tpos; at.brackets_end[at.bc] = -1;
|
|
}
|
|
at.bl++; at.bc++; at.ppos++;
|
|
continue;
|
|
}
|
|
if (pattern[at.ppos] == ')') {
|
|
at.bl--;
|
|
if ((at.bl >= 0) && (at.bl < MAX_BRACKETED_SUBEXPRESSIONS) && (at.bracket_nesting[at.bl] >= 0))
|
|
at.brackets_end[at.bracket_nesting[at.bl]] = at.tpos-1;
|
|
at.ppos++;
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 195 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
;
|
|
|
|
int chcl, /* what class of characters to match: a |*_CLASS| value */
|
|
range_from, range_to, /* for |LITERAL_CLASS| only */
|
|
reverse = FALSE; /* require a non-match rather than a match */
|
|
|
|
{
|
|
#line 240 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int len;
|
|
chcl = Regexp__get_cclass(pattern, at.ppos, &len, &range_from, &range_to, &reverse);
|
|
at.ppos += len;
|
|
|
|
}
|
|
#line 200 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
;
|
|
|
|
int rep_from = 1, rep_to = 1; /* minimum and maximum number of repetitions */
|
|
int greedy = TRUE; /* go for a maximal-length match if possible */
|
|
|
|
{
|
|
#line 248 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
if (chcl == WHITESPACE_CLASS) {
|
|
rep_from = 1; rep_to = Str__len(text)-at.tpos;
|
|
}
|
|
if (pattern[at.ppos] == '+') {
|
|
rep_from = 1; rep_to = Str__len(text)-at.tpos; at.ppos++;
|
|
} else if (pattern[at.ppos] == '*') {
|
|
rep_from = 0; rep_to = Str__len(text)-at.tpos; at.ppos++;
|
|
}
|
|
if (pattern[at.ppos] == '?') { greedy = FALSE; at.ppos++; }
|
|
|
|
}
|
|
#line 204 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
;
|
|
|
|
int reps = 0;
|
|
|
|
{
|
|
#line 259 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
for (reps = 0; ((Str__get_at(text, at.tpos+reps)) && (reps < rep_to)); reps++)
|
|
if (Regexp__test_cclass(Str__get_at(text, at.tpos+reps), chcl,
|
|
range_from, range_to, pattern, reverse) == FALSE)
|
|
break;
|
|
|
|
}
|
|
#line 207 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
;
|
|
if (reps < rep_from) return -1;
|
|
|
|
/* we can now accept anything from |rep_from| to |reps| repetitions */
|
|
if (rep_from == reps) { at.tpos += reps; continue; }
|
|
|
|
{
|
|
#line 265 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int from = rep_from, to = reps, dj = 1, from_tpos = at.tpos;
|
|
if (greedy) { from = reps; to = rep_from; dj = -1; }
|
|
for (int j = from; j != to+dj; j += dj) {
|
|
at.tpos = from_tpos + j;
|
|
int try = Regexp__match_r(mr, text, pattern, &at, allow_partial);
|
|
if (try >= 0) return try;
|
|
}
|
|
|
|
}
|
|
#line 212 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
;
|
|
|
|
/* no match length worked, so no match */
|
|
return -1;
|
|
}
|
|
|
|
{
|
|
#line 274 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
if (mr) {
|
|
for (int i=0; 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->no_matched_texts = at.bc;
|
|
}
|
|
|
|
}
|
|
#line 217 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
;
|
|
return at.tpos;
|
|
}
|
|
|
|
#line 315 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__get_cclass(wchar_t *pattern, int ppos, int *len, int *from, int *to, int *reverse) {
|
|
if (pattern[ppos] == '^') { ppos++; *reverse = TRUE; } else { *reverse = FALSE; }
|
|
switch (pattern[ppos]) {
|
|
case '%':
|
|
ppos++;
|
|
*len = 2;
|
|
switch (pattern[ppos]) {
|
|
case 'd': return DIGIT_CLASS;
|
|
case 'c': return ANY_CLASS;
|
|
case 'C': return NONWHITESPACE_CLASS;
|
|
case 'i': return IDENTIFIER_CLASS;
|
|
case 'p': return PREFORM_CLASS;
|
|
case 'P': return PREFORMC_CLASS;
|
|
case 'q': return QUOTE_CLASS;
|
|
case 't': return TAB_CLASS;
|
|
}
|
|
*from = ppos; *to = ppos; return LITERAL_CLASS;
|
|
case '[':
|
|
*from = ppos+2;
|
|
while ((pattern[ppos]) && (pattern[ppos] != ']')) ppos++;
|
|
*to = ppos - 1; *len = ppos - *from + 1;
|
|
return LITERAL_CLASS;
|
|
case ' ':
|
|
*len = 1; return WHITESPACE_CLASS;
|
|
}
|
|
*len = 1; *from = ppos; *to = ppos; return LITERAL_CLASS;
|
|
}
|
|
|
|
#line 344 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__test_cclass(int c, int chcl, int range_from, int range_to, wchar_t *drawn_from, int reverse) {
|
|
int match = FALSE;
|
|
switch (chcl) {
|
|
case ANY_CLASS: if (c) match = TRUE; break;
|
|
case DIGIT_CLASS: if (isdigit(c)) match = TRUE; break;
|
|
case WHITESPACE_CLASS: if (Characters__is_space_or_tab(c)) match = TRUE; break;
|
|
case TAB_CLASS: if (c == '\t') match = TRUE; break;
|
|
case NONWHITESPACE_CLASS: if (!(Characters__is_space_or_tab(c))) match = TRUE; break;
|
|
case QUOTE_CLASS: if (c != '\"') match = TRUE; break;
|
|
case IDENTIFIER_CLASS: if (Regexp__identifier_char(c)) match = TRUE; break;
|
|
case PREFORM_CLASS: if ((c == '-') || (c == '_') ||
|
|
((c >= 'a') && (c <= 'z')) ||
|
|
((c >= '0') && (c <= '9'))) match = TRUE; break;
|
|
case PREFORMC_CLASS: if ((c == '-') || (c == '_') || (c == ':') ||
|
|
((c >= 'a') && (c <= 'z')) ||
|
|
((c >= '0') && (c <= '9'))) match = TRUE; break;
|
|
case LITERAL_CLASS:
|
|
for (int j = range_from; j <= range_to; j++) {
|
|
int c1 = drawn_from[j], c2 = c1;
|
|
if ((j+1 < range_to) && (drawn_from[j+1] == '-')) { c2 = drawn_from[j+2]; j += 2; }
|
|
if ((c >= c1) && (c <= c2)) {
|
|
match = TRUE; break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (reverse) match = (match)?FALSE:TRUE;
|
|
return match;
|
|
}
|
|
|
|
#line 388 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
int Regexp__replace(text_stream *text, wchar_t *pattern, wchar_t *replacement, int options) {
|
|
TEMPORARY_TEXT(altered);
|
|
match_results mr = Regexp__create_mr();
|
|
int changes = 0;
|
|
for (int i=0, L=Str__len(text); i<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 427 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
for (i++; i<L; i++)
|
|
PUT_TO(altered, Str__get_at(text, i));
|
|
|
|
}
|
|
#line 415 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
; break; }
|
|
continue;
|
|
} else PUT_TO(altered, Str__get_at(text, i));
|
|
if (options & REP_ATSTART) {
|
|
{
|
|
#line 427 "inweb/foundation-module/Chapter 4/Pattern Matching.w"
|
|
for (i++; i<L; i++)
|
|
PUT_TO(altered, Str__get_at(text, i));
|
|
|
|
}
|
|
#line 418 "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(" ");
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" width=\"%d\"", width)
|
|
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\"");
|
|
}
|
|
void HTML__next_html_column_centred(OUTPUT_STREAM, int width) {
|
|
WRITE(" ");
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "align=\"center\" valign=\"top\" width=\"%d\"", width)
|
|
else HTML_OPEN_WITH("td", "align=\"center\" valign=\"top\"");
|
|
}
|
|
void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) {
|
|
WRITE(" ");
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" colspan=\"%d\" width=\"%d\"", sp, width)
|
|
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" colspan=\"%d\"", sp);
|
|
}
|
|
void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) {
|
|
WRITE(" ");
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "style=\"white-space:nowrap;\" align=\"left\" valign=\"top\" width=\"%d\"", width)
|
|
else HTML_OPEN_WITH("td", "style=\"white-space:nowrap;\" align=\"left\" valign=\"top\"");
|
|
}
|
|
void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) {
|
|
WRITE(" ");
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "style=\"padding-top: 3px;\" align=\"left\" valign=\"top\" width=\"%d\"", width)
|
|
else HTML_OPEN_WITH("td", "style=\"padding-top: 3px;\" align=\"left\" valign=\"top\"");
|
|
}
|
|
void HTML__next_html_column_nw(OUTPUT_STREAM, int width) {
|
|
WRITE(" ");
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "nowrap=\"nowrap\" align=\"left\" valign=\"top\" width=\"%d\"", width)
|
|
else HTML_OPEN_WITH("td", "nowrap=\"nowrap\" align=\"left\" valign=\"top\"");
|
|
}
|
|
void HTML__next_html_column_w(OUTPUT_STREAM, int width) {
|
|
WRITE(" ");
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\" width=\"%d\"", width)
|
|
else HTML_OPEN_WITH("td", "align=\"left\" valign=\"top\"");
|
|
}
|
|
void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) {
|
|
HTML_CLOSE("td");
|
|
if (width > 0) HTML_OPEN_WITH("td", "align=\"right\" valign=\"top\" width=\"%d\"", width)
|
|
else HTML_OPEN_WITH("td", "align=\"right\" valign=\"top\"");
|
|
}
|
|
void HTML__end_html_row(OUTPUT_STREAM) {
|
|
HTML_CLOSE("td");
|
|
HTML_CLOSE("tr");
|
|
}
|
|
void HTML__end_html_table(OUTPUT_STREAM) {
|
|
HTML_CLOSE("table");
|
|
}
|
|
|
|
#line 515 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__open_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) {
|
|
HTML_OPEN_WITH("table",
|
|
"width=\"100%%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" "
|
|
"style=\"background-color: #%s\"", html_colour);
|
|
HTML_OPEN("tr");
|
|
HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE);
|
|
if (rounding & ROUND_BOX_TOP) HTML__box_corner(OUT, html_colour, "tl");
|
|
HTML_CLOSE("td");
|
|
HTML_OPEN("td");
|
|
HTML_CLOSE("td");
|
|
HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE);
|
|
if (rounding & ROUND_BOX_TOP) HTML__box_corner(OUT, html_colour, "tr");
|
|
HTML_CLOSE("td");
|
|
HTML_CLOSE("tr");
|
|
HTML_OPEN("tr");
|
|
HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE);
|
|
HTML_CLOSE("td");
|
|
HTML_OPEN("td");
|
|
}
|
|
|
|
void HTML__close_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) {
|
|
HTML_CLOSE("td");
|
|
HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE);
|
|
HTML_CLOSE("td");
|
|
HTML_CLOSE("tr");
|
|
HTML_OPEN("tr");
|
|
HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE);
|
|
if (rounding & ROUND_BOX_BOTTOM) HTML__box_corner(OUT, html_colour, "bl");
|
|
HTML_CLOSE("td");
|
|
HTML_OPEN("td");
|
|
HTML_CLOSE("td");
|
|
HTML_OPEN_WITH("td", "width=\"%d\"", CORNER_SIZE);
|
|
if (rounding & ROUND_BOX_BOTTOM) HTML__box_corner(OUT, html_colour, "br");
|
|
HTML_CLOSE("td");
|
|
HTML_CLOSE("tr");
|
|
HTML__end_html_table(OUT);
|
|
}
|
|
|
|
void HTML__box_corner(OUTPUT_STREAM, char *html_colour, char *corner) {
|
|
HTML_TAG_WITH("img",
|
|
"src=\"inform:/bg_images/%s_corner_%s.gif\" "
|
|
"width=\"%d\" height=\"%d\" border=\"0\" alt=\"...\"",
|
|
corner, html_colour, CORNER_SIZE, CORNER_SIZE);
|
|
}
|
|
|
|
#line 563 "inweb/foundation-module/Chapter 5/HTML.w"
|
|
void HTML__comment(OUTPUT_STREAM, text_stream *text) {
|
|
WRITE("<!--%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 62 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
|
|
#line 79 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
|
|
#line 87 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
web_md *WebMetadata__get_without_modules(pathname *P, filename *alt_F) {
|
|
return WebMetadata__get(P, alt_F, V2_SYNTAX, NULL, FALSE, FALSE, NULL);
|
|
}
|
|
|
|
web_md *WebMetadata__get(pathname *P, filename *alt_F, int syntax_version,
|
|
module_search *I, int verbosely, int including_modules, pathname *path_to_inweb) {
|
|
if ((including_modules) && (I == NULL)) I = WebModules__make_search_path(NULL);
|
|
web_md *Wm = CREATE(web_md);
|
|
|
|
{
|
|
#line 104 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
Wm->bibliographic_data = NEW_LINKED_LIST(web_bibliographic_datum);
|
|
Bibliographic__initialise_data(Wm);
|
|
|
|
}
|
|
#line 95 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
{
|
|
#line 108 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
if (P) {
|
|
Wm->path_to_web = P;
|
|
Wm->single_file = NULL;
|
|
Wm->contents_filename = WebMetadata__contents_filename(P);
|
|
} else {
|
|
Wm->path_to_web = Filenames__get_path_to(alt_F);
|
|
Wm->single_file = alt_F;
|
|
Wm->contents_filename = NULL;
|
|
}
|
|
Wm->version_number = VersionNumbers__null();
|
|
Wm->default_syntax = syntax_version;
|
|
Wm->chaptered = FALSE;
|
|
Wm->sections_md = NEW_LINKED_LIST(sections_md);
|
|
Wm->chapters_md = NEW_LINKED_LIST(chapter_md);
|
|
Wm->tangle_target_names = NEW_LINKED_LIST(text_stream);
|
|
Wm->main_language_name = Str__new();
|
|
Wm->header_filenames = NEW_LINKED_LIST(filename);
|
|
Wm->as_module = WebModules__create_main_module(Wm);
|
|
|
|
}
|
|
#line 96 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
WebMetadata__read_contents_page(Wm, Wm->as_module, I, verbosely,
|
|
including_modules, NULL, path_to_inweb);
|
|
|
|
{
|
|
#line 128 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
Bibliographic__check_required_data(Wm);
|
|
BuildFiles__deduce_semver(Wm);
|
|
BuildFiles__set_bibliographic_data_for(Wm);
|
|
|
|
}
|
|
#line 99 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
return Wm;
|
|
}
|
|
|
|
#line 171 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
|
|
void WebMetadata__read_contents_page(web_md *Wm, module *of_module,
|
|
module_search *import_path, int verbosely,
|
|
int including_modules, pathname *path, pathname *X) {
|
|
reader_state RS;
|
|
|
|
{
|
|
#line 191 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
RS.Wm = Wm;
|
|
RS.reading_from = of_module;
|
|
RS.in_biblio = TRUE;
|
|
RS.in_purpose = FALSE;
|
|
RS.chapter_being_scanned = NULL;
|
|
RS.chapter_folder_name = Str__new();
|
|
RS.titling_line_to_insert = Str__new();
|
|
RS.scan_verbosely = verbosely;
|
|
RS.including_modules = including_modules;
|
|
RS.path_to = path;
|
|
RS.import_from = import_path;
|
|
RS.halted = FALSE;
|
|
RS.path_to_inweb = X;
|
|
|
|
if (path == NULL) {
|
|
path = Wm->path_to_web;
|
|
RS.main_web_not_module = TRUE;
|
|
} else {
|
|
RS.main_web_not_module = FALSE;
|
|
}
|
|
|
|
if (Wm->single_file) {
|
|
RS.contents_filename = Wm->single_file;
|
|
RS.halt_at_at = TRUE;
|
|
} else {
|
|
RS.contents_filename = WebMetadata__contents_filename(path);
|
|
RS.halt_at_at = FALSE;
|
|
}
|
|
RS.section_count = 0;
|
|
RS.last_section = NULL;
|
|
|
|
}
|
|
#line 176 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
int cl = TextFiles__read(RS.contents_filename, FALSE, "can't open contents file",
|
|
TRUE, WebMetadata__read_contents_line, NULL, &RS);
|
|
if (verbosely) {
|
|
if (Wm->single_file) {
|
|
PRINT("Read %d lines of contents part at top of file\n", cl);
|
|
} else {
|
|
PRINT("Read contents section (%d lines)\n", cl);
|
|
}
|
|
}
|
|
if (RS.section_count == 1) RS.last_section->is_a_singleton = TRUE;
|
|
}
|
|
|
|
#line 227 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
void WebMetadata__read_contents_line(text_stream *line, text_file_position *tfp, void *X) {
|
|
reader_state *RS = (reader_state *) X;
|
|
if (RS->halted) return;
|
|
|
|
int begins_with_white_space = FALSE;
|
|
if (Characters__is_whitespace(Str__get_first_char(line)))
|
|
begins_with_white_space = TRUE;
|
|
Str__trim_white_space(line);
|
|
|
|
|
|
{
|
|
#line 251 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
if (Str__eq(line, TL_IS_19))
|
|
RS->Wm->default_syntax = V1_SYNTAX;
|
|
else if (Str__eq(line, TL_IS_20))
|
|
RS->Wm->default_syntax = V2_SYNTAX;
|
|
|
|
}
|
|
#line 236 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
int syntax = RS->Wm->default_syntax;
|
|
|
|
filename *filename_of_single_file_web = NULL;
|
|
if ((RS->halt_at_at) && (Str__get_at(line, 0) == '@'))
|
|
|
|
{
|
|
#line 262 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
RS->halted = TRUE;
|
|
text_stream *new_chapter_range = TL_IS_21;
|
|
text_stream *language_name = NULL;
|
|
line = TL_IS_22;
|
|
|
|
{
|
|
#line 463 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
chapter_md *Cm = CREATE(chapter_md);
|
|
Cm->ch_range = Str__duplicate(new_chapter_range);
|
|
Cm->ch_title = Str__duplicate(line);
|
|
Cm->rubric = Str__new();
|
|
Cm->ch_language_name = language_name;
|
|
Cm->imported = TRUE;
|
|
Cm->sections_md = NEW_LINKED_LIST(section_md);
|
|
if (RS->main_web_not_module) Cm->imported = FALSE;
|
|
|
|
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->Wm->chapters_md);
|
|
RS->chapter_being_scanned = Cm;
|
|
|
|
}
|
|
#line 266 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
line = TL_IS_23;
|
|
filename_of_single_file_web = tfp->text_file_filename;
|
|
|
|
{
|
|
#line 480 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
section_md *Sm = CREATE(section_md);
|
|
Sm = CREATE(section_md);
|
|
|
|
{
|
|
#line 490 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
Sm->source_file_for_section = filename_of_single_file_web;
|
|
Sm->using_syntax = syntax;
|
|
Sm->is_a_singleton = FALSE;
|
|
Sm->titling_line_to_insert = Str__duplicate(RS->titling_line_to_insert);
|
|
Str__clear(RS->titling_line_to_insert);
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L"(%c+) %^\"(%c+)\" *")) {
|
|
Sm->sect_title = Str__duplicate(mr.exp[0]);
|
|
Sm->tag_name = Str__duplicate(mr.exp[1]);
|
|
} else {
|
|
Sm->sect_title = Str__duplicate(line);
|
|
Sm->tag_name = NULL;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 482 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
{
|
|
#line 507 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
chapter_md *Cm = RS->chapter_being_scanned;
|
|
RS->section_count++;
|
|
RS->last_section = Sm;
|
|
ADD_TO_LINKED_LIST(Sm, section_md, Cm->sections_md);
|
|
ADD_TO_LINKED_LIST(Sm, section_md, RS->Wm->sections_md);
|
|
ADD_TO_LINKED_LIST(Sm, section_md, RS->reading_from->sections_md);
|
|
|
|
}
|
|
#line 483 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
{
|
|
#line 515 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
Sm->sect_language_name = RS->chapter_being_scanned->ch_language_name; /* by default */
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L"(%c*%C) %(Independent (%c*) *%)")) {
|
|
text_stream *title_alone = mr.exp[0];
|
|
text_stream *language_name = mr.exp[1];
|
|
|
|
{
|
|
#line 526 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
text_stream *p = language_name;
|
|
if (Str__len(p) == 0) p = Bibliographic__get_datum(RS->Wm, TL_IS_26);
|
|
Sm->sect_independent_language = Str__duplicate(p);
|
|
|
|
}
|
|
#line 520 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
Str__copy(Sm->sect_title, title_alone);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 484 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
if (Sm->source_file_for_section == NULL)
|
|
|
|
{
|
|
#line 536 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
TEMPORARY_TEXT(leafname_to_use);
|
|
WRITE_TO(leafname_to_use, "%S.i6t", Sm->sect_title);
|
|
pathname *P = RS->path_to;
|
|
if (P == NULL) P = RS->Wm->path_to_web;
|
|
if (Str__len(RS->chapter_folder_name) > 0)
|
|
P = Pathnames__subfolder(P, RS->chapter_folder_name);
|
|
Sm->source_file_for_section = Filenames__in_folder(P, leafname_to_use);
|
|
if (TextFiles__exists(Sm->source_file_for_section) == FALSE) {
|
|
Str__clear(leafname_to_use);
|
|
WRITE_TO(leafname_to_use, "%S.w", Sm->sect_title);
|
|
Sm->source_file_for_section = Filenames__in_folder(P, leafname_to_use);
|
|
}
|
|
DISCARD_TEXT(leafname_to_use);
|
|
|
|
}
|
|
#line 487 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
}
|
|
#line 269 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
return;
|
|
|
|
}
|
|
#line 241 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
|
|
{
|
|
#line 278 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
if (Str__len(line) == 0)
|
|
{
|
|
#line 286 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
RS->in_biblio = FALSE;
|
|
|
|
}
|
|
#line 278 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
|
|
else if (RS->in_biblio)
|
|
{
|
|
#line 292 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
if (RS->main_web_not_module) {
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L"(%c+?): (%c+?) *")) {
|
|
TEMPORARY_TEXT(key);
|
|
Str__copy(key, mr.exp[0]);
|
|
TEMPORARY_TEXT(value);
|
|
Str__copy(value, mr.exp[1]);
|
|
|
|
{
|
|
#line 312 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
if (Bibliographic__datum_can_be_declared(RS->Wm, key)) {
|
|
if (Bibliographic__datum_on_or_off(RS->Wm, key)) {
|
|
if ((Str__ne_wide_string(value, L"On")) && (Str__ne_wide_string(value, L"Off"))) {
|
|
TEMPORARY_TEXT(err);
|
|
WRITE_TO(err, "this setting must be 'On' or 'Off': %S", key);
|
|
Errors__in_text_file_S(err, tfp);
|
|
DISCARD_TEXT(err);
|
|
Str__clear(value);
|
|
WRITE_TO(value, "Off");
|
|
}
|
|
}
|
|
Bibliographic__set_datum(RS->Wm, key, value);
|
|
} else {
|
|
TEMPORARY_TEXT(err);
|
|
WRITE_TO(err, "no such bibliographic datum: %S", key);
|
|
Errors__in_text_file_S(err, tfp);
|
|
DISCARD_TEXT(err);
|
|
}
|
|
|
|
}
|
|
#line 299 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
DISCARD_TEXT(key);
|
|
DISCARD_TEXT(value);
|
|
} else {
|
|
TEMPORARY_TEXT(err);
|
|
WRITE_TO(err, "expected 'Setting: Value' but found '%S'", line);
|
|
Errors__in_text_file_S(err, tfp);
|
|
DISCARD_TEXT(err);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
}
|
|
#line 279 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
|
|
else
|
|
{
|
|
#line 335 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
if (begins_with_white_space == FALSE) {
|
|
if (Str__get_first_char(line) == '"') {
|
|
RS->in_purpose = TRUE; Str__delete_first_character(line);
|
|
}
|
|
if (RS->in_purpose == TRUE)
|
|
{
|
|
#line 348 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
if ((Str__len(line) > 0) && (Str__get_last_char(line) == '"')) {
|
|
Str__truncate(line, Str__len(line)-1); RS->in_purpose = FALSE;
|
|
}
|
|
if (RS->chapter_being_scanned) {
|
|
text_stream *r = RS->chapter_being_scanned->rubric;
|
|
if (Str__len(r) > 0) WRITE_TO(r, " ");
|
|
WRITE_TO(r, "%S", line);
|
|
}
|
|
|
|
}
|
|
#line 339 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
|
|
else
|
|
{
|
|
#line 360 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
TEMPORARY_TEXT(new_chapter_range); /* e.g., S, P, 1, 2, 3, A, B, ... */
|
|
TEMPORARY_TEXT(pdf_leafname);
|
|
text_stream *language_name = NULL;
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L"(%c*%C) %(Independent(%c*)%)")) {
|
|
text_stream *title_alone = mr.exp[0];
|
|
language_name = mr.exp[1];
|
|
|
|
{
|
|
#line 455 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, language_name, L" *"))
|
|
language_name = Bibliographic__get_datum(RS->Wm, TL_IS_25);
|
|
else if (Regexp__match(&mr, language_name, L" *(%c*?) *"))
|
|
language_name = mr.exp[0];
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 368 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
Str__copy(line, title_alone);
|
|
}
|
|
int this_is_a_chapter = TRUE;
|
|
Str__clear(RS->chapter_folder_name);
|
|
if (Str__eq_wide_string(line, L"Sections")) {
|
|
WRITE_TO(new_chapter_range, "S");
|
|
WRITE_TO(RS->chapter_folder_name, "Sections");
|
|
WRITE_TO(pdf_leafname, "Sections.pdf");
|
|
RS->Wm->chaptered = FALSE;
|
|
Str__clear(RS->titling_line_to_insert);
|
|
} else if (Str__eq_wide_string(line, L"Preliminaries")) {
|
|
WRITE_TO(new_chapter_range, "P");
|
|
WRITE_TO(RS->chapter_folder_name, "Preliminaries");
|
|
Str__clear(RS->titling_line_to_insert);
|
|
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
|
|
WRITE_TO(pdf_leafname, "Preliminaries.pdf");
|
|
RS->Wm->chaptered = TRUE;
|
|
} else if (Str__eq_wide_string(line, L"Manual")) {
|
|
WRITE_TO(new_chapter_range, "M");
|
|
WRITE_TO(RS->chapter_folder_name, "Manual");
|
|
Str__clear(RS->titling_line_to_insert);
|
|
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
|
|
WRITE_TO(pdf_leafname, "Manual.pdf");
|
|
RS->Wm->chaptered = TRUE;
|
|
} else if (Regexp__match(&mr, line, L"Header: (%c+)")) {
|
|
pathname *P = RS->path_to;
|
|
if (P == NULL) P = RS->Wm->path_to_web;
|
|
P = Pathnames__subfolder(P, TL_IS_24);
|
|
filename *HF = Filenames__in_folder(P, mr.exp[0]);
|
|
ADD_TO_LINKED_LIST(HF, filename, RS->Wm->header_filenames);
|
|
this_is_a_chapter = FALSE;
|
|
} else if (Regexp__match(&mr, line, L"Import: (%c+)")) {
|
|
if (RS->import_from) {
|
|
module *imported =
|
|
WebModules__find(RS->Wm, RS->import_from, mr.exp[0], RS->path_to_inweb);
|
|
if (imported == NULL) {
|
|
TEMPORARY_TEXT(err);
|
|
WRITE_TO(err, "unable to find module: %S", line);
|
|
Errors__in_text_file_S(err, tfp);
|
|
DISCARD_TEXT(err);
|
|
} else {
|
|
if (RS->including_modules) {
|
|
int save_syntax = RS->Wm->default_syntax;
|
|
WebMetadata__read_contents_page(RS->Wm, imported, RS->import_from,
|
|
RS->scan_verbosely, RS->including_modules,
|
|
imported->module_location, RS->path_to_inweb);
|
|
RS->Wm->default_syntax = save_syntax;
|
|
}
|
|
}
|
|
}
|
|
this_is_a_chapter = FALSE;
|
|
} else if (Regexp__match(&mr, line, L"Chapter (%d+): %c+")) {
|
|
int n = Str__atoi(mr.exp[0], 0);
|
|
WRITE_TO(new_chapter_range, "%d", n);
|
|
WRITE_TO(RS->chapter_folder_name, "Chapter %d", n);
|
|
Str__clear(RS->titling_line_to_insert);
|
|
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
|
|
WRITE_TO(pdf_leafname, "Chapter-%d.pdf", n);
|
|
RS->Wm->chaptered = TRUE;
|
|
} else if (Regexp__match(&mr, line, L"Appendix (%c): %c+")) {
|
|
text_stream *letter = mr.exp[0];
|
|
Str__copy(new_chapter_range, letter);
|
|
WRITE_TO(RS->chapter_folder_name, "Appendix %S", letter);
|
|
Str__clear(RS->titling_line_to_insert);
|
|
WRITE_TO(RS->titling_line_to_insert, "%S.", line);
|
|
WRITE_TO(pdf_leafname, "Appendix-%S.pdf", letter);
|
|
RS->Wm->chaptered = TRUE;
|
|
} else {
|
|
TEMPORARY_TEXT(err);
|
|
WRITE_TO(err, "segment not understood: %S", line);
|
|
Errors__in_text_file_S(err, tfp);
|
|
WRITE_TO(STDERR, "(Must be 'Chapter <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 463 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
chapter_md *Cm = CREATE(chapter_md);
|
|
Cm->ch_range = Str__duplicate(new_chapter_range);
|
|
Cm->ch_title = Str__duplicate(line);
|
|
Cm->rubric = Str__new();
|
|
Cm->ch_language_name = language_name;
|
|
Cm->imported = TRUE;
|
|
Cm->sections_md = NEW_LINKED_LIST(section_md);
|
|
if (RS->main_web_not_module) Cm->imported = FALSE;
|
|
|
|
ADD_TO_LINKED_LIST(Cm, chapter_md, RS->Wm->chapters_md);
|
|
RS->chapter_being_scanned = Cm;
|
|
|
|
}
|
|
#line 446 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
DISCARD_TEXT(new_chapter_range);
|
|
DISCARD_TEXT(pdf_leafname);
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 340 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
} else
|
|
{
|
|
#line 480 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
section_md *Sm = CREATE(section_md);
|
|
Sm = CREATE(section_md);
|
|
|
|
{
|
|
#line 490 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
Sm->source_file_for_section = filename_of_single_file_web;
|
|
Sm->using_syntax = syntax;
|
|
Sm->is_a_singleton = FALSE;
|
|
Sm->titling_line_to_insert = Str__duplicate(RS->titling_line_to_insert);
|
|
Str__clear(RS->titling_line_to_insert);
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L"(%c+) %^\"(%c+)\" *")) {
|
|
Sm->sect_title = Str__duplicate(mr.exp[0]);
|
|
Sm->tag_name = Str__duplicate(mr.exp[1]);
|
|
} else {
|
|
Sm->sect_title = Str__duplicate(line);
|
|
Sm->tag_name = NULL;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 482 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
{
|
|
#line 507 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
chapter_md *Cm = RS->chapter_being_scanned;
|
|
RS->section_count++;
|
|
RS->last_section = Sm;
|
|
ADD_TO_LINKED_LIST(Sm, section_md, Cm->sections_md);
|
|
ADD_TO_LINKED_LIST(Sm, section_md, RS->Wm->sections_md);
|
|
ADD_TO_LINKED_LIST(Sm, section_md, RS->reading_from->sections_md);
|
|
|
|
}
|
|
#line 483 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
{
|
|
#line 515 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
Sm->sect_language_name = RS->chapter_being_scanned->ch_language_name; /* by default */
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L"(%c*%C) %(Independent (%c*) *%)")) {
|
|
text_stream *title_alone = mr.exp[0];
|
|
text_stream *language_name = mr.exp[1];
|
|
|
|
{
|
|
#line 526 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
text_stream *p = language_name;
|
|
if (Str__len(p) == 0) p = Bibliographic__get_datum(RS->Wm, TL_IS_26);
|
|
Sm->sect_independent_language = Str__duplicate(p);
|
|
|
|
}
|
|
#line 520 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
Str__copy(Sm->sect_title, title_alone);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 484 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
if (Sm->source_file_for_section == NULL)
|
|
|
|
{
|
|
#line 536 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
TEMPORARY_TEXT(leafname_to_use);
|
|
WRITE_TO(leafname_to_use, "%S.i6t", Sm->sect_title);
|
|
pathname *P = RS->path_to;
|
|
if (P == NULL) P = RS->Wm->path_to_web;
|
|
if (Str__len(RS->chapter_folder_name) > 0)
|
|
P = Pathnames__subfolder(P, RS->chapter_folder_name);
|
|
Sm->source_file_for_section = Filenames__in_folder(P, leafname_to_use);
|
|
if (TextFiles__exists(Sm->source_file_for_section) == FALSE) {
|
|
Str__clear(leafname_to_use);
|
|
WRITE_TO(leafname_to_use, "%S.w", Sm->sect_title);
|
|
Sm->source_file_for_section = Filenames__in_folder(P, leafname_to_use);
|
|
}
|
|
DISCARD_TEXT(leafname_to_use);
|
|
|
|
}
|
|
#line 487 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
}
|
|
#line 341 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
}
|
|
#line 280 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
|
|
}
|
|
#line 243 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
;
|
|
}
|
|
|
|
#line 553 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
int WebMetadata__directory_looks_like_a_web(pathname *P) {
|
|
return TextFiles__exists(WebMetadata__contents_filename(P));
|
|
}
|
|
|
|
filename *WebMetadata__contents_filename(pathname *P) {
|
|
return Filenames__in_folder(P, TL_IS_27);
|
|
}
|
|
|
|
#line 564 "inweb/foundation-module/Chapter 8/Web Structure.w"
|
|
int WebMetadata__chapter_count(web_md *Wm) {
|
|
int n = 0;
|
|
chapter_md *Cm;
|
|
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) n++;
|
|
return n;
|
|
}
|
|
int WebMetadata__section_count(web_md *Wm) {
|
|
int n = 0;
|
|
chapter_md *Cm;
|
|
LOOP_OVER_LINKED_LIST(Cm, chapter_md, Wm->chapters_md) {
|
|
section_md *Sm;
|
|
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) n++;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
#line 20 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
|
|
#line 29 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
int Bibliographic__datum_can_be_declared(web_md *Wm, text_stream *key) {
|
|
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
|
|
if (bd == NULL) return FALSE;
|
|
return bd->declaration_permitted;
|
|
}
|
|
|
|
int Bibliographic__datum_on_or_off(web_md *Wm, text_stream *key) {
|
|
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
|
|
if (bd == NULL) return FALSE;
|
|
return bd->on_or_off;
|
|
}
|
|
|
|
#line 45 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
void Bibliographic__initialise_data(web_md *Wm) {
|
|
web_bibliographic_datum *bd;
|
|
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_28, NULL); bd->declaration_mandatory = TRUE;
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_29, NULL); bd->declaration_mandatory = TRUE;
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_30, NULL); bd->declaration_mandatory = TRUE;
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_31, NULL); bd->declaration_mandatory = TRUE;
|
|
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_32, NULL);
|
|
bd->alias = Bibliographic__set_datum(Wm, TL_IS_33, NULL); /* alias US to UK spelling */
|
|
|
|
Bibliographic__set_datum(Wm, TL_IS_34, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_35, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_36, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_37, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_38, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_39, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_40, TL_IS_41);
|
|
Bibliographic__set_datum(Wm, TL_IS_42, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_43, NULL);
|
|
Bibliographic__set_datum(Wm, TL_IS_44, NULL);
|
|
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_45, TL_IS_46); bd->on_or_off = TRUE;
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_47, TL_IS_48); bd->on_or_off = TRUE;
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_49, TL_IS_50); bd->on_or_off = TRUE;
|
|
bd = Bibliographic__set_datum(Wm, TL_IS_51, NULL);
|
|
}
|
|
|
|
#line 77 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
void Bibliographic__check_required_data(web_md *Wm) {
|
|
web_bibliographic_datum *bd;
|
|
LOOP_OVER_BIBLIOGRAPHIC_DATA(bd, Wm)
|
|
if ((bd->declaration_mandatory) &&
|
|
(Str__len(bd->value) == 0))
|
|
Errors__fatal_with_text(
|
|
"The web does not specify '%S: ...'", bd->key);
|
|
}
|
|
|
|
#line 90 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
text_stream *Bibliographic__get_datum(web_md *Wm, text_stream *key) {
|
|
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
|
|
if (bd) return bd->value;
|
|
return NULL;
|
|
}
|
|
|
|
int Bibliographic__data_exists(web_md *Wm, text_stream *key) {
|
|
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
|
|
if ((bd) && (Str__len(bd->value) > 0)) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
web_bibliographic_datum *Bibliographic__look_up_datum(web_md *Wm, text_stream *key) {
|
|
web_bibliographic_datum *bd;
|
|
LOOP_OVER_BIBLIOGRAPHIC_DATA(bd, Wm)
|
|
if (Str__eq(key, bd->key)) {
|
|
if (bd->alias) return bd->alias;
|
|
return bd;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#line 117 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
web_bibliographic_datum *Bibliographic__set_datum(web_md *Wm, text_stream *key, text_stream *val) {
|
|
web_bibliographic_datum *bd = Bibliographic__look_up_datum(Wm, key);
|
|
if (bd == NULL)
|
|
{
|
|
#line 126 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
bd = CREATE(web_bibliographic_datum);
|
|
bd->key = Str__duplicate(key);
|
|
bd->value = Str__duplicate(val);
|
|
bd->declaration_mandatory = FALSE;
|
|
bd->declaration_permitted = TRUE;
|
|
bd->on_or_off = FALSE;
|
|
bd->alias = NULL;
|
|
ADD_TO_LINKED_LIST(bd, web_bibliographic_datum, Wm->bibliographic_data);
|
|
|
|
}
|
|
#line 119 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
|
|
else Str__copy(bd->value, val);
|
|
if (Str__eq_wide_string(key, L"Title"))
|
|
{
|
|
#line 141 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
TEMPORARY_TEXT(recapped);
|
|
Str__copy(recapped, val);
|
|
LOOP_THROUGH_TEXT(P, recapped)
|
|
Str__put(P, toupper(Str__get(P)));
|
|
Bibliographic__set_datum(Wm, TL_IS_52, recapped);
|
|
DISCARD_TEXT(recapped);
|
|
|
|
}
|
|
#line 121 "inweb/foundation-module/Chapter 8/Bibliographic Data for Webs.w"
|
|
;
|
|
return bd;
|
|
}
|
|
|
|
#line 28 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
|
|
#line 30 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module *WebModules__new(text_stream *name, pathname *at, int m) {
|
|
module *M = CREATE(module);
|
|
M->module_location = at;
|
|
M->module_name = Str__duplicate(name);
|
|
M->dependencies = NEW_LINKED_LIST(module);
|
|
M->origin_marker = m;
|
|
M->module_tag = TL_IS_53;
|
|
M->sections_md = NEW_LINKED_LIST(section_md);
|
|
return M;
|
|
}
|
|
|
|
#line 50 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module *WebModules__create_main_module(web_md *WS) {
|
|
return WebModules__new(TL_IS_54, WS->path_to_web, READING_WEB_MOM);
|
|
}
|
|
|
|
#line 61 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
void WebModules__dependency(module *A, module *B) {
|
|
if ((A == NULL) || (B == NULL)) internal_error("no module");
|
|
ADD_TO_LINKED_LIST(B, module, A->dependencies);
|
|
}
|
|
|
|
#line 75 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
|
|
#line 77 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module_search *WebModules__make_search_path(pathname *ext_path) {
|
|
module_search *ms = CREATE(module_search);
|
|
ms->path_to_search = ext_path;
|
|
return ms;
|
|
}
|
|
|
|
#line 87 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
module *WebModules__find(web_md *WS, module_search *ms, text_stream *name, pathname *X) {
|
|
TEMPORARY_TEXT(T);
|
|
WRITE_TO(T, "%S-module", name);
|
|
pathname *tries[4];
|
|
tries[0] = WS?(WS->path_to_web):NULL;
|
|
tries[1] = tries[0]?(Pathnames__up(tries[0])):NULL;
|
|
tries[2] = X;
|
|
tries[3] = ms->path_to_search;
|
|
int N = 4;
|
|
for (int i=0; i<N; i++) {
|
|
pathname *P = Pathnames__from_text_relative(tries[i], T);
|
|
if ((P) && (WebModules__exists(P)))
|
|
{
|
|
#line 108 "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 98 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
;
|
|
}
|
|
DISCARD_TEXT(T);
|
|
return NULL;
|
|
}
|
|
|
|
#line 116 "inweb/foundation-module/Chapter 8/Web Modules.w"
|
|
int WebModules__exists(pathname *P) {
|
|
return WebMetadata__directory_looks_like_a_web(P);
|
|
}
|
|
|
|
#line 10 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
filename *BuildFiles__build_file_for_web(web_md *WS) {
|
|
filename *F = Filenames__in_folder(WS->path_to_web, TL_IS_55);
|
|
if (TextFiles__exists(F)) return F;
|
|
F = Filenames__in_folder(NULL, TL_IS_56);
|
|
if (TextFiles__exists(F)) return F;
|
|
return NULL;
|
|
}
|
|
|
|
#line 26 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
|
|
#line 30 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
build_file_data BuildFiles__read(filename *F) {
|
|
build_file_data bfd;
|
|
bfd.prerelease_text = Str__new();
|
|
bfd.build_code = Str__new();
|
|
bfd.build_date = Str__new();
|
|
TextFiles__read(F, FALSE, "unable to read build file", TRUE,
|
|
&BuildFiles__build_file_helper, NULL, (void *) &bfd);
|
|
return bfd;
|
|
}
|
|
|
|
void BuildFiles__build_file_helper(text_stream *text, text_file_position *tfp, void *state) {
|
|
build_file_data *bfd = (build_file_data *) state;
|
|
if (Str__len(text) == 0) return;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, text, L"Build Date: *(%c*)")) {
|
|
bfd->build_date = Str__duplicate(mr.exp[0]);
|
|
} else if (Regexp__match(&mr, text, L"Build Number: *(%c*)")) {
|
|
bfd->build_code = Str__duplicate(mr.exp[0]);
|
|
} else if (Regexp__match(&mr, text, L"Prerelease: *(%c*)")) {
|
|
bfd->prerelease_text = Str__duplicate(mr.exp[0]);
|
|
} else {
|
|
Errors__in_text_file("can't parse build file line", tfp);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 59 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__write(build_file_data bfd, filename *F) {
|
|
text_stream vr_stream;
|
|
text_stream *OUT = &vr_stream;
|
|
if (Streams__open_to_file(OUT, F, UTF8_ENC) == FALSE)
|
|
Errors__fatal_with_file("can't write build file", F);
|
|
if (Str__len(bfd.prerelease_text) > 0)
|
|
WRITE("Prerelease: %S\n", bfd.prerelease_text);
|
|
WRITE("Build Date: %S\n", bfd.build_date);
|
|
if (Str__len(bfd.build_code) > 0)
|
|
WRITE("Build Number: %S\n", bfd.build_code);
|
|
Streams__close(OUT);
|
|
}
|
|
|
|
#line 77 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__set_bibliographic_data_for(web_md *WS) {
|
|
filename *F = BuildFiles__build_file_for_web(WS);
|
|
if (F) {
|
|
build_file_data bfd = BuildFiles__read(F);
|
|
if (Str__len(bfd.prerelease_text) > 0)
|
|
Bibliographic__set_datum(WS, TL_IS_57, bfd.prerelease_text);
|
|
if (Str__len(bfd.build_code) > 0)
|
|
Bibliographic__set_datum(WS, TL_IS_58, bfd.build_code);
|
|
if (Str__len(bfd.build_date) > 0)
|
|
Bibliographic__set_datum(WS, TL_IS_59, bfd.build_date);
|
|
}
|
|
}
|
|
|
|
#line 99 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__deduce_semver(web_md *WS) {
|
|
TEMPORARY_TEXT(combined);
|
|
text_stream *s = Bibliographic__get_datum(WS, TL_IS_60);
|
|
if (Str__len(s) > 0) WRITE_TO(combined, "%S", s);
|
|
else {
|
|
text_stream *v = Bibliographic__get_datum(WS, TL_IS_61);
|
|
if (Str__len(v) > 0) WRITE_TO(combined, "%S", v);
|
|
text_stream *p = Bibliographic__get_datum(WS, TL_IS_62);
|
|
if (Str__len(p) > 0) WRITE_TO(combined, "-%S", p);
|
|
text_stream *b = Bibliographic__get_datum(WS, TL_IS_63);
|
|
if (Str__len(b) > 0) WRITE_TO(combined, "+%S", b);
|
|
}
|
|
if (Str__len(combined) > 0) {
|
|
WS->version_number = VersionNumbers__from_text(combined);
|
|
if (VersionNumbers__is_null(WS->version_number)) {
|
|
Errors__fatal_with_text(
|
|
"Combined version '%S' does not comply with the semver standard",
|
|
combined);
|
|
} else {
|
|
Bibliographic__set_datum(WS, TL_IS_64, combined);
|
|
}
|
|
}
|
|
DISCARD_TEXT(combined);
|
|
}
|
|
|
|
#line 129 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__advance_for_web(web_md *WS) {
|
|
filename *F = BuildFiles__build_file_for_web(WS);
|
|
if (F) BuildFiles__advance(F);
|
|
else Errors__fatal("web has no build file");
|
|
}
|
|
|
|
void BuildFiles__advance(filename *F) {
|
|
build_file_data bfd = BuildFiles__read(F);
|
|
if (BuildFiles__dated_today(bfd.build_date) == FALSE) {
|
|
BuildFiles__increment(bfd.build_code);
|
|
BuildFiles__write(bfd, F);
|
|
}
|
|
}
|
|
|
|
#line 148 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
int BuildFiles__dated_today(text_stream *dateline) {
|
|
char *monthname[12] = { "January", "February", "March", "April", "May", "June",
|
|
"July", "August", "September", "October", "November", "December" };
|
|
TEMPORARY_TEXT(today);
|
|
WRITE_TO(today, "%d %s %d",
|
|
the_present->tm_mday, monthname[the_present->tm_mon], the_present->tm_year+1900);
|
|
int rv = TRUE;
|
|
if (Str__ne(dateline, today)) {
|
|
rv = FALSE;
|
|
Str__clear(dateline);
|
|
Str__copy(dateline, today);
|
|
}
|
|
DISCARD_TEXT(today);
|
|
return rv;
|
|
}
|
|
|
|
#line 174 "inweb/foundation-module/Chapter 8/Build Files.w"
|
|
void BuildFiles__increment(text_stream *T) {
|
|
if (Str__len(T) != 4) Errors__with_text("build code malformed: %S", T);
|
|
else {
|
|
int N = Str__get_at(T, 0) - '0';
|
|
int L = Str__get_at(T, 1);
|
|
int M1 = Str__get_at(T, 2) - '0';
|
|
int M2 = Str__get_at(T, 3) - '0';
|
|
if ((N < 0) || (N > 9) || (L < 'A') || (L > 'Z') ||
|
|
(M1 < 0) || (M1 > 9) || (M2 < 0) || (M2 > 9)) {
|
|
Errors__with_text("build code malformed: %S", T);
|
|
} else {
|
|
M2++;
|
|
if (M2 == 10) { M2 = 0; M1++; }
|
|
if (M1 == 10) { M1 = 0; M2 = 1; L++; }
|
|
if ((L == 'I') || (L == 'O')) L++;
|
|
if (L > 'Z') { L = 'A'; N++; }
|
|
if (N == 10) Errors__with_text("build code overflowed: %S", T);
|
|
else {
|
|
Str__clear(T);
|
|
WRITE_TO(T, "%d%c%d%d", N, L, M1, M2);
|
|
PRINT("Build code advanced to %S\n", T);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 55 "inweb/Chapter 1/Basics.w"
|
|
ALLOCATE_IN_ARRAYS(source_line, 1000)
|
|
ALLOCATE_INDIVIDUALLY(breadcrumb_request)
|
|
ALLOCATE_INDIVIDUALLY(c_structure)
|
|
ALLOCATE_INDIVIDUALLY(chapter)
|
|
ALLOCATE_INDIVIDUALLY(colouring_rule)
|
|
ALLOCATE_INDIVIDUALLY(enumeration_set)
|
|
ALLOCATE_INDIVIDUALLY(function)
|
|
ALLOCATE_INDIVIDUALLY(hash_table_entry_usage)
|
|
ALLOCATE_INDIVIDUALLY(hash_table_entry)
|
|
ALLOCATE_INDIVIDUALLY(colouring_language_block)
|
|
ALLOCATE_INDIVIDUALLY(macro_tokens)
|
|
ALLOCATE_INDIVIDUALLY(macro_usage)
|
|
ALLOCATE_INDIVIDUALLY(macro)
|
|
ALLOCATE_INDIVIDUALLY(nonterminal_variable)
|
|
ALLOCATE_INDIVIDUALLY(para_macro)
|
|
ALLOCATE_INDIVIDUALLY(paragraph_tagging)
|
|
ALLOCATE_INDIVIDUALLY(paragraph)
|
|
ALLOCATE_INDIVIDUALLY(preform_nonterminal)
|
|
ALLOCATE_INDIVIDUALLY(programming_language)
|
|
ALLOCATE_INDIVIDUALLY(reserved_word)
|
|
ALLOCATE_INDIVIDUALLY(section)
|
|
ALLOCATE_INDIVIDUALLY(structure_element)
|
|
ALLOCATE_INDIVIDUALLY(tangle_target)
|
|
ALLOCATE_INDIVIDUALLY(tex_results)
|
|
ALLOCATE_INDIVIDUALLY(text_literal)
|
|
ALLOCATE_INDIVIDUALLY(theme_tag)
|
|
ALLOCATE_INDIVIDUALLY(weave_format)
|
|
ALLOCATE_INDIVIDUALLY(weave_pattern)
|
|
ALLOCATE_INDIVIDUALLY(weave_target)
|
|
ALLOCATE_INDIVIDUALLY(web)
|
|
ALLOCATE_INDIVIDUALLY(writeme_asset)
|
|
|
|
#line 10 "inweb/Chapter 1/Program Control.w"
|
|
int default_inweb_syntax = V2_SYNTAX;
|
|
|
|
#line 22 "inweb/Chapter 1/Program Control.w"
|
|
|
|
#line 24 "inweb/Chapter 1/Program Control.w"
|
|
int fundamental_mode = NO_MODE;
|
|
|
|
#line 43 "inweb/Chapter 1/Program Control.w"
|
|
|
|
#line 51 "inweb/Chapter 1/Program Control.w"
|
|
pathname *path_to_inweb = NULL; /* where we are installed */
|
|
pathname *path_to_inweb_materials = NULL; /* the materials pathname */
|
|
pathname *path_to_inweb_patterns = NULL; /* where built-in patterns are stored */
|
|
|
|
#line 58 "inweb/Chapter 1/Program Control.w"
|
|
int no_inweb_errors = 0;
|
|
|
|
#line 63 "inweb/Chapter 1/Program Control.w"
|
|
int main(int argc, char **argv) {
|
|
|
|
{
|
|
#line 78 "inweb/Chapter 1/Program Control.w"
|
|
Foundation__start();
|
|
Formats__create_weave_formats();
|
|
|
|
}
|
|
#line 64 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
inweb_instructions args = Configuration__read(argc, argv);
|
|
fundamental_mode = args.inweb_mode;
|
|
path_to_inweb = Pathnames__installation_path("INWEB_PATH", TL_IS_66);
|
|
if (args.verbose_switch) PRINT("Installation path is %p\n", path_to_inweb);
|
|
path_to_inweb_patterns = Pathnames__subfolder(path_to_inweb, TL_IS_67);
|
|
path_to_inweb_materials = Pathnames__subfolder(path_to_inweb, TL_IS_68);
|
|
|
|
Main__follow_instructions(&args);
|
|
|
|
|
|
{
|
|
#line 82 "inweb/Chapter 1/Program Control.w"
|
|
Foundation__end();
|
|
return (no_inweb_errors == 0)?0:1;
|
|
|
|
}
|
|
#line 74 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
}
|
|
|
|
#line 90 "inweb/Chapter 1/Program Control.w"
|
|
void Main__follow_instructions(inweb_instructions *ins) {
|
|
web *W = NULL;
|
|
if ((ins->chosen_web) || (ins->chosen_file)) {
|
|
W = Reader__load_web(ins->chosen_web, ins->chosen_file,
|
|
WebModules__make_search_path(ins->import_setting), ins->verbose_switch,
|
|
TRUE);
|
|
W->redirect_weaves_to = ins->weave_into_setting;
|
|
Reader__read_web(W, ins->verbose_switch);
|
|
Parser__parse_web(W, ins->inweb_mode, ins->sequential);
|
|
}
|
|
if (no_inweb_errors == 0) {
|
|
if (ins->inweb_mode == TRANSLATE_MODE)
|
|
{
|
|
#line 110 "inweb/Chapter 1/Program Control.w"
|
|
if ((ins->makefile_setting) && (ins->prototype_setting == NULL))
|
|
ins->prototype_setting = Filenames__from_text(TL_IS_69);
|
|
if ((ins->gitignore_setting) && (ins->prototype_setting == NULL))
|
|
ins->prototype_setting = Filenames__from_text(TL_IS_70);
|
|
if ((ins->writeme_setting) && (ins->prototype_setting == NULL))
|
|
ins->prototype_setting = Filenames__from_text(TL_IS_71);
|
|
if (ins->makefile_setting)
|
|
Makefiles__write(W, ins->prototype_setting, ins->makefile_setting,
|
|
WebModules__make_search_path(ins->import_setting));
|
|
else if (ins->gitignore_setting)
|
|
Git__write_gitignore(W, ins->prototype_setting, ins->gitignore_setting);
|
|
else if (ins->advance_setting)
|
|
BuildFiles__advance(ins->advance_setting);
|
|
else if (ins->writeme_setting)
|
|
Readme__write(ins->prototype_setting, ins->writeme_setting);
|
|
|
|
}
|
|
#line 101 "inweb/Chapter 1/Program Control.w"
|
|
|
|
else if (ins->show_languages_switch)
|
|
{
|
|
#line 129 "inweb/Chapter 1/Program Control.w"
|
|
Languages__read_definitions(NULL);
|
|
Languages__show(STDOUT);
|
|
|
|
}
|
|
#line 102 "inweb/Chapter 1/Program Control.w"
|
|
|
|
else if (ins->inweb_mode != NO_MODE)
|
|
{
|
|
#line 135 "inweb/Chapter 1/Program Control.w"
|
|
Reader__print_web_statistics(W);
|
|
if (ins->inweb_mode == ANALYSE_MODE)
|
|
{
|
|
#line 143 "inweb/Chapter 1/Program Control.w"
|
|
if (ins->swarm_mode != SWARM_OFF_SWM)
|
|
Errors__fatal("only specific parts of the web can be analysed");
|
|
if (ins->catalogue_switch)
|
|
Analyser__catalogue_the_sections(W, ins->chosen_range, BASIC_SECTIONCAT);
|
|
if (ins->functions_switch)
|
|
Analyser__catalogue_the_sections(W, ins->chosen_range, FUNCTIONS_SECTIONCAT);
|
|
if (ins->structures_switch)
|
|
Analyser__catalogue_the_sections(W, ins->chosen_range, STRUCTURES_SECTIONCAT);
|
|
if (ins->makefile_setting)
|
|
Analyser__write_makefile(W, ins->makefile_setting,
|
|
WebModules__make_search_path(ins->import_setting));
|
|
if (ins->gitignore_setting)
|
|
Analyser__write_gitignore(W, ins->gitignore_setting);
|
|
if (ins->advance_switch)
|
|
BuildFiles__advance_for_web(W->md);
|
|
if (ins->scan_switch)
|
|
Analyser__scan_line_categories(W, ins->chosen_range);
|
|
|
|
}
|
|
#line 136 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
if (ins->inweb_mode == TANGLE_MODE)
|
|
{
|
|
#line 176 "inweb/Chapter 1/Program Control.w"
|
|
TEMPORARY_TEXT(tangle_leaf);
|
|
tangle_target *tn = NULL;
|
|
if (Str__eq_wide_string(ins->chosen_range, L"0")) {
|
|
|
|
{
|
|
#line 199 "inweb/Chapter 1/Program Control.w"
|
|
tn = NULL;
|
|
if (Bibliographic__data_exists(W->md, TL_IS_72))
|
|
Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_73));
|
|
else
|
|
Str__copy(tangle_leaf, Bibliographic__get_datum(W->md, TL_IS_74));
|
|
Str__concatenate(tangle_leaf, W->main_language->file_extension);
|
|
|
|
}
|
|
#line 179 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
} else if (Reader__get_section_for_range(W, ins->chosen_range)) {
|
|
|
|
{
|
|
#line 209 "inweb/Chapter 1/Program Control.w"
|
|
section *S = Reader__get_section_for_range(W, ins->chosen_range);
|
|
tn = S->sect_target;
|
|
if (tn == NULL) Errors__fatal("section cannot be independently tangled");
|
|
Str__copy(tangle_leaf, Filenames__get_leafname(S->md->source_file_for_section));
|
|
|
|
}
|
|
#line 181 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
}
|
|
if (Str__len(tangle_leaf) == 0) { Errors__fatal("no tangle destination known"); }
|
|
|
|
filename *tangle_to = ins->tangle_setting;
|
|
if (tangle_to == NULL) {
|
|
pathname *P = Reader__tangled_folder(W);
|
|
if (W->md->single_file) P = Filenames__get_path_to(W->md->single_file);
|
|
tangle_to = Filenames__in_folder(P, tangle_leaf);
|
|
}
|
|
if (tn == NULL) tn = Tangler__primary_target(W);
|
|
Tangler__go(W, tn, tangle_to);
|
|
DISCARD_TEXT(tangle_leaf);
|
|
|
|
}
|
|
#line 137 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
if (ins->inweb_mode == WEAVE_MODE)
|
|
{
|
|
#line 217 "inweb/Chapter 1/Program Control.w"
|
|
Numbering__number_web(W);
|
|
if (ins->weave_docs)
|
|
{
|
|
#line 251 "inweb/Chapter 1/Program Control.w"
|
|
if (ins->weave_into_setting == NULL) {
|
|
pathname *docs = Pathnames__subfolder(W->md->path_to_web, TL_IS_75);
|
|
Pathnames__create_in_file_system(docs);
|
|
text_stream *leaf = Str__new();
|
|
if (Bibliographic__data_exists(W->md, TL_IS_76))
|
|
Str__copy(leaf, Bibliographic__get_datum(W->md, TL_IS_77));
|
|
else
|
|
Str__copy(leaf, Bibliographic__get_datum(W->md, TL_IS_78));
|
|
if (Str__len(leaf) > 0) {
|
|
ins->weave_into_setting = Pathnames__subfolder(docs, leaf);
|
|
Pathnames__create_in_file_system(ins->weave_into_setting);
|
|
} else ins->weave_into_setting = docs;
|
|
} else {
|
|
Pathnames__create_in_file_system(ins->weave_into_setting);
|
|
}
|
|
W->redirect_weaves_to = ins->weave_into_setting;
|
|
ins->weave_pattern = TL_IS_79;
|
|
|
|
}
|
|
#line 218 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
|
|
theme_tag *tag = Tags__find_by_name(ins->tag_setting, FALSE);
|
|
if ((Str__len(ins->tag_setting) > 0) && (tag == NULL))
|
|
Errors__fatal_with_text("no such theme as '%S'", ins->tag_setting);
|
|
|
|
weave_pattern *pattern = Patterns__find(W, ins->weave_pattern);
|
|
if ((ins->chosen_range_actually_chosen == FALSE) && (ins->chosen_file == NULL))
|
|
Configuration__set_range(ins, pattern->default_range);
|
|
|
|
int r = Formats__begin_weaving(W, pattern);
|
|
if (r != SWARM_OFF_SWM) ins->swarm_mode = r;
|
|
|
|
{
|
|
#line 270 "inweb/Chapter 1/Program Control.w"
|
|
section *S; int k = 1;
|
|
LOOP_OVER(S, section)
|
|
if (Reader__range_within(S->sect_range, ins->chosen_range))
|
|
S->printed_number = k++;
|
|
|
|
}
|
|
#line 230 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
if (ins->swarm_mode == SWARM_OFF_SWM) {
|
|
int shall_we_open = ins->open_pdf_switch;
|
|
if (shall_we_open == NOT_APPLICABLE) { /* i.e., if it wasn't set at the command line */
|
|
if (Str__len(pattern->open_command) > 0) shall_we_open = TRUE;
|
|
else shall_we_open = FALSE;
|
|
}
|
|
Swarm__weave_subset(W, ins->chosen_range, shall_we_open, tag, pattern,
|
|
ins->weave_to_setting, ins->weave_into_setting, ins->weave_docs,
|
|
ins->breadcrumb_setting, ins->navigation_setting);
|
|
} else {
|
|
Swarm__weave(W, ins->chosen_range, ins->swarm_mode, tag, pattern,
|
|
ins->weave_to_setting, ins->weave_into_setting, ins->weave_docs,
|
|
ins->breadcrumb_setting, ins->navigation_setting);
|
|
}
|
|
Formats__end_weaving(W, pattern);
|
|
|
|
}
|
|
#line 138 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
|
|
}
|
|
#line 103 "inweb/Chapter 1/Program Control.w"
|
|
;
|
|
}
|
|
}
|
|
|
|
#line 281 "inweb/Chapter 1/Program Control.w"
|
|
void Main__error_in_web(text_stream *message, source_line *sl) {
|
|
if (sl) {
|
|
Errors__in_text_file_S(message, &(sl->source));
|
|
WRITE_TO(STDERR, "%07d %S\n", sl->source.line_count, sl->text);
|
|
} else {
|
|
Errors__in_text_file_S(message, NULL);
|
|
}
|
|
no_inweb_errors++;
|
|
}
|
|
|
|
#line 47 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 53 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 60 "inweb/Chapter 1/Configuration.w"
|
|
inweb_instructions Configuration__read(int argc, char **argv) {
|
|
inweb_instructions args;
|
|
|
|
{
|
|
#line 78 "inweb/Chapter 1/Configuration.w"
|
|
args.inweb_mode = NO_MODE;
|
|
args.swarm_mode = SWARM_OFF_SWM;
|
|
args.show_languages_switch = FALSE;
|
|
args.catalogue_switch = FALSE;
|
|
args.functions_switch = FALSE;
|
|
args.structures_switch = FALSE;
|
|
args.advance_switch = FALSE;
|
|
args.open_pdf_switch = NOT_APPLICABLE;
|
|
args.scan_switch = FALSE;
|
|
args.verbose_switch = FALSE;
|
|
args.chosen_web = NULL;
|
|
args.chosen_file = NULL;
|
|
args.chosen_range = Str__new();
|
|
args.chosen_range_actually_chosen = FALSE;
|
|
args.tangle_setting = NULL;
|
|
args.weave_to_setting = NULL;
|
|
args.weave_into_setting = NULL;
|
|
args.sequential = FALSE;
|
|
args.makefile_setting = NULL;
|
|
args.gitignore_setting = NULL;
|
|
args.advance_setting = NULL;
|
|
args.writeme_setting = NULL;
|
|
args.prototype_setting = NULL;
|
|
args.navigation_setting = NULL;
|
|
args.breadcrumb_setting = NEW_LINKED_LIST(breadcrumb_request);
|
|
args.tag_setting = Str__new();
|
|
args.weave_pattern = Str__new_from_wide_string(L"HTML");
|
|
args.weave_docs = FALSE;
|
|
args.import_setting = NULL;
|
|
args.targets = 0;
|
|
|
|
}
|
|
#line 62 "inweb/Chapter 1/Configuration.w"
|
|
;
|
|
|
|
{
|
|
#line 154 "inweb/Chapter 1/Configuration.w"
|
|
CommandLine__declare_heading(L"inweb: a tool for literate programming\n\n"
|
|
L"Usage: inweb WEB OPTIONS RANGE\n\n"
|
|
L"WEB must be a directory holding a literate program (a 'web')\n\n"
|
|
L"The legal RANGEs are:\n"
|
|
L" all: complete web (the default if no TARGETS set)\n"
|
|
L" P: all preliminaries\n"
|
|
L" 1: Chapter 1 (and so on)\n"
|
|
L" A: Appendix A (and so on, up to Appendix O)\n"
|
|
L" 3/eg: section with abbreviated name \"3/eg\" (and so on)\n"
|
|
L"You can also, or instead, specify:\n"
|
|
L" index: to weave an HTML page indexing the project\n"
|
|
L" chapters: to weave all chapters as individual documents\n"
|
|
L" sections: ditto with sections\n");
|
|
|
|
CommandLine__begin_group(LANGUAGES_CLSG,
|
|
TL_IS_81);
|
|
CommandLine__declare_switch(LANGUAGE_CLSW, L"read-language", 2,
|
|
L"read language definition from file X");
|
|
CommandLine__declare_switch(LANGUAGES_CLSW, L"read-languages", 2,
|
|
L"read all language definitions in path X");
|
|
CommandLine__declare_switch(SHOW_LANGUAGES_CLSW, L"show-languages", 1,
|
|
L"list programming languages supported by Inweb");
|
|
CommandLine__end_group();
|
|
|
|
CommandLine__begin_group(ANALYSIS_CLSG,
|
|
TL_IS_82);
|
|
CommandLine__declare_switch(CATALOGUE_CLSW, L"catalogue", 1,
|
|
L"list the sections in the web");
|
|
CommandLine__declare_switch(CATALOGUE_CLSW, L"catalog", 1,
|
|
L"same as '-catalogue'");
|
|
CommandLine__declare_switch(MAKEFILE_CLSW, L"makefile", 2,
|
|
L"write a makefile for this web and store it in X");
|
|
CommandLine__declare_switch(GITIGNORE_CLSW, L"gitignore", 2,
|
|
L"write a .gitignore file for this web and store it in X");
|
|
CommandLine__declare_switch(ADVANCE_FILE_CLSW, L"advance-build-file", 2,
|
|
L"increment daily build code in file X");
|
|
CommandLine__declare_switch(WRITEME_CLSW, L"write-me", 2,
|
|
L"write a read-me file following instructions in file X");
|
|
CommandLine__declare_switch(PROTOTYPE_CLSW, L"prototype", 2,
|
|
L"translate makefile from prototype X");
|
|
CommandLine__declare_switch(FUNCTIONS_CLSW, L"functions", 1,
|
|
L"catalogue the functions in the web");
|
|
CommandLine__declare_switch(STRUCTURES_CLSW, L"structures", 1,
|
|
L"catalogue the structures in the web");
|
|
CommandLine__declare_switch(ADVANCE_CLSW, L"advance-build", 1,
|
|
L"increment daily build code for the web");
|
|
CommandLine__declare_switch(SCAN_CLSW, L"scan", 1,
|
|
L"scan the web");
|
|
CommandLine__end_group();
|
|
|
|
CommandLine__begin_group(WEAVING_CLSG,
|
|
TL_IS_83);
|
|
CommandLine__declare_switch(WEAVE_DOCS_CLSW, L"weave-docs", 1,
|
|
L"weave the web for use at GitHub Pages");
|
|
CommandLine__declare_switch(WEAVE_CLSW, L"weave", 1,
|
|
L"weave the web into human-readable form");
|
|
CommandLine__declare_switch(WEAVE_INTO_CLSW, L"weave-into", 2,
|
|
L"weave, but into directory X");
|
|
CommandLine__declare_switch(WEAVE_TO_CLSW, L"weave-to", 2,
|
|
L"weave, but to filename X (for single files only)");
|
|
CommandLine__declare_boolean_switch(SEQUENTIAL_CLSW, L"sequential", 1,
|
|
L"name woven leaves with sequential numbering", FALSE);
|
|
CommandLine__declare_switch(OPEN_CLSW, L"open", 1,
|
|
L"weave then open woven file");
|
|
CommandLine__declare_switch(WEAVE_AS_CLSW, L"weave-as", 2,
|
|
L"set weave pattern to X (default is 'HTML')");
|
|
CommandLine__declare_switch(WEAVE_TAG_CLSW, L"weave-tag", 2,
|
|
L"weave, but only using material tagged as X");
|
|
CommandLine__declare_switch(BREADCRUMB_CLSW, L"breadcrumb", 2,
|
|
L"use the text X as a breadcrumb in overhead navigation");
|
|
CommandLine__declare_switch(NAVIGATION_CLSW, L"navigation", 2,
|
|
L"use the file X as a column of navigation links");
|
|
CommandLine__end_group();
|
|
|
|
CommandLine__begin_group(TANGLING_CLSG,
|
|
TL_IS_84);
|
|
CommandLine__declare_switch(TANGLE_CLSW, L"tangle", 1,
|
|
L"tangle the web into machine-compilable form");
|
|
CommandLine__declare_switch(TANGLE_TO_CLSW, L"tangle-to", 2,
|
|
L"tangle, but to filename X");
|
|
CommandLine__end_group();
|
|
|
|
CommandLine__declare_boolean_switch(VERBOSE_CLSW, L"verbose", 1,
|
|
L"explain what inweb is doing", FALSE);
|
|
CommandLine__declare_switch(IMPORT_FROM_CLSW, L"import-from", 2,
|
|
L"specify that imported modules are at pathname X");
|
|
|
|
}
|
|
#line 63 "inweb/Chapter 1/Configuration.w"
|
|
;
|
|
CommandLine__read(argc, argv, &args, &Configuration__switch, &Configuration__bareword);
|
|
if ((args.chosen_web == NULL) && (args.chosen_file == NULL)) {
|
|
if ((args.makefile_setting) || (args.gitignore_setting))
|
|
args.inweb_mode = TRANSLATE_MODE;
|
|
if (args.inweb_mode != TRANSLATE_MODE)
|
|
args.inweb_mode = NO_MODE;
|
|
}
|
|
if (Str__len(args.chosen_range) == 0) {
|
|
Str__copy(args.chosen_range, TL_IS_80);
|
|
}
|
|
return args;
|
|
}
|
|
|
|
#line 115 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 117 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 121 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 123 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 134 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 136 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 147 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 149 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 152 "inweb/Chapter 1/Configuration.w"
|
|
|
|
#line 244 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__switch(int id, int val, text_stream *arg, void *state) {
|
|
inweb_instructions *args = (inweb_instructions *) state;
|
|
switch (id) {
|
|
/* Miscellaneous */
|
|
case VERBOSE_CLSW: args->verbose_switch = TRUE; break;
|
|
case IMPORT_FROM_CLSW: args->import_setting = Pathnames__from_text(arg); break;
|
|
|
|
/* Analysis */
|
|
case LANGUAGE_CLSW:
|
|
Languages__read_definition(Filenames__from_text(arg)); break;
|
|
case LANGUAGES_CLSW:
|
|
Languages__read_definitions(Pathnames__from_text(arg)); break;
|
|
case SHOW_LANGUAGES_CLSW:
|
|
args->show_languages_switch = TRUE;
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
|
|
case CATALOGUE_CLSW:
|
|
args->catalogue_switch = TRUE;
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
|
|
case FUNCTIONS_CLSW:
|
|
args->functions_switch = TRUE;
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
|
|
case STRUCTURES_CLSW:
|
|
args->structures_switch = TRUE;
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
|
|
case ADVANCE_CLSW:
|
|
args->advance_switch = TRUE;
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
|
|
case MAKEFILE_CLSW:
|
|
args->makefile_setting = Filenames__from_text(arg);
|
|
if (args->inweb_mode != TRANSLATE_MODE)
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE);
|
|
break;
|
|
case GITIGNORE_CLSW:
|
|
args->gitignore_setting = Filenames__from_text(arg);
|
|
if (args->inweb_mode != TRANSLATE_MODE)
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE);
|
|
break;
|
|
case ADVANCE_FILE_CLSW:
|
|
args->advance_setting = Filenames__from_text(arg);
|
|
Configuration__set_fundamental_mode(args, TRANSLATE_MODE);
|
|
break;
|
|
case WRITEME_CLSW:
|
|
args->writeme_setting = Filenames__from_text(arg);
|
|
Configuration__set_fundamental_mode(args, TRANSLATE_MODE);
|
|
break;
|
|
case PROTOTYPE_CLSW:
|
|
args->prototype_setting = Filenames__from_text(arg);
|
|
Configuration__set_fundamental_mode(args, TRANSLATE_MODE); break;
|
|
case SCAN_CLSW:
|
|
args->scan_switch = TRUE;
|
|
Configuration__set_fundamental_mode(args, ANALYSE_MODE); break;
|
|
|
|
/* Weave-related */
|
|
case WEAVE_CLSW:
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case WEAVE_DOCS_CLSW:
|
|
args->weave_docs = TRUE;
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case WEAVE_INTO_CLSW:
|
|
args->weave_into_setting = Pathnames__from_text(arg);
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case WEAVE_TO_CLSW:
|
|
args->weave_to_setting = Filenames__from_text(arg);
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case SEQUENTIAL_CLSW:
|
|
args->sequential = val; break;
|
|
case OPEN_CLSW:
|
|
args->open_pdf_switch = TRUE;
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case WEAVE_AS_CLSW:
|
|
args->weave_pattern = Str__duplicate(arg);
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case WEAVE_TAG_CLSW:
|
|
args->tag_setting = Str__duplicate(arg);
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case BREADCRUMB_CLSW:
|
|
ADD_TO_LINKED_LIST(Configuration__breadcrumb(arg),
|
|
breadcrumb_request, args->breadcrumb_setting);
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
case NAVIGATION_CLSW:
|
|
args->navigation_setting = Filenames__from_text(arg);
|
|
Configuration__set_fundamental_mode(args, WEAVE_MODE); break;
|
|
|
|
/* Tangle-related */
|
|
case TANGLE_CLSW:
|
|
Configuration__set_fundamental_mode(args, TANGLE_MODE); break;
|
|
case TANGLE_TO_CLSW:
|
|
args->tangle_setting = Filenames__from_text(arg);
|
|
Configuration__set_fundamental_mode(args, TANGLE_MODE); break;
|
|
|
|
default: internal_error("unimplemented switch");
|
|
}
|
|
}
|
|
|
|
breadcrumb_request *Configuration__breadcrumb(text_stream *arg) {
|
|
breadcrumb_request *BR = CREATE(breadcrumb_request);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, arg, L"(%c*?): *(%c*)")) {
|
|
BR->breadcrumb_text = Str__duplicate(mr.exp[0]);
|
|
BR->breadcrumb_link = Str__duplicate(mr.exp[1]);
|
|
} else {
|
|
BR->breadcrumb_text = Str__duplicate(arg);
|
|
BR->breadcrumb_link = Str__duplicate(arg);
|
|
WRITE_TO(BR->breadcrumb_link, ".html");
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
return BR;
|
|
}
|
|
|
|
#line 358 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__bareword(int id, text_stream *opt, void *state) {
|
|
inweb_instructions *args = (inweb_instructions *) state;
|
|
if ((args->chosen_web == NULL) && (args->chosen_file == NULL)) {
|
|
if (Str__suffix_eq(opt, TL_IS_85, 6))
|
|
args->chosen_file = Filenames__from_text(opt);
|
|
else
|
|
args->chosen_web = Pathnames__from_text(opt);
|
|
} else Configuration__set_range(args, opt);
|
|
}
|
|
|
|
#line 373 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__set_range(inweb_instructions *args, text_stream *opt) {
|
|
match_results mr = Regexp__create_mr();
|
|
if (Str__eq_wide_string(opt, L"index")) {
|
|
args->swarm_mode = SWARM_INDEX_SWM;
|
|
} else if (Str__eq_wide_string(opt, L"chapters")) {
|
|
args->swarm_mode = SWARM_CHAPTERS_SWM;
|
|
} else if (Str__eq_wide_string(opt, L"sections")) {
|
|
args->swarm_mode = SWARM_SECTIONS_SWM;
|
|
} else {
|
|
if (++args->targets > 1) Errors__fatal("at most one target may be given");
|
|
if (Str__eq_wide_string(opt, L"all")) {
|
|
Str__copy(args->chosen_range, TL_IS_86);
|
|
} else if (((isalnum(Str__get_first_char(opt))) && (Str__len(opt) == 1))
|
|
|| (Regexp__match(&mr, opt, L"%i+/%i+"))) {
|
|
Str__copy(args->chosen_range, opt);
|
|
string_position P = Str__start(args->chosen_range);
|
|
Str__put(P, toupper(Str__get(P)));
|
|
} else {
|
|
TEMPORARY_TEXT(ERM);
|
|
WRITE_TO(ERM, "target not recognised (see -help for more): %S", opt);
|
|
Main__error_in_web(ERM, NULL);
|
|
DISCARD_TEXT(ERM);
|
|
exit(1);
|
|
}
|
|
}
|
|
args->chosen_range_actually_chosen = TRUE;
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 405 "inweb/Chapter 1/Configuration.w"
|
|
void Configuration__set_fundamental_mode(inweb_instructions *args, int new_material) {
|
|
if ((args->inweb_mode != NO_MODE) && (args->inweb_mode != new_material))
|
|
Errors__fatal("can only do one at a time - weaving, tangling or analysing");
|
|
args->inweb_mode = new_material;
|
|
}
|
|
|
|
#line 33 "inweb/Chapter 1/Patterns.w"
|
|
|
|
#line 37 "inweb/Chapter 1/Patterns.w"
|
|
weave_pattern *Patterns__find(web *W, text_stream *name) {
|
|
filename *pattern_file = NULL;
|
|
weave_pattern *wp = CREATE(weave_pattern);
|
|
|
|
{
|
|
#line 47 "inweb/Chapter 1/Patterns.w"
|
|
wp->pattern_name = Str__duplicate(name);
|
|
wp->pattern_location = NULL;
|
|
wp->payloads = NEW_LINKED_LIST(text_stream);
|
|
wp->up_payloads = NEW_LINKED_LIST(text_stream);
|
|
wp->based_on = NULL;
|
|
wp->embed_CSS = FALSE;
|
|
wp->hierarchical = FALSE;
|
|
wp->patterned_for = W;
|
|
wp->show_abbrevs = TRUE;
|
|
wp->number_sections = FALSE;
|
|
wp->default_range = Str__duplicate(TL_IS_87);
|
|
wp->tex_command = Str__duplicate(TL_IS_88);
|
|
wp->pdftex_command = Str__duplicate(TL_IS_89);
|
|
wp->open_command = Str__duplicate(TL_IS_90);
|
|
|
|
}
|
|
#line 40 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
|
|
{
|
|
#line 63 "inweb/Chapter 1/Patterns.w"
|
|
wp->pattern_location =
|
|
Pathnames__subfolder(
|
|
Pathnames__subfolder(W->md->path_to_web, TL_IS_91),
|
|
name);
|
|
pattern_file = Filenames__in_folder(wp->pattern_location, TL_IS_92);
|
|
if (TextFiles__exists(pattern_file) == FALSE) {
|
|
wp->pattern_location = Pathnames__subfolder(path_to_inweb_patterns, name);
|
|
pattern_file = Filenames__in_folder(wp->pattern_location, TL_IS_93);
|
|
if (TextFiles__exists(pattern_file) == FALSE)
|
|
Errors__fatal_with_text("no such weave pattern as '%S'", name);
|
|
}
|
|
|
|
}
|
|
#line 41 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
|
|
{
|
|
#line 76 "inweb/Chapter 1/Patterns.w"
|
|
if (pattern_file)
|
|
TextFiles__read(pattern_file, FALSE, "can't open pattern.txt file",
|
|
TRUE, Patterns__scan_pattern_line, NULL, wp);
|
|
if (wp->pattern_format == NULL)
|
|
Errors__fatal_with_text("pattern did not specify a format", name);
|
|
|
|
}
|
|
#line 42 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
return wp;
|
|
}
|
|
|
|
#line 87 "inweb/Chapter 1/Patterns.w"
|
|
void Patterns__scan_pattern_line(text_stream *line, text_file_position *tfp, void *X) {
|
|
weave_pattern *wp = (weave_pattern *) X;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L" *from (%c+)"))
|
|
{
|
|
#line 102 "inweb/Chapter 1/Patterns.w"
|
|
wp->based_on = Patterns__find(wp->patterned_for, mr.exp[0]);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 90 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *(%c+?) = (%c+)"))
|
|
{
|
|
#line 107 "inweb/Chapter 1/Patterns.w"
|
|
if (Str__eq(mr.exp[0], TL_IS_94)) {
|
|
wp->pattern_format = Formats__find_by_name(mr.exp[1]);
|
|
} else if (Str__eq(mr.exp[0], TL_IS_95)) {
|
|
wp->show_abbrevs = Patterns__yes_or_no(mr.exp[1], tfp);
|
|
} else if (Str__eq(mr.exp[0], TL_IS_96)) {
|
|
wp->number_sections = Patterns__yes_or_no(mr.exp[1], tfp);
|
|
} else if (Str__eq(mr.exp[0], TL_IS_97)) {
|
|
wp->default_range = Str__duplicate(mr.exp[1]);
|
|
} else if (Str__eq(mr.exp[0], TL_IS_98)) {
|
|
wp->tex_command = Str__duplicate(mr.exp[1]);
|
|
} else if (Str__eq(mr.exp[0], TL_IS_99)) {
|
|
wp->pdftex_command = Str__duplicate(mr.exp[1]);
|
|
} else if (Str__eq(mr.exp[0], TL_IS_100)) {
|
|
wp->open_command = Str__duplicate(mr.exp[1]);
|
|
} else if ((Bibliographic__data_exists(wp->patterned_for->md, mr.exp[0])) ||
|
|
(Str__eq(mr.exp[0], TL_IS_101))) {
|
|
Bibliographic__set_datum(wp->patterned_for->md, mr.exp[0], mr.exp[1]);
|
|
} else {
|
|
PRINT("Setting: %S\n", mr.exp[0]);
|
|
Errors__in_text_file("no such pattern setting", tfp);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 91 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *embed css *"))
|
|
{
|
|
#line 132 "inweb/Chapter 1/Patterns.w"
|
|
wp->embed_CSS = TRUE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 92 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *hierarchical *"))
|
|
{
|
|
#line 137 "inweb/Chapter 1/Patterns.w"
|
|
wp->hierarchical = TRUE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 93 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *use (%c+)"))
|
|
{
|
|
#line 146 "inweb/Chapter 1/Patterns.w"
|
|
text_stream *leafname = Str__duplicate(mr.exp[0]);
|
|
ADD_TO_LINKED_LIST(leafname, text_stream, wp->payloads);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 94 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *use-up (%c+)"))
|
|
{
|
|
#line 152 "inweb/Chapter 1/Patterns.w"
|
|
text_stream *leafname = Str__duplicate(mr.exp[0]);
|
|
ADD_TO_LINKED_LIST(leafname, text_stream, wp->up_payloads);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 95 "inweb/Chapter 1/Patterns.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *%C%c*"))
|
|
Errors__in_text_file("unrecognised pattern command", tfp);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 158 "inweb/Chapter 1/Patterns.w"
|
|
int Patterns__yes_or_no(text_stream *arg, text_file_position *tfp) {
|
|
if (Str__eq(arg, TL_IS_102)) return TRUE;
|
|
if (Str__eq(arg, TL_IS_103)) return FALSE;
|
|
Errors__in_text_file("setting must be 'yes' or 'no'", tfp);
|
|
return FALSE;
|
|
}
|
|
|
|
#line 176 "inweb/Chapter 1/Patterns.w"
|
|
filename *Patterns__obtain_filename(weave_pattern *pattern, text_stream *leafname) {
|
|
if (Str__prefix_eq(leafname, TL_IS_104, 3)) {
|
|
Str__delete_first_character(leafname);
|
|
Str__delete_first_character(leafname);
|
|
Str__delete_first_character(leafname);
|
|
}
|
|
filename *F = Filenames__in_folder(pattern->pattern_location, leafname);
|
|
if (TextFiles__exists(F)) return F;
|
|
if (pattern->based_on) return Patterns__obtain_filename(pattern->based_on, leafname);
|
|
return NULL;
|
|
}
|
|
|
|
#line 192 "inweb/Chapter 1/Patterns.w"
|
|
void Patterns__copy_payloads_into_weave(web *W, weave_pattern *pattern) {
|
|
text_stream *leafname;
|
|
LOOP_OVER_LINKED_LIST(leafname, text_stream, pattern->payloads) {
|
|
filename *F = Patterns__obtain_filename(pattern, leafname);
|
|
Patterns__copy_file_into_weave(W, F);
|
|
if (W->as_ebook) {
|
|
filename *rel = Filenames__in_folder(NULL, leafname);
|
|
Epub__note_image(W->as_ebook, rel);
|
|
}
|
|
}
|
|
LOOP_OVER_LINKED_LIST(leafname, text_stream, pattern->up_payloads) {
|
|
filename *F = Patterns__obtain_filename(pattern, leafname);
|
|
Patterns__copy_up_file_into_weave(W, F);
|
|
if (W->as_ebook) {
|
|
filename *rel = Filenames__in_folder(NULL, leafname);
|
|
Epub__note_image(W->as_ebook, rel);
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 213 "inweb/Chapter 1/Patterns.w"
|
|
void Patterns__copy_file_into_weave(web *W, filename *F) {
|
|
pathname *H = W->redirect_weaves_to;
|
|
if (H == NULL) H = Reader__woven_folder(W);
|
|
Shell__copy(F, H, "");
|
|
}
|
|
void Patterns__copy_up_file_into_weave(web *W, filename *F) {
|
|
pathname *H = W->redirect_weaves_to;
|
|
if (H == NULL) H = Reader__woven_folder(W);
|
|
H = Pathnames__up(H);
|
|
Shell__copy(F, H, "");
|
|
}
|
|
|
|
#line 47 "inweb/Chapter 2/The Reader.w"
|
|
|
|
#line 61 "inweb/Chapter 2/The Reader.w"
|
|
|
|
#line 93 "inweb/Chapter 2/The Reader.w"
|
|
|
|
#line 98 "inweb/Chapter 2/The Reader.w"
|
|
web_md *Reader__load_web_md(pathname *P, filename *alt_F, module_search *I, int verbosely,
|
|
int including_modules) {
|
|
return WebMetadata__get(P, alt_F, default_inweb_syntax, I, verbosely,
|
|
including_modules, path_to_inweb);
|
|
}
|
|
|
|
web *Reader__load_web(pathname *P, filename *alt_F, module_search *I, int verbosely,
|
|
int including_modules) {
|
|
|
|
web *W = CREATE(web);
|
|
W->md = Reader__load_web_md(P, alt_F, I, verbosely, including_modules);
|
|
tangle_target *main_target = NULL;
|
|
|
|
|
|
{
|
|
#line 135 "inweb/Chapter 2/The Reader.w"
|
|
TEMPORARY_TEXT(IB);
|
|
WRITE_TO(IB, "%s", INWEB_BUILD);
|
|
web_bibliographic_datum *bd = Bibliographic__set_datum(W->md, TL_IS_105, IB);
|
|
bd->declaration_permitted = FALSE;
|
|
DISCARD_TEXT(IB);
|
|
|
|
}
|
|
#line 111 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
|
|
{
|
|
#line 142 "inweb/Chapter 2/The Reader.w"
|
|
W->chapters = NEW_LINKED_LIST(chapter);
|
|
W->headers = NEW_LINKED_LIST(filename);
|
|
W->c_structures = NEW_LINKED_LIST(c_structure);
|
|
W->tangle_targets = NEW_LINKED_LIST(tangle_target);
|
|
W->analysed = FALSE;
|
|
W->as_ebook = NULL;
|
|
W->redirect_weaves_to = NULL;
|
|
W->main_language = Languages__default();
|
|
W->no_lines = 0; W->no_paragraphs = 0;
|
|
text_stream *language_name = Bibliographic__get_datum(W->md, TL_IS_106);
|
|
if (Str__len(language_name) > 0)
|
|
W->main_language = Languages__find_by_name(language_name);
|
|
main_target = Reader__add_tangle_target(W, W->main_language);
|
|
|
|
}
|
|
#line 112 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
chapter_md *Cm;
|
|
LOOP_OVER_LINKED_LIST(Cm, chapter_md, W->md->chapters_md) {
|
|
chapter *C = CREATE(chapter);
|
|
C->md = Cm;
|
|
C->owning_web = W;
|
|
|
|
{
|
|
#line 157 "inweb/Chapter 2/The Reader.w"
|
|
C->ch_weave = NULL;
|
|
C->titling_line_inserted = FALSE;
|
|
C->sections = NEW_LINKED_LIST(section);
|
|
C->ch_language = W->main_language;
|
|
if (Str__len(Cm->ch_language_name) > 0)
|
|
C->ch_language = Languages__find_by_name(Cm->ch_language_name);
|
|
|
|
}
|
|
#line 118 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
ADD_TO_LINKED_LIST(C, chapter, W->chapters);
|
|
section_md *Sm;
|
|
LOOP_OVER_LINKED_LIST(Sm, section_md, Cm->sections_md) {
|
|
section *S = CREATE(section);
|
|
S->md = Sm;
|
|
S->owning_chapter = C;
|
|
S->owning_web = W;
|
|
|
|
{
|
|
#line 165 "inweb/Chapter 2/The Reader.w"
|
|
S->sect_extent = 0;
|
|
S->first_line = NULL; S->last_line = NULL;
|
|
S->sect_paragraphs = 0;
|
|
S->paragraphs = NEW_LINKED_LIST(paragraph);
|
|
S->macros = NEW_LINKED_LIST(para_macro);
|
|
|
|
S->scratch_flag = FALSE;
|
|
S->barred = FALSE;
|
|
S->printed_number = -1;
|
|
S->sect_weave = NULL;
|
|
S->sect_namespace = Str__new();
|
|
S->owning_web = W;
|
|
S->sect_language = C->ch_language;
|
|
if (Str__len(S->md->sect_language_name) > 0)
|
|
S->sect_language = Languages__find_by_name(S->md->sect_language_name);
|
|
if (Str__len(S->md->sect_independent_language) > 0) {
|
|
programming_language *pl =
|
|
Languages__find_by_name(S->md->sect_independent_language);
|
|
S->sect_language = pl;
|
|
S->sect_target = Reader__add_tangle_target(W, pl);
|
|
} else {
|
|
S->sect_target = main_target;
|
|
}
|
|
S->tag_with = NULL;
|
|
if (Str__len(Sm->tag_name) > 0)
|
|
S->tag_with = Tags__add_by_name(NULL, Sm->tag_name);
|
|
S->sect_range = Str__new();
|
|
|
|
}
|
|
#line 126 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
ADD_TO_LINKED_LIST(S, section, C->sections);
|
|
}
|
|
}
|
|
|
|
{
|
|
#line 194 "inweb/Chapter 2/The Reader.w"
|
|
filename *HF;
|
|
LOOP_OVER_LINKED_LIST(HF, filename, W->md->header_filenames)
|
|
Reader__add_imported_header(W, HF);
|
|
|
|
}
|
|
#line 130 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
return W;
|
|
}
|
|
|
|
#line 207 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__read_web(web *W, int verbosely) {
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)
|
|
Reader__read_file(W, C,
|
|
S->md->source_file_for_section,
|
|
S->md->titling_line_to_insert, S, verbosely,
|
|
(W->md->single_file)?TRUE:FALSE);
|
|
}
|
|
|
|
#line 221 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__read_file(web *W, chapter *C, filename *F, text_stream *titling_line,
|
|
section *S, int verbosely, int disregard_top) {
|
|
S->owning_chapter = C;
|
|
if (disregard_top)
|
|
S->paused_until_at = TRUE;
|
|
else
|
|
S->paused_until_at = FALSE;
|
|
|
|
if ((titling_line) && (Str__len(titling_line) > 0) &&
|
|
(S->owning_chapter->titling_line_inserted == FALSE))
|
|
|
|
{
|
|
#line 243 "inweb/Chapter 2/The Reader.w"
|
|
S->owning_chapter->titling_line_inserted = TRUE;
|
|
TEMPORARY_TEXT(line);
|
|
text_file_position *tfp = NULL;
|
|
WRITE_TO(line, "Chapter Heading");
|
|
|
|
{
|
|
#line 277 "inweb/Chapter 2/The Reader.w"
|
|
source_line *sl = Lines__new_source_line(line, tfp);
|
|
|
|
/* enter this in its section's linked list of lines: */
|
|
sl->owning_section = S;
|
|
if (S->first_line == NULL) S->first_line = sl;
|
|
else S->last_line->next_line = sl;
|
|
S->last_line = sl;
|
|
|
|
/* we haven't detected paragraph boundaries yet, so: */
|
|
sl->owning_paragraph = NULL;
|
|
|
|
/* and keep count: */
|
|
sl->owning_section->sect_extent++;
|
|
sl->owning_section->owning_chapter->owning_web->no_lines++;
|
|
|
|
}
|
|
#line 247 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
DISCARD_TEXT(line);
|
|
|
|
}
|
|
#line 231 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
|
|
if (disregard_top)
|
|
|
|
{
|
|
#line 251 "inweb/Chapter 2/The Reader.w"
|
|
TEMPORARY_TEXT(line);
|
|
text_file_position *tfp = NULL;
|
|
WRITE_TO(line, "Main.");
|
|
|
|
{
|
|
#line 277 "inweb/Chapter 2/The Reader.w"
|
|
source_line *sl = Lines__new_source_line(line, tfp);
|
|
|
|
/* enter this in its section's linked list of lines: */
|
|
sl->owning_section = S;
|
|
if (S->first_line == NULL) S->first_line = sl;
|
|
else S->last_line->next_line = sl;
|
|
S->last_line = sl;
|
|
|
|
/* we haven't detected paragraph boundaries yet, so: */
|
|
sl->owning_paragraph = NULL;
|
|
|
|
/* and keep count: */
|
|
sl->owning_section->sect_extent++;
|
|
sl->owning_section->owning_chapter->owning_web->no_lines++;
|
|
|
|
}
|
|
#line 254 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
Str__clear(line);
|
|
|
|
{
|
|
#line 277 "inweb/Chapter 2/The Reader.w"
|
|
source_line *sl = Lines__new_source_line(line, tfp);
|
|
|
|
/* enter this in its section's linked list of lines: */
|
|
sl->owning_section = S;
|
|
if (S->first_line == NULL) S->first_line = sl;
|
|
else S->last_line->next_line = sl;
|
|
S->last_line = sl;
|
|
|
|
/* we haven't detected paragraph boundaries yet, so: */
|
|
sl->owning_paragraph = NULL;
|
|
|
|
/* and keep count: */
|
|
sl->owning_section->sect_extent++;
|
|
sl->owning_section->owning_chapter->owning_web->no_lines++;
|
|
|
|
}
|
|
#line 256 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
DISCARD_TEXT(line);
|
|
|
|
}
|
|
#line 234 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
|
|
int cl = TextFiles__read(F, FALSE, "can't open section file", TRUE,
|
|
Reader__scan_source_line, NULL, (void *) S);
|
|
if (verbosely)
|
|
PRINT("Read section: '%S' (%d lines)\n", S->md->sect_title, cl);
|
|
}
|
|
|
|
#line 264 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__scan_source_line(text_stream *line, text_file_position *tfp, void *state) {
|
|
section *S = (section *) state;
|
|
int l = Str__len(line) - 1;
|
|
while ((l>=0) && (Characters__is_space_or_tab(Str__get_at(line, l)))) Str__truncate(line, l--);
|
|
|
|
if (S->paused_until_at) {
|
|
if (Str__get_at(line, 0) == '@') S->paused_until_at = FALSE;
|
|
else return;
|
|
}
|
|
|
|
{
|
|
#line 277 "inweb/Chapter 2/The Reader.w"
|
|
source_line *sl = Lines__new_source_line(line, tfp);
|
|
|
|
/* enter this in its section's linked list of lines: */
|
|
sl->owning_section = S;
|
|
if (S->first_line == NULL) S->first_line = sl;
|
|
else S->last_line->next_line = sl;
|
|
S->last_line = sl;
|
|
|
|
/* we haven't detected paragraph boundaries yet, so: */
|
|
sl->owning_paragraph = NULL;
|
|
|
|
/* and keep count: */
|
|
sl->owning_section->sect_extent++;
|
|
sl->owning_section->owning_chapter->owning_web->no_lines++;
|
|
|
|
}
|
|
#line 273 "inweb/Chapter 2/The Reader.w"
|
|
;
|
|
}
|
|
|
|
#line 296 "inweb/Chapter 2/The Reader.w"
|
|
pathname *Reader__woven_folder(web *W) {
|
|
pathname *P = Pathnames__subfolder(W->md->path_to_web, TL_IS_107);
|
|
if (Pathnames__create_in_file_system(P) == FALSE)
|
|
Errors__fatal_with_path("unable to create Woven subdirectory", P);
|
|
return P;
|
|
}
|
|
pathname *Reader__tangled_folder(web *W) {
|
|
pathname *P = Pathnames__subfolder(W->md->path_to_web, TL_IS_108);
|
|
if (Pathnames__create_in_file_system(P) == FALSE)
|
|
Errors__fatal_with_path("unable to create Tangled subdirectory", P);
|
|
return P;
|
|
}
|
|
|
|
#line 317 "inweb/Chapter 2/The Reader.w"
|
|
chapter *Reader__get_chapter_for_range(web *W, text_stream *range) {
|
|
chapter *C;
|
|
if (W)
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
if (Str__eq(C->md->ch_range, range))
|
|
return C;
|
|
return NULL;
|
|
}
|
|
|
|
section *Reader__get_section_for_range(web *W, text_stream *range) {
|
|
chapter *C;
|
|
section *S;
|
|
if (W)
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)
|
|
if (Str__eq(S->sect_range, range))
|
|
return S;
|
|
return NULL;
|
|
}
|
|
|
|
#line 340 "inweb/Chapter 2/The Reader.w"
|
|
section *Reader__section_by_filename(web *W, text_stream *filename) {
|
|
chapter *C;
|
|
section *S;
|
|
if (W)
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
|
|
TEMPORARY_TEXT(SFN);
|
|
WRITE_TO(SFN, "%f", S->md->source_file_for_section);
|
|
int rv = Str__eq(SFN, filename);
|
|
DISCARD_TEXT(SFN);
|
|
if (rv) return S;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#line 362 "inweb/Chapter 2/The Reader.w"
|
|
int Reader__range_within(text_stream *range1, text_stream *range2) {
|
|
if (Str__eq_wide_string(range2, L"0")) return TRUE;
|
|
if (Str__eq(range1, range2)) return TRUE;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, range2, L"%c+/%c+")) { Regexp__dispose_of(&mr); return FALSE; }
|
|
if (Regexp__match(&mr, range1, L"(%c+)/%c+")) {
|
|
if (Str__eq(mr.exp[0], range2)) { Regexp__dispose_of(&mr); return TRUE; }
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#line 389 "inweb/Chapter 2/The Reader.w"
|
|
|
|
#line 391 "inweb/Chapter 2/The Reader.w"
|
|
tangle_target *Reader__add_tangle_target(web *W, programming_language *language) {
|
|
tangle_target *tt = CREATE(tangle_target);
|
|
tt->tangle_language = language;
|
|
ADD_TO_LINKED_LIST(tt, tangle_target, W->tangle_targets);
|
|
tt->symbols.analysis_hash_initialised = FALSE;
|
|
return tt;
|
|
}
|
|
|
|
#line 415 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__add_imported_header(web *W, filename *HF) {
|
|
ADD_TO_LINKED_LIST(HF, filename, W->headers);
|
|
}
|
|
|
|
#line 422 "inweb/Chapter 2/The Reader.w"
|
|
int Reader__web_has_one_section(web *W) {
|
|
if (WebMetadata__section_count(W->md) == 1) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
#line 430 "inweb/Chapter 2/The Reader.w"
|
|
void Reader__print_web_statistics(web *W) {
|
|
PRINT("web \"%S\": ", Bibliographic__get_datum(W->md, TL_IS_109));
|
|
int c = WebMetadata__chapter_count(W->md);
|
|
int s = WebMetadata__section_count(W->md);
|
|
if (W->md->chaptered) PRINT("%d chapter%s : ",
|
|
c, (c == 1)?"":"s");
|
|
PRINT("%d section%s : %d paragraph%s : %d line%s\n",
|
|
s, (s == 1)?"":"s",
|
|
W->no_paragraphs, (W->no_paragraphs == 1)?"":"s",
|
|
W->no_lines, (W->no_lines == 1)?"":"s");
|
|
}
|
|
|
|
|
|
|
|
#line 41 "inweb/Chapter 2/Line Categories.w"
|
|
|
|
#line 43 "inweb/Chapter 2/Line Categories.w"
|
|
source_line *Lines__new_source_line(text_stream *line, text_file_position *tfp) {
|
|
source_line *sl = CREATE(source_line);
|
|
sl->text = Str__duplicate(line);
|
|
sl->text_operand = Str__new();
|
|
sl->text_operand2 = Str__new();
|
|
|
|
sl->category = NO_LCAT; /* that is, unknown category as yet */
|
|
sl->command_code = NO_CMD;
|
|
sl->default_defn = FALSE;
|
|
sl->colour_as = NULL;
|
|
sl->is_commentary = FALSE;
|
|
sl->function_defined = NULL;
|
|
sl->preform_nonterminal_defined = NULL;
|
|
sl->suppress_tangling = FALSE;
|
|
sl->interface_line_identified = FALSE;
|
|
|
|
if (tfp) sl->source = *tfp; else sl->source = TextFiles__nowhere();
|
|
|
|
sl->owning_section = NULL;
|
|
sl->next_line = NULL;
|
|
sl->owning_paragraph = NULL;
|
|
return sl;
|
|
}
|
|
|
|
#line 75 "inweb/Chapter 2/Line Categories.w"
|
|
|
|
#line 99 "inweb/Chapter 2/Line Categories.w"
|
|
|
|
#line 104 "inweb/Chapter 2/Line Categories.w"
|
|
char *Lines__category_name(int cat) {
|
|
switch (cat) {
|
|
case NO_LCAT: return "(uncategorised)";
|
|
|
|
case BAR_LCAT: return "BAR";
|
|
case BEGIN_CODE_LCAT: return "BEGIN_CODE";
|
|
case BEGIN_DEFINITION_LCAT: return "BEGIN_DEFINITION";
|
|
case C_LIBRARY_INCLUDE_LCAT: return "C_LIBRARY_INCLUDE";
|
|
case CHAPTER_HEADING_LCAT: return "CHAPTER_HEADING";
|
|
case CODE_BODY_LCAT: return "CODE_BODY";
|
|
case COMMAND_LCAT: return "COMMAND";
|
|
case COMMENT_BODY_LCAT: return "COMMENT_BODY";
|
|
case CONT_DEFINITION_LCAT: return "CONT_DEFINITION";
|
|
case DEFINITIONS_LCAT: return "DEFINITIONS";
|
|
case HEADING_START_LCAT: return "PB_PARAGRAPH_START";
|
|
case INTERFACE_BODY_LCAT: return "INTERFACE_BODY";
|
|
case INTERFACE_LCAT: return "INTERFACE";
|
|
case MACRO_DEFINITION_LCAT: return "MACRO_DEFINITION";
|
|
case PARAGRAPH_START_LCAT: return "PARAGRAPH_START";
|
|
case PREFORM_GRAMMAR_LCAT: return "PREFORM_GRAMMAR";
|
|
case PREFORM_LCAT: return "PREFORM";
|
|
case PURPOSE_BODY_LCAT: return "PURPOSE_BODY";
|
|
case PURPOSE_LCAT: return "PURPOSE";
|
|
case SECTION_HEADING_LCAT: return "SECTION_HEADING";
|
|
case SOURCE_DISPLAY_LCAT: return "SOURCE_DISPLAY";
|
|
case TEXT_EXTRACT_LCAT: return "TEXT_EXTRACT";
|
|
case TYPEDEF_LCAT: return "TYPEDEF";
|
|
}
|
|
return "(?unknown)";
|
|
}
|
|
|
|
#line 144 "inweb/Chapter 2/Line Categories.w"
|
|
|
|
#line 17 "inweb/Chapter 2/The Parser.w"
|
|
void Parser__parse_web(web *W, int inweb_mode, int sequential) {
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) {
|
|
int section_counter = 1;
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
|
|
|
|
{
|
|
#line 36 "inweb/Chapter 2/The Parser.w"
|
|
int comment_mode = TRUE;
|
|
int code_lcat_for_body = NO_LCAT;
|
|
programming_language *code_pl_for_body = NULL;
|
|
int before_bar = TRUE;
|
|
int next_par_number = 1;
|
|
paragraph *current_paragraph = NULL;
|
|
TEMPORARY_TEXT(tag_list);
|
|
for (source_line *L = S->first_line, *PL = NULL; L; PL = L, L = L->next_line) {
|
|
|
|
{
|
|
#line 78 "inweb/Chapter 2/The Parser.w"
|
|
match_results mr = Regexp__create_mr();
|
|
while (Regexp__match(&mr, tag_list, L" *%^\"(%c+?)\" *(%c*)")) {
|
|
Tags__add_by_name(current_paragraph, mr.exp[0]);
|
|
Str__copy(tag_list, mr.exp[1]);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
Str__clear(tag_list);
|
|
|
|
}
|
|
#line 44 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
{
|
|
#line 62 "inweb/Chapter 2/The Parser.w"
|
|
if (Str__get_first_char(L->text) == '@') {
|
|
match_results mr = Regexp__create_mr();
|
|
while (Regexp__match(&mr, L->text, L"(%c*?)( *%^\"%c+?\")(%c*)")) {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "tags written ^\"thus\"", V2_SYNTAX);
|
|
Str__clear(L->text);
|
|
WRITE_TO(tag_list, "%S", mr.exp[1]);
|
|
Str__copy(L->text, mr.exp[0]); WRITE_TO(L->text, " %S", mr.exp[2]);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
}
|
|
#line 45 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
{
|
|
#line 109 "inweb/Chapter 2/The Parser.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if ((PL) && (PL->category == CODE_BODY_LCAT) &&
|
|
(Str__get_first_char(L->text) == '@') && (Str__get_at(L->text, 1) == '<') &&
|
|
(Regexp__match(&mr, L->text, L"%c<(%c+)@> *= *")) &&
|
|
(S->md->using_syntax >= V2_SYNTAX)) {
|
|
|
|
{
|
|
#line 129 "inweb/Chapter 2/The Parser.w"
|
|
source_line *NL = Lines__new_source_line(TL_IS_112, &(L->source));
|
|
PL->next_line = NL;
|
|
NL->next_line = L;
|
|
L = PL;
|
|
Regexp__dispose_of(&mr);
|
|
continue;
|
|
|
|
}
|
|
#line 114 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
}
|
|
if ((PL) && (Regexp__match(&mr, L->text, L"@ *= *"))) {
|
|
Str__clear(L->text);
|
|
Str__copy(L->text, TL_IS_111);
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "implied paragraph breaks", V2_SYNTAX);
|
|
|
|
{
|
|
#line 129 "inweb/Chapter 2/The Parser.w"
|
|
source_line *NL = Lines__new_source_line(TL_IS_112, &(L->source));
|
|
PL->next_line = NL;
|
|
NL->next_line = L;
|
|
L = PL;
|
|
Regexp__dispose_of(&mr);
|
|
continue;
|
|
|
|
}
|
|
#line 121 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 46 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
{
|
|
#line 141 "inweb/Chapter 2/The Parser.w"
|
|
L->is_commentary = comment_mode;
|
|
L->category = COMMENT_BODY_LCAT; /* until set otherwise down below */
|
|
L->owning_paragraph = current_paragraph;
|
|
|
|
if (L->source.line_count == 0)
|
|
{
|
|
#line 165 "inweb/Chapter 2/The Parser.w"
|
|
if (Str__eq_wide_string(L->text, L"Chapter Heading")) {
|
|
comment_mode = TRUE;
|
|
L->is_commentary = TRUE;
|
|
L->category = CHAPTER_HEADING_LCAT;
|
|
}
|
|
|
|
}
|
|
#line 145 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
if (L->source.line_count <= 1)
|
|
{
|
|
#line 175 "inweb/Chapter 2/The Parser.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L"%[(%C+)%] (%C+/%C+): (%c+).")) {
|
|
S->sect_namespace = Str__duplicate(mr.exp[0]);
|
|
S->sect_range = Str__duplicate(mr.exp[1]);
|
|
S->md->sect_title = Str__duplicate(mr.exp[2]);
|
|
L->text_operand = Str__duplicate(mr.exp[2]);
|
|
L->category = SECTION_HEADING_LCAT;
|
|
} else if (Regexp__match(&mr, L->text, L"(%C+/%C+): (%c+).")) {
|
|
S->sect_range = Str__duplicate(mr.exp[0]);
|
|
S->md->sect_title = Str__duplicate(mr.exp[1]);
|
|
L->text_operand = Str__duplicate(mr.exp[1]);
|
|
L->category = SECTION_HEADING_LCAT;
|
|
} else if (Regexp__match(&mr, L->text, L"%[(%C+::)%] (%c+).")) {
|
|
S->sect_namespace = Str__duplicate(mr.exp[0]);
|
|
S->md->sect_title = Str__duplicate(mr.exp[1]);
|
|
|
|
{
|
|
#line 204 "inweb/Chapter 2/The Parser.w"
|
|
if (Str__len(S->sect_range) == 0) {
|
|
if (sequential) {
|
|
WRITE_TO(S->sect_range, "%S/", C->md->ch_range);
|
|
WRITE_TO(S->sect_range, "s%d", section_counter);
|
|
} else {
|
|
text_stream *from = S->md->sect_title;
|
|
int letters_from_each_word = 5;
|
|
do {
|
|
Str__clear(S->sect_range);
|
|
WRITE_TO(S->sect_range, "%S/", C->md->ch_range);
|
|
|
|
{
|
|
#line 226 "inweb/Chapter 2/The Parser.w"
|
|
int sn = 0, sw = Str__len(S->sect_range);
|
|
if (Str__get_at(from, sn) == FOLDER_SEPARATOR) sn++;
|
|
int letters_from_current_word = 0;
|
|
while ((Str__get_at(from, sn)) && (Str__get_at(from, sn) != '.')) {
|
|
if (Str__get_at(from, sn) == ' ') letters_from_current_word = 0;
|
|
else {
|
|
if (letters_from_current_word < letters_from_each_word) {
|
|
if (Str__get_at(from, sn) != '-') {
|
|
int l = tolower(Str__get_at(from, sn));
|
|
if ((letters_from_current_word == 0) ||
|
|
((l != 'a') && (l != 'e') && (l != 'i') && (l != 'o') && (l != 'u'))) {
|
|
Str__put_at(S->sect_range, sw++, l); Str__put_at(S->sect_range, sw, 0);
|
|
letters_from_current_word++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sn++;
|
|
}
|
|
|
|
}
|
|
#line 214 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
if (--letters_from_each_word == 0) break;
|
|
} while (Str__len(S->sect_range) > 5);
|
|
|
|
|
|
{
|
|
#line 249 "inweb/Chapter 2/The Parser.w"
|
|
TEMPORARY_TEXT(original_range);
|
|
Str__copy(original_range, S->sect_range);
|
|
int disnum = 0, collision = FALSE;
|
|
do {
|
|
if (disnum++ > 0) {
|
|
int ldn = 4;
|
|
if (disnum >= 1000) ldn = 3;
|
|
else if (disnum >= 100) ldn = 2;
|
|
else if (disnum >= 10) ldn = 1;
|
|
else ldn = 0;
|
|
Str__clear(S->sect_range);
|
|
WRITE_TO(S->sect_range, "%S", original_range);
|
|
Str__truncate(S->sect_range, Str__len(S->sect_range) - ldn);
|
|
WRITE_TO(S->sect_range, "%d", disnum);
|
|
}
|
|
collision = FALSE;
|
|
chapter *C;
|
|
section *S2;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
LOOP_OVER_LINKED_LIST(S2, section, C->sections)
|
|
if ((S2 != S) && (Str__eq(S2->sect_range, S->sect_range))) {
|
|
collision = TRUE; break;
|
|
}
|
|
} while (collision);
|
|
DISCARD_TEXT(original_range);
|
|
|
|
}
|
|
#line 218 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 190 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
L->text_operand = Str__duplicate(mr.exp[1]);
|
|
L->category = SECTION_HEADING_LCAT;
|
|
} else if (Regexp__match(&mr, L->text, L"(%c+).")) {
|
|
S->md->sect_title = Str__duplicate(mr.exp[0]);
|
|
|
|
{
|
|
#line 204 "inweb/Chapter 2/The Parser.w"
|
|
if (Str__len(S->sect_range) == 0) {
|
|
if (sequential) {
|
|
WRITE_TO(S->sect_range, "%S/", C->md->ch_range);
|
|
WRITE_TO(S->sect_range, "s%d", section_counter);
|
|
} else {
|
|
text_stream *from = S->md->sect_title;
|
|
int letters_from_each_word = 5;
|
|
do {
|
|
Str__clear(S->sect_range);
|
|
WRITE_TO(S->sect_range, "%S/", C->md->ch_range);
|
|
|
|
{
|
|
#line 226 "inweb/Chapter 2/The Parser.w"
|
|
int sn = 0, sw = Str__len(S->sect_range);
|
|
if (Str__get_at(from, sn) == FOLDER_SEPARATOR) sn++;
|
|
int letters_from_current_word = 0;
|
|
while ((Str__get_at(from, sn)) && (Str__get_at(from, sn) != '.')) {
|
|
if (Str__get_at(from, sn) == ' ') letters_from_current_word = 0;
|
|
else {
|
|
if (letters_from_current_word < letters_from_each_word) {
|
|
if (Str__get_at(from, sn) != '-') {
|
|
int l = tolower(Str__get_at(from, sn));
|
|
if ((letters_from_current_word == 0) ||
|
|
((l != 'a') && (l != 'e') && (l != 'i') && (l != 'o') && (l != 'u'))) {
|
|
Str__put_at(S->sect_range, sw++, l); Str__put_at(S->sect_range, sw, 0);
|
|
letters_from_current_word++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sn++;
|
|
}
|
|
|
|
}
|
|
#line 214 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
if (--letters_from_each_word == 0) break;
|
|
} while (Str__len(S->sect_range) > 5);
|
|
|
|
|
|
{
|
|
#line 249 "inweb/Chapter 2/The Parser.w"
|
|
TEMPORARY_TEXT(original_range);
|
|
Str__copy(original_range, S->sect_range);
|
|
int disnum = 0, collision = FALSE;
|
|
do {
|
|
if (disnum++ > 0) {
|
|
int ldn = 4;
|
|
if (disnum >= 1000) ldn = 3;
|
|
else if (disnum >= 100) ldn = 2;
|
|
else if (disnum >= 10) ldn = 1;
|
|
else ldn = 0;
|
|
Str__clear(S->sect_range);
|
|
WRITE_TO(S->sect_range, "%S", original_range);
|
|
Str__truncate(S->sect_range, Str__len(S->sect_range) - ldn);
|
|
WRITE_TO(S->sect_range, "%d", disnum);
|
|
}
|
|
collision = FALSE;
|
|
chapter *C;
|
|
section *S2;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
LOOP_OVER_LINKED_LIST(S2, section, C->sections)
|
|
if ((S2 != S) && (Str__eq(S2->sect_range, S->sect_range))) {
|
|
collision = TRUE; break;
|
|
}
|
|
} while (collision);
|
|
DISCARD_TEXT(original_range);
|
|
|
|
}
|
|
#line 218 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 195 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
L->text_operand = Str__duplicate(mr.exp[0]);
|
|
L->category = SECTION_HEADING_LCAT;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 146 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
{
|
|
#line 280 "inweb/Chapter 2/The Parser.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L"%[%[(%c+)%]%]")) {
|
|
TEMPORARY_TEXT(full_command);
|
|
TEMPORARY_TEXT(command_text);
|
|
Str__copy(full_command, mr.exp[0]);
|
|
Str__copy(command_text, mr.exp[0]);
|
|
L->category = COMMAND_LCAT;
|
|
if (Regexp__match(&mr, command_text, L"(%c+?): *(%c+)")) {
|
|
Str__copy(command_text, mr.exp[0]);
|
|
L->text_operand = Str__duplicate(mr.exp[1]);
|
|
}
|
|
if (Str__eq_wide_string(command_text, L"Page Break")) {
|
|
if (S->md->using_syntax > V1_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "[[Page Break]]", V1_SYNTAX);
|
|
L->command_code = PAGEBREAK_CMD;
|
|
} else if (Str__eq_wide_string(command_text, L"Grammar Index"))
|
|
L->command_code = GRAMMAR_INDEX_CMD;
|
|
else if (Str__eq_wide_string(command_text, L"Tag")) {
|
|
if (S->md->using_syntax > V1_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "[[Tag...]]", V1_SYNTAX);
|
|
Tags__add_by_name(L->owning_paragraph, L->text_operand);
|
|
L->command_code = TAG_CMD;
|
|
} else if (Str__eq_wide_string(command_text, L"Figure")) {
|
|
if (S->md->using_syntax > V1_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "[[Figure...]]", V1_SYNTAX);
|
|
Tags__add_by_name(L->owning_paragraph, TL_IS_113);
|
|
L->command_code = FIGURE_CMD;
|
|
} else {
|
|
if (S->md->using_syntax >= V2_SYNTAX) {
|
|
Tags__add_by_name(L->owning_paragraph, TL_IS_114);
|
|
L->command_code = FIGURE_CMD;
|
|
Str__copy(L->text_operand, full_command);
|
|
} else {
|
|
Main__error_in_web(TL_IS_115, L);
|
|
}
|
|
}
|
|
L->is_commentary = TRUE;
|
|
DISCARD_TEXT(command_text);
|
|
DISCARD_TEXT(full_command);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 147 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
{
|
|
#line 326 "inweb/Chapter 2/The Parser.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if ((Str__get_first_char(L->text) == '@') && (Str__get_at(L->text, 1) == '<') &&
|
|
(Regexp__match(&mr, L->text, L"%c<(%c+)@> *= *"))) {
|
|
TEMPORARY_TEXT(para_macro_name);
|
|
Str__copy(para_macro_name, mr.exp[0]);
|
|
L->category = MACRO_DEFINITION_LCAT;
|
|
if (current_paragraph == NULL)
|
|
Main__error_in_web(TL_IS_116, L);
|
|
else Macros__create(S, current_paragraph, L, para_macro_name);
|
|
comment_mode = FALSE;
|
|
L->is_commentary = FALSE;
|
|
code_lcat_for_body = CODE_BODY_LCAT; /* code follows on subsequent lines */
|
|
code_pl_for_body = NULL;
|
|
DISCARD_TEXT(para_macro_name);
|
|
continue;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 148 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
if (Str__get_first_char(L->text) == '=') {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "column-1 '=' as code divider", V2_SYNTAX);
|
|
|
|
{
|
|
#line 366 "inweb/Chapter 2/The Parser.w"
|
|
L->category = BEGIN_CODE_LCAT;
|
|
code_lcat_for_body = CODE_BODY_LCAT;
|
|
code_pl_for_body = NULL;
|
|
comment_mode = FALSE;
|
|
match_results mr = Regexp__create_mr();
|
|
match_results mr2 = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L"= *(%c+) *")) {
|
|
if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_117))) {
|
|
current_paragraph->placed_very_early = TRUE;
|
|
} else if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_118))) {
|
|
current_paragraph->placed_early = TRUE;
|
|
} else if ((current_paragraph) && (Str__eq(mr.exp[0], TL_IS_119))) {
|
|
code_lcat_for_body = TEXT_EXTRACT_LCAT;
|
|
code_pl_for_body = NULL;
|
|
} else if ((current_paragraph) && (Regexp__match(&mr2, mr.exp[0], L"%(sample (%c+) code%)"))) {
|
|
code_lcat_for_body = TEXT_EXTRACT_LCAT;
|
|
code_pl_for_body = Languages__find_by_name(mr2.exp[0]);
|
|
} else {
|
|
Main__error_in_web(TL_IS_120, L);
|
|
}
|
|
} else if (Regexp__match(&mr, L->text, L"= *%C%c*")) {
|
|
Main__error_in_web(TL_IS_121, L);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
Regexp__dispose_of(&mr2);
|
|
continue;
|
|
|
|
}
|
|
#line 152 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
}
|
|
if ((Str__get_first_char(L->text) == '@') &&
|
|
(Str__get_at(L->text, 1) != '<') &&
|
|
(L->category != MACRO_DEFINITION_LCAT))
|
|
|
|
{
|
|
#line 348 "inweb/Chapter 2/The Parser.w"
|
|
TEMPORARY_TEXT(command_text);
|
|
Str__copy(command_text, L->text);
|
|
Str__delete_first_character(command_text); /* i.e., strip the at-sign from the front */
|
|
TEMPORARY_TEXT(remainder);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, command_text, L"(%C*) *(%c*?)")) {
|
|
Str__copy(command_text, mr.exp[0]);
|
|
Str__copy(remainder, mr.exp[1]);
|
|
}
|
|
|
|
{
|
|
#line 400 "inweb/Chapter 2/The Parser.w"
|
|
if (Str__eq_wide_string(command_text, L"Purpose:"))
|
|
{
|
|
#line 447 "inweb/Chapter 2/The Parser.w"
|
|
if (before_bar == FALSE) Main__error_in_web(TL_IS_123, L);
|
|
if (S->md->using_syntax >= V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@Purpose'", V1_SYNTAX);
|
|
L->category = PURPOSE_LCAT;
|
|
L->is_commentary = TRUE;
|
|
L->text_operand = Str__duplicate(remainder);
|
|
S->sect_purpose = Parser__extract_purpose(remainder, L->next_line, L->owning_section, &L);
|
|
|
|
}
|
|
#line 400 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else if (Str__eq_wide_string(command_text, L"Interface:"))
|
|
{
|
|
#line 456 "inweb/Chapter 2/The Parser.w"
|
|
if (S->md->using_syntax >= V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@Interface'", V1_SYNTAX);
|
|
if (before_bar == FALSE) Main__error_in_web(TL_IS_124, L);
|
|
L->category = INTERFACE_LCAT;
|
|
L->is_commentary = TRUE;
|
|
source_line *XL = L->next_line;
|
|
while ((XL) && (XL->next_line) && (XL->owning_section == L->owning_section)) {
|
|
if (Str__get_first_char(XL->text) == '@') break;
|
|
XL->category = INTERFACE_BODY_LCAT;
|
|
L = XL;
|
|
XL = XL->next_line;
|
|
}
|
|
|
|
}
|
|
#line 401 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else if (Str__eq_wide_string(command_text, L"Definitions:"))
|
|
{
|
|
#line 470 "inweb/Chapter 2/The Parser.w"
|
|
if (S->md->using_syntax >= V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@Definitions' headings", V1_SYNTAX);
|
|
if (before_bar == FALSE) Main__error_in_web(TL_IS_125, L);
|
|
L->category = DEFINITIONS_LCAT;
|
|
L->is_commentary = TRUE;
|
|
before_bar = TRUE;
|
|
next_par_number = 1;
|
|
|
|
}
|
|
#line 402 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else if (Regexp__match(&mr, command_text, L"----+"))
|
|
{
|
|
#line 482 "inweb/Chapter 2/The Parser.w"
|
|
if (S->md->using_syntax >= V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "the bar '----...'", V1_SYNTAX);
|
|
if (before_bar == FALSE) Main__error_in_web(TL_IS_126, L);
|
|
L->category = BAR_LCAT;
|
|
L->is_commentary = TRUE;
|
|
comment_mode = TRUE;
|
|
S->barred = TRUE;
|
|
before_bar = FALSE;
|
|
next_par_number = 1;
|
|
|
|
}
|
|
#line 403 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else if ((Str__eq_wide_string(command_text, L"c")) ||
|
|
(Str__eq_wide_string(command_text, L"x")) ||
|
|
((S->md->using_syntax == V1_SYNTAX) && (Str__eq_wide_string(command_text, L"e"))))
|
|
|
|
{
|
|
#line 499 "inweb/Chapter 2/The Parser.w"
|
|
if (S->md->using_syntax > V1_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@c' and '@x'", V1_SYNTAX);
|
|
L->category = BEGIN_CODE_LCAT;
|
|
if ((Str__eq_wide_string(command_text, L"e")) && (current_paragraph))
|
|
current_paragraph->placed_early = TRUE;
|
|
if (Str__eq_wide_string(command_text, L"x")) code_lcat_for_body = TEXT_EXTRACT_LCAT;
|
|
else code_lcat_for_body = CODE_BODY_LCAT;
|
|
code_pl_for_body = NULL;
|
|
comment_mode = FALSE;
|
|
|
|
}
|
|
#line 407 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else if (Str__eq_wide_string(command_text, L"d"))
|
|
{
|
|
#line 513 "inweb/Chapter 2/The Parser.w"
|
|
L->category = BEGIN_DEFINITION_LCAT;
|
|
code_lcat_for_body = CONT_DEFINITION_LCAT;
|
|
code_pl_for_body = NULL;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
|
|
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
|
|
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
|
|
} else {
|
|
L->text_operand = Str__duplicate(remainder); /* name of term defined */
|
|
L->text_operand2 = Str__new(); /* no value given */
|
|
}
|
|
Analyser__mark_reserved_word_for_section(S, L->text_operand, CONSTANT_COLOUR);
|
|
comment_mode = FALSE;
|
|
L->is_commentary = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 408 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else if (Str__eq_wide_string(command_text, L"define")) {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@define' for definitions (use '@d' instead)", V2_SYNTAX);
|
|
|
|
{
|
|
#line 513 "inweb/Chapter 2/The Parser.w"
|
|
L->category = BEGIN_DEFINITION_LCAT;
|
|
code_lcat_for_body = CONT_DEFINITION_LCAT;
|
|
code_pl_for_body = NULL;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
|
|
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
|
|
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
|
|
} else {
|
|
L->text_operand = Str__duplicate(remainder); /* name of term defined */
|
|
L->text_operand2 = Str__new(); /* no value given */
|
|
}
|
|
Analyser__mark_reserved_word_for_section(S, L->text_operand, CONSTANT_COLOUR);
|
|
comment_mode = FALSE;
|
|
L->is_commentary = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 412 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
} else if (Str__eq_wide_string(command_text, L"default")) {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@default' for definitions", V2_SYNTAX);
|
|
L->default_defn = TRUE;
|
|
|
|
{
|
|
#line 513 "inweb/Chapter 2/The Parser.w"
|
|
L->category = BEGIN_DEFINITION_LCAT;
|
|
code_lcat_for_body = CONT_DEFINITION_LCAT;
|
|
code_pl_for_body = NULL;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, remainder, L"(%C+) (%c+)")) {
|
|
L->text_operand = Str__duplicate(mr.exp[0]); /* name of term defined */
|
|
L->text_operand2 = Str__duplicate(mr.exp[1]); /* Value */
|
|
} else {
|
|
L->text_operand = Str__duplicate(remainder); /* name of term defined */
|
|
L->text_operand2 = Str__new(); /* no value given */
|
|
}
|
|
Analyser__mark_reserved_word_for_section(S, L->text_operand, CONSTANT_COLOUR);
|
|
comment_mode = FALSE;
|
|
L->is_commentary = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 417 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
} else if (Str__eq_wide_string(command_text, L"enum"))
|
|
{
|
|
#line 533 "inweb/Chapter 2/The Parser.w"
|
|
L->category = BEGIN_DEFINITION_LCAT;
|
|
text_stream *from = NULL;
|
|
match_results mr = Regexp__create_mr();
|
|
L->text_operand = Str__duplicate(remainder); /* name of term defined */
|
|
TEMPORARY_TEXT(before);
|
|
TEMPORARY_TEXT(after);
|
|
if (LanguageMethods__parse_comment(S->sect_language, L->text_operand,
|
|
before, after)) {
|
|
Str__copy(L->text_operand, before);
|
|
}
|
|
DISCARD_TEXT(before);
|
|
DISCARD_TEXT(after);
|
|
Str__trim_white_space(L->text_operand);
|
|
if (Regexp__match(&mr, L->text_operand, L"(%C+) from (%c+)")) {
|
|
from = mr.exp[1];
|
|
Str__copy(L->text_operand, mr.exp[0]);
|
|
} else if (Regexp__match(&mr, L->text_operand, L"(%C+) (%c+)")) {
|
|
Main__error_in_web(TL_IS_127, L);
|
|
}
|
|
L->text_operand2 = Str__new();
|
|
if (inweb_mode == TANGLE_MODE)
|
|
Enumerations__define(L->text_operand2, L->text_operand, from, L);
|
|
Analyser__mark_reserved_word_for_section(S, L->text_operand, CONSTANT_COLOUR);
|
|
comment_mode = FALSE;
|
|
L->is_commentary = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 418 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else if ((Str__eq_wide_string(command_text, L"e")) && (S->md->using_syntax >= V2_SYNTAX))
|
|
|
|
{
|
|
#line 533 "inweb/Chapter 2/The Parser.w"
|
|
L->category = BEGIN_DEFINITION_LCAT;
|
|
text_stream *from = NULL;
|
|
match_results mr = Regexp__create_mr();
|
|
L->text_operand = Str__duplicate(remainder); /* name of term defined */
|
|
TEMPORARY_TEXT(before);
|
|
TEMPORARY_TEXT(after);
|
|
if (LanguageMethods__parse_comment(S->sect_language, L->text_operand,
|
|
before, after)) {
|
|
Str__copy(L->text_operand, before);
|
|
}
|
|
DISCARD_TEXT(before);
|
|
DISCARD_TEXT(after);
|
|
Str__trim_white_space(L->text_operand);
|
|
if (Regexp__match(&mr, L->text_operand, L"(%C+) from (%c+)")) {
|
|
from = mr.exp[1];
|
|
Str__copy(L->text_operand, mr.exp[0]);
|
|
} else if (Regexp__match(&mr, L->text_operand, L"(%C+) (%c+)")) {
|
|
Main__error_in_web(TL_IS_127, L);
|
|
}
|
|
L->text_operand2 = Str__new();
|
|
if (inweb_mode == TANGLE_MODE)
|
|
Enumerations__define(L->text_operand2, L->text_operand, from, L);
|
|
Analyser__mark_reserved_word_for_section(S, L->text_operand, CONSTANT_COLOUR);
|
|
comment_mode = FALSE;
|
|
L->is_commentary = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 420 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else {
|
|
int weight = -1, new_page = FALSE;
|
|
if (Str__eq_wide_string(command_text, L"")) weight = ORDINARY_WEIGHT;
|
|
if ((Str__eq_wide_string(command_text, L"h")) || (Str__eq_wide_string(command_text, L"heading"))) {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@h' or '@heading' for headings (use '@p' instead)", V2_SYNTAX);
|
|
weight = SUBHEADING_WEIGHT;
|
|
}
|
|
if (Str__eq_wide_string(command_text, L"p")) {
|
|
if (S->md->using_syntax > V1_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@p' for headings (use '@h' instead)", V1_SYNTAX);
|
|
weight = SUBHEADING_WEIGHT;
|
|
}
|
|
if (Str__eq_wide_string(command_text, L"pp")) {
|
|
if (S->md->using_syntax > V1_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "'@pp' for super-headings", V1_SYNTAX);
|
|
weight = SUBHEADING_WEIGHT; new_page = TRUE;
|
|
}
|
|
if (weight >= 0)
|
|
{
|
|
#line 585 "inweb/Chapter 2/The Parser.w"
|
|
comment_mode = TRUE;
|
|
L->is_commentary = TRUE;
|
|
L->category = PARAGRAPH_START_LCAT;
|
|
if (weight == SUBHEADING_WEIGHT) L->category = HEADING_START_LCAT;
|
|
L->text_operand = Str__new(); /* title */
|
|
match_results mr = Regexp__create_mr();
|
|
if ((weight == SUBHEADING_WEIGHT) && (Regexp__match(&mr, remainder, L"(%c+). (%c+)"))) {
|
|
L->text_operand = Str__duplicate(mr.exp[0]);
|
|
L->text_operand2 = Str__duplicate(mr.exp[1]);
|
|
} else if ((weight == SUBHEADING_WEIGHT) && (Regexp__match(&mr, remainder, L"(%c+). *"))) {
|
|
L->text_operand = Str__duplicate(mr.exp[0]);
|
|
L->text_operand2 = Str__new();
|
|
} else {
|
|
L->text_operand = Str__new();
|
|
L->text_operand2 = Str__duplicate(remainder);
|
|
}
|
|
|
|
{
|
|
#line 632 "inweb/Chapter 2/The Parser.w"
|
|
paragraph *P = CREATE(paragraph);
|
|
if (S->md->using_syntax > V1_SYNTAX) {
|
|
P->above_bar = FALSE;
|
|
P->placed_early = FALSE;
|
|
P->placed_very_early = FALSE;
|
|
} else {
|
|
P->above_bar = before_bar;
|
|
P->placed_early = before_bar;
|
|
P->placed_very_early = FALSE;
|
|
}
|
|
if ((S->md->using_syntax == V1_SYNTAX) && (before_bar))
|
|
P->ornament = Str__duplicate(TL_IS_128);
|
|
else
|
|
P->ornament = Str__duplicate(TL_IS_129);
|
|
WRITE_TO(P->paragraph_number, "%d", next_par_number++);
|
|
P->parent_paragraph = NULL;
|
|
P->next_child_number = 1;
|
|
P->starts_on_new_page = FALSE;
|
|
P->weight = weight;
|
|
P->first_line_in_paragraph = L;
|
|
P->defines_macro = NULL;
|
|
P->functions = NEW_LINKED_LIST(function);
|
|
P->structures = NEW_LINKED_LIST(c_structure);
|
|
P->taggings = NEW_LINKED_LIST(paragraph_tagging);
|
|
|
|
P->under_section = S;
|
|
S->sect_paragraphs++;
|
|
ADD_TO_LINKED_LIST(P, paragraph, S->paragraphs);
|
|
|
|
current_paragraph = P;
|
|
|
|
}
|
|
#line 601 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
L->owning_paragraph = current_paragraph;
|
|
W->no_paragraphs++;
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 439 "inweb/Chapter 2/The Parser.w"
|
|
|
|
else Main__error_in_web(TL_IS_122, L);
|
|
}
|
|
|
|
}
|
|
#line 357 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
DISCARD_TEXT(remainder);
|
|
DISCARD_TEXT(command_text);
|
|
Regexp__dispose_of(&mr);
|
|
continue;
|
|
|
|
}
|
|
#line 157 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
if (comment_mode)
|
|
{
|
|
#line 666 "inweb/Chapter 2/The Parser.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L">> (%c+)")) {
|
|
L->category = SOURCE_DISPLAY_LCAT;
|
|
L->text_operand = Str__duplicate(mr.exp[0]);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 158 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
if (comment_mode == FALSE)
|
|
{
|
|
#line 678 "inweb/Chapter 2/The Parser.w"
|
|
if ((L->category != BEGIN_DEFINITION_LCAT) && (L->category != COMMAND_LCAT)) {
|
|
L->category = code_lcat_for_body;
|
|
if (L->category == TEXT_EXTRACT_LCAT) L->colour_as = code_pl_for_body;
|
|
}
|
|
|
|
if ((L->category == CONT_DEFINITION_LCAT) && (Regexp__string_is_white_space(L->text))) {
|
|
L->category = COMMENT_BODY_LCAT;
|
|
L->is_commentary = TRUE;
|
|
code_lcat_for_body = COMMENT_BODY_LCAT;
|
|
comment_mode = TRUE;
|
|
}
|
|
|
|
LanguageMethods__subcategorise_line(S->sect_language, L);
|
|
|
|
}
|
|
#line 159 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
}
|
|
#line 47 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
}
|
|
DISCARD_TEXT(tag_list);
|
|
|
|
{
|
|
#line 97 "inweb/Chapter 2/The Parser.w"
|
|
if (S->md->using_syntax >= V2_SYNTAX) {
|
|
source_line *L = S->first_line;
|
|
if ((L) && (L->category == CHAPTER_HEADING_LCAT)) L = L->next_line;
|
|
S->sect_purpose = Parser__extract_purpose(TL_IS_110, L?L->next_line: NULL, S, NULL);
|
|
if (Str__len(S->sect_purpose) > 0) L->next_line->category = PURPOSE_LCAT;
|
|
}
|
|
|
|
}
|
|
#line 50 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
{
|
|
#line 87 "inweb/Chapter 2/The Parser.w"
|
|
paragraph *P;
|
|
if (S->tag_with)
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
Tags__add_to_paragraph(P, S->tag_with, NULL);
|
|
|
|
}
|
|
#line 51 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
|
|
}
|
|
#line 23 "inweb/Chapter 2/The Parser.w"
|
|
;
|
|
section_counter++;
|
|
}
|
|
}
|
|
LanguageMethods__further_parsing(W, W->main_language);
|
|
}
|
|
|
|
#line 630 "inweb/Chapter 2/The Parser.w"
|
|
|
|
#line 697 "inweb/Chapter 2/The Parser.w"
|
|
text_stream *Parser__extract_purpose(text_stream *prologue, source_line *XL, section *S, source_line **adjust) {
|
|
text_stream *P = Str__duplicate(prologue);
|
|
while ((XL) && (XL->next_line) && (XL->owning_section == S) &&
|
|
(((adjust) && (isalnum(Str__get_first_char(XL->text)))) ||
|
|
((!adjust) && (XL->category == COMMENT_BODY_LCAT)))) {
|
|
WRITE_TO(P, " %S", XL->text);
|
|
XL->category = PURPOSE_BODY_LCAT;
|
|
XL->is_commentary = TRUE;
|
|
if (adjust) *adjust = XL;
|
|
XL = XL->next_line;
|
|
}
|
|
Str__trim_white_space(P);
|
|
return P;
|
|
}
|
|
|
|
#line 718 "inweb/Chapter 2/The Parser.w"
|
|
void Parser__wrong_version(int using, source_line *L, char *feature, int need) {
|
|
TEMPORARY_TEXT(warning);
|
|
WRITE_TO(warning, "%s is a feature available only in version %d syntax (you're using version %d)",
|
|
feature, need, using);
|
|
Main__error_in_web(warning, L);
|
|
DISCARD_TEXT(warning);
|
|
}
|
|
|
|
#line 15 "inweb/Chapter 2/Paragraph Macros.w"
|
|
|
|
#line 20 "inweb/Chapter 2/Paragraph Macros.w"
|
|
para_macro *Macros__create(section *S, paragraph *P, source_line *L, text_stream *name) {
|
|
para_macro *pmac = CREATE(para_macro);
|
|
pmac->macro_name = Str__duplicate(name);
|
|
pmac->defining_paragraph = P;
|
|
P->defines_macro = pmac;
|
|
pmac->defn_start = L->next_line;
|
|
pmac->macro_usages = NEW_LINKED_LIST(macro_usage);
|
|
ADD_TO_LINKED_LIST(pmac, para_macro, S->macros);
|
|
return pmac;
|
|
}
|
|
|
|
#line 38 "inweb/Chapter 2/Paragraph Macros.w"
|
|
para_macro *Macros__find_by_name(text_stream *name, section *scope) {
|
|
para_macro *pmac;
|
|
LOOP_OVER_LINKED_LIST(pmac, para_macro, scope->macros)
|
|
if (Str__eq(name, pmac->macro_name))
|
|
return pmac;
|
|
return NULL;
|
|
}
|
|
|
|
#line 16 "inweb/Chapter 2/Tags.w"
|
|
|
|
#line 22 "inweb/Chapter 2/Tags.w"
|
|
theme_tag *Tags__find_by_name(text_stream *name, int creating_if_necessary) {
|
|
theme_tag *tag;
|
|
LOOP_OVER(tag, theme_tag)
|
|
if (Str__eq(name, tag->tag_name))
|
|
return tag;
|
|
if (creating_if_necessary) {
|
|
tag = CREATE(theme_tag);
|
|
tag->tag_name = Str__duplicate(name);
|
|
tag->ifdef_positive = NOT_APPLICABLE;
|
|
tag->ifdef_symbol = Str__new();
|
|
if (Str__prefix_eq(name, TL_IS_130, 6)) {
|
|
Str__substr(tag->ifdef_symbol, Str__at(name, 6), Str__end(name));
|
|
tag->ifdef_positive = TRUE;
|
|
} else if (Str__prefix_eq(name, TL_IS_131, 7)) {
|
|
Str__substr(tag->ifdef_symbol, Str__at(name, 7), Str__end(name));
|
|
tag->ifdef_positive = FALSE;
|
|
}
|
|
LanguageMethods__new_tag_declared(tag);
|
|
return tag;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#line 55 "inweb/Chapter 2/Tags.w"
|
|
|
|
void Tags__add_to_paragraph(paragraph *P, theme_tag *tag, text_stream *caption) {
|
|
if (P) {
|
|
paragraph_tagging *pt = CREATE(paragraph_tagging);
|
|
pt->the_tag = tag;
|
|
if (caption) pt->caption = Str__duplicate(caption);
|
|
else pt->caption = Str__new();
|
|
ADD_TO_LINKED_LIST(pt, paragraph_tagging, P->taggings);
|
|
}
|
|
}
|
|
|
|
#line 71 "inweb/Chapter 2/Tags.w"
|
|
theme_tag *Tags__add_by_name(paragraph *P, text_stream *text) {
|
|
if (Str__len(text) == 0) internal_error("empty tag name");
|
|
TEMPORARY_TEXT(name); Str__copy(name, text);
|
|
TEMPORARY_TEXT(caption);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, name, L"(%c+?): (%c+)")) {
|
|
Str__copy(name, mr.exp[0]);
|
|
Str__copy(caption, mr.exp[1]);
|
|
}
|
|
theme_tag *tag = Tags__find_by_name(name, TRUE);
|
|
if (P) Tags__add_to_paragraph(P, tag, caption);
|
|
DISCARD_TEXT(name);
|
|
DISCARD_TEXT(caption);
|
|
Regexp__dispose_of(&mr);
|
|
return tag;
|
|
}
|
|
|
|
#line 91 "inweb/Chapter 2/Tags.w"
|
|
text_stream *Tags__retrieve_caption(paragraph *P, theme_tag *tag) {
|
|
if (tag == NULL) return NULL;
|
|
if (P) {
|
|
paragraph_tagging *pt;
|
|
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
|
|
if (tag == pt->the_tag)
|
|
return pt->caption;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#line 107 "inweb/Chapter 2/Tags.w"
|
|
int Tags__tagged_with(paragraph *P, theme_tag *tag) {
|
|
if (tag == NULL) return TRUE;
|
|
if (P) {
|
|
paragraph_tagging *pt;
|
|
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
|
|
if (tag == pt->the_tag)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#line 119 "inweb/Chapter 2/Tags.w"
|
|
void Tags__open_ifdefs(OUTPUT_STREAM, paragraph *P) {
|
|
paragraph_tagging *pt;
|
|
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
|
|
if (Str__len(pt->the_tag->ifdef_symbol) > 0)
|
|
LanguageMethods__open_ifdef(OUT,
|
|
P->under_section->sect_language, pt->the_tag->ifdef_symbol, pt->the_tag->ifdef_positive);
|
|
}
|
|
|
|
void Tags__close_ifdefs(OUTPUT_STREAM, paragraph *P) {
|
|
paragraph_tagging *pt;
|
|
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
|
|
if (Str__len(pt->the_tag->ifdef_symbol) > 0)
|
|
LanguageMethods__close_ifdef(OUT,
|
|
P->under_section->sect_language, pt->the_tag->ifdef_symbol, pt->the_tag->ifdef_positive);
|
|
}
|
|
|
|
void Tags__show_endnote_on_ifdefs(OUTPUT_STREAM, weave_target *wv, paragraph *P) {
|
|
int d = 0, sense = TRUE;
|
|
|
|
{
|
|
#line 147 "inweb/Chapter 2/Tags.w"
|
|
int c = 0;
|
|
paragraph_tagging *pt;
|
|
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
|
|
if (pt->the_tag->ifdef_positive == sense)
|
|
if (Str__len(pt->the_tag->ifdef_symbol) > 0) {
|
|
if (c++ == 0) {
|
|
if (d++ == 0) {
|
|
Formats__endnote(OUT, wv, 1);
|
|
Formats__text(OUT, wv, TL_IS_133);
|
|
} else {
|
|
Formats__text(OUT, wv, TL_IS_134);
|
|
}
|
|
} else {
|
|
Formats__text(OUT, wv, TL_IS_135);
|
|
}
|
|
Formats__text(OUT, wv, pt->the_tag->ifdef_symbol);
|
|
}
|
|
if (c > 0) {
|
|
if (c == 1) Formats__text(OUT, wv, TL_IS_136);
|
|
else Formats__text(OUT, wv, TL_IS_137);
|
|
if (sense) Formats__text(OUT, wv, TL_IS_138);
|
|
else Formats__text(OUT, wv, TL_IS_139);
|
|
}
|
|
|
|
}
|
|
#line 137 "inweb/Chapter 2/Tags.w"
|
|
;
|
|
sense = FALSE;
|
|
|
|
{
|
|
#line 147 "inweb/Chapter 2/Tags.w"
|
|
int c = 0;
|
|
paragraph_tagging *pt;
|
|
LOOP_OVER_LINKED_LIST(pt, paragraph_tagging, P->taggings)
|
|
if (pt->the_tag->ifdef_positive == sense)
|
|
if (Str__len(pt->the_tag->ifdef_symbol) > 0) {
|
|
if (c++ == 0) {
|
|
if (d++ == 0) {
|
|
Formats__endnote(OUT, wv, 1);
|
|
Formats__text(OUT, wv, TL_IS_133);
|
|
} else {
|
|
Formats__text(OUT, wv, TL_IS_134);
|
|
}
|
|
} else {
|
|
Formats__text(OUT, wv, TL_IS_135);
|
|
}
|
|
Formats__text(OUT, wv, pt->the_tag->ifdef_symbol);
|
|
}
|
|
if (c > 0) {
|
|
if (c == 1) Formats__text(OUT, wv, TL_IS_136);
|
|
else Formats__text(OUT, wv, TL_IS_137);
|
|
if (sense) Formats__text(OUT, wv, TL_IS_138);
|
|
else Formats__text(OUT, wv, TL_IS_139);
|
|
}
|
|
|
|
}
|
|
#line 139 "inweb/Chapter 2/Tags.w"
|
|
;
|
|
if (d > 0) {
|
|
Formats__text(OUT, wv, TL_IS_132);
|
|
Formats__endnote(OUT, wv, 2);
|
|
}
|
|
}
|
|
|
|
#line 22 "inweb/Chapter 2/Enumerated Constants.w"
|
|
|
|
#line 27 "inweb/Chapter 2/Enumerated Constants.w"
|
|
enumeration_set *Enumerations__find(text_stream *post) {
|
|
enumeration_set *es = NULL;
|
|
LOOP_OVER(es, enumeration_set)
|
|
if (Str__eq(post, es->postfix))
|
|
return es;
|
|
return NULL;
|
|
}
|
|
|
|
#line 40 "inweb/Chapter 2/Enumerated Constants.w"
|
|
void Enumerations__define(OUTPUT_STREAM, text_stream *symbol,
|
|
text_stream *from, source_line *L) {
|
|
TEMPORARY_TEXT(pf);
|
|
|
|
{
|
|
#line 54 "inweb/Chapter 2/Enumerated Constants.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, symbol, L"%c*_(%C+?)")) Str__copy(pf, mr.exp[0]);
|
|
else {
|
|
Main__error_in_web(TL_IS_140, L);
|
|
WRITE_TO(pf, "BOGUS");
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 43 "inweb/Chapter 2/Enumerated Constants.w"
|
|
;
|
|
enumeration_set *es = Enumerations__find(pf);
|
|
if (from == NULL)
|
|
{
|
|
#line 63 "inweb/Chapter 2/Enumerated Constants.w"
|
|
if (es) {
|
|
if (es->stub) WRITE("(%S+", es->stub);
|
|
WRITE("%d", es->next_free_value++);
|
|
if (es->stub) WRITE(")");
|
|
} else Main__error_in_web(TL_IS_141, L);
|
|
|
|
}
|
|
#line 45 "inweb/Chapter 2/Enumerated Constants.w"
|
|
|
|
else
|
|
{
|
|
#line 70 "inweb/Chapter 2/Enumerated Constants.w"
|
|
if (es) Main__error_in_web(TL_IS_142, L);
|
|
else {
|
|
es = CREATE(enumeration_set);
|
|
es->postfix = Str__duplicate(pf);
|
|
es->stub = NULL;
|
|
if ((Str__len(from) < 8) &&
|
|
((Regexp__match(NULL, from, L"%d+")) ||
|
|
(Regexp__match(NULL, from, L"-%d+")))) {
|
|
es->first_value = Str__atoi(from, 0);
|
|
es->next_free_value = es->first_value + 1;
|
|
} else {
|
|
es->stub = Str__duplicate(from);
|
|
es->first_value = 0;
|
|
es->next_free_value = 1;
|
|
}
|
|
}
|
|
if (es->stub) WRITE("(%S+", es->stub);
|
|
WRITE("%d", es->first_value);
|
|
if (es->stub) WRITE(")");
|
|
|
|
}
|
|
#line 46 "inweb/Chapter 2/Enumerated Constants.w"
|
|
;
|
|
DISCARD_TEXT(pf);
|
|
if (es) es->last_observed_at = L;
|
|
}
|
|
|
|
#line 95 "inweb/Chapter 2/Enumerated Constants.w"
|
|
void Enumerations__define_extents(OUTPUT_STREAM, tangle_target *target, programming_language *lang) {
|
|
enumeration_set *es;
|
|
LOOP_OVER(es, enumeration_set) {
|
|
TEMPORARY_TEXT(symbol);
|
|
TEMPORARY_TEXT(value);
|
|
WRITE_TO(symbol, "NO_DEFINED_%S_VALUES", es->postfix);
|
|
WRITE_TO(value, "%d", es->next_free_value - es->first_value);
|
|
LanguageMethods__start_definition(OUT, lang, symbol, value,
|
|
es->last_observed_at->owning_section, es->last_observed_at);
|
|
LanguageMethods__end_definition(OUT, lang,
|
|
es->last_observed_at->owning_section, es->last_observed_at);
|
|
DISCARD_TEXT(symbol);
|
|
DISCARD_TEXT(value);
|
|
}
|
|
}
|
|
|
|
#line 19 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
void Numbering__number_web(web *W) {
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters) {
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
|
|
|
|
{
|
|
#line 31 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
for (source_line *L = S->first_line; L; L = L->next_line) {
|
|
TEMPORARY_TEXT(p);
|
|
Str__copy(p, L->text);
|
|
int mlen, mpos;
|
|
while ((mpos = Regexp__find_expansion(p, '@', '<', '@', '>', &mlen)) != -1) {
|
|
TEMPORARY_TEXT(found_macro);
|
|
Str__substr(found_macro, Str__at(p, mpos+2), Str__at(p, mpos+mlen-2));
|
|
TEMPORARY_TEXT(original_p);
|
|
Str__copy(original_p, p);
|
|
Str__clear(p);
|
|
Str__substr(p, Str__at(original_p, mpos + mlen), Str__end(original_p));
|
|
DISCARD_TEXT(original_p);
|
|
para_macro *pmac = Macros__find_by_name(found_macro, S);
|
|
if (pmac)
|
|
{
|
|
#line 68 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
macro_usage *mu, *last = NULL;
|
|
LOOP_OVER_LINKED_LIST(mu, macro_usage, pmac->macro_usages) {
|
|
last = mu;
|
|
if (mu->used_in_paragraph == L->owning_paragraph)
|
|
break;
|
|
}
|
|
if (mu == NULL) {
|
|
mu = CREATE(macro_usage);
|
|
mu->used_in_paragraph = L->owning_paragraph;
|
|
mu->multiplicity = 0;
|
|
ADD_TO_LINKED_LIST(mu, macro_usage, pmac->macro_usages);
|
|
}
|
|
mu->multiplicity++;
|
|
|
|
}
|
|
#line 44 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
DISCARD_TEXT(found_macro);
|
|
}
|
|
DISCARD_TEXT(p);
|
|
}
|
|
|
|
}
|
|
#line 24 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
|
|
{
|
|
#line 88 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
|
|
{
|
|
#line 95 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
paragraph *P;
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
if (P->defines_macro) {
|
|
macro_usage *mu =
|
|
FIRST_IN_LINKED_LIST(macro_usage, P->defines_macro->macro_usages);
|
|
if (mu) P->parent_paragraph = mu->used_in_paragraph;
|
|
}
|
|
|
|
}
|
|
#line 88 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
|
|
{
|
|
#line 104 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
paragraph *P;
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
if (P->parent_paragraph == NULL)
|
|
for (linked_list_item *P2_item = P_item; P2_item; P2_item = NEXT_ITEM_IN_LINKED_LIST(P2_item, paragraph)) {
|
|
paragraph *P2 = CONTENT_IN_ITEM(P2_item, paragraph);
|
|
if (P2->parent_paragraph) {
|
|
if (P2->parent_paragraph->allocation_id < P->allocation_id)
|
|
P->parent_paragraph = P2->parent_paragraph;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 89 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
|
|
{
|
|
#line 117 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
paragraph *P;
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
P->paragraph_number = Str__new();
|
|
|
|
}
|
|
#line 90 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
|
|
{
|
|
#line 126 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
int top_level = 1;
|
|
paragraph *P;
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
if (P->parent_paragraph == NULL) {
|
|
WRITE_TO(P->paragraph_number, "%d", top_level++);
|
|
P->next_child_number = 1;
|
|
} else
|
|
Str__clear(P->paragraph_number);
|
|
|
|
}
|
|
#line 91 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
|
|
{
|
|
#line 136 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
paragraph *P;
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
Numbering__settle_paragraph_number(P);
|
|
|
|
}
|
|
#line 92 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
|
|
}
|
|
#line 25 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 66 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
|
|
#line 146 "inweb/Chapter 2/Paragraph Numbering.w"
|
|
void Numbering__settle_paragraph_number(paragraph *P) {
|
|
if (Str__len(P->paragraph_number) > 0) return;
|
|
WRITE_TO(P->paragraph_number, "X"); /* to prevent malformed sections hanging this */
|
|
if (P->parent_paragraph) Numbering__settle_paragraph_number(P->parent_paragraph);
|
|
Str__clear(P->paragraph_number);
|
|
WRITE_TO(P->paragraph_number, "%S.%d", P->parent_paragraph->paragraph_number,
|
|
P->parent_paragraph->next_child_number++);
|
|
P->next_child_number = 1;
|
|
}
|
|
|
|
#line 11 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__scan_line_categories(web *W, text_stream *range) {
|
|
PRINT("Scan of source lines for '%S'\n", range);
|
|
int count = 1;
|
|
chapter *C = Reader__get_chapter_for_range(W, range);
|
|
if (C) {
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)
|
|
for (source_line *L = S->first_line; L; L = L->next_line)
|
|
|
|
{
|
|
#line 35 "inweb/Chapter 3/The Analyser.w"
|
|
TEMPORARY_TEXT(C);
|
|
WRITE_TO(C, "%s", Lines__category_name(L->category));
|
|
while (Str__len(C) < 20) PUT_TO(C, '.');
|
|
PRINT("%07d %S %S\n", count++, C, L->text);
|
|
DISCARD_TEXT(C);
|
|
|
|
}
|
|
#line 19 "inweb/Chapter 3/The Analyser.w"
|
|
;
|
|
} else {
|
|
section *S = Reader__get_section_for_range(W, range);
|
|
if (S) {
|
|
for (source_line *L = S->first_line; L; L = L->next_line)
|
|
|
|
{
|
|
#line 35 "inweb/Chapter 3/The Analyser.w"
|
|
TEMPORARY_TEXT(C);
|
|
WRITE_TO(C, "%s", Lines__category_name(L->category));
|
|
while (Str__len(C) < 20) PUT_TO(C, '.');
|
|
PRINT("%07d %S %S\n", count++, C, L->text);
|
|
DISCARD_TEXT(C);
|
|
|
|
}
|
|
#line 24 "inweb/Chapter 3/The Analyser.w"
|
|
|
|
} else {
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)
|
|
for (source_line *L = S->first_line; L; L = L->next_line)
|
|
|
|
{
|
|
#line 35 "inweb/Chapter 3/The Analyser.w"
|
|
TEMPORARY_TEXT(C);
|
|
WRITE_TO(C, "%s", Lines__category_name(L->category));
|
|
while (Str__len(C) < 20) PUT_TO(C, '.');
|
|
PRINT("%07d %S %S\n", count++, C, L->text);
|
|
DISCARD_TEXT(C);
|
|
|
|
}
|
|
#line 29 "inweb/Chapter 3/The Analyser.w"
|
|
;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 50 "inweb/Chapter 3/The Analyser.w"
|
|
|
|
#line 52 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__catalogue_the_sections(web *W, text_stream *range, int form) {
|
|
int max_width = 0, max_range_width = 0;
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
|
|
if (max_range_width < Str__len(S->sect_range)) max_range_width = Str__len(S->sect_range);
|
|
TEMPORARY_TEXT(main_title);
|
|
WRITE_TO(main_title, "Chapter %S/%S", C->md->ch_range, S->md->sect_title);
|
|
if (max_width < Str__len(main_title)) max_width = Str__len(main_title);
|
|
DISCARD_TEXT(main_title);
|
|
}
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
if ((Str__eq_wide_string(range, L"0")) || (Str__eq(range, C->md->ch_range))) {
|
|
PRINT(" -----\n");
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
|
|
TEMPORARY_TEXT(main_title);
|
|
WRITE_TO(main_title, "Chapter %S/%S", C->md->ch_range, S->md->sect_title);
|
|
PRINT("%4d %S", S->sect_extent, S->sect_range);
|
|
for (int i = Str__len(S->sect_range); 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)
|
|
LanguageMethods__catalogue(S->sect_language, S,
|
|
(form == FUNCTIONS_SECTIONCAT)?TRUE:FALSE);
|
|
PRINT("\n");
|
|
DISCARD_TEXT(main_title);
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 107 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__analyse_code(web *W) {
|
|
if (W->analysed) return;
|
|
|
|
|
|
{
|
|
#line 142 "inweb/Chapter 3/The Analyser.w"
|
|
LanguageMethods__early_preweave_analysis(W->main_language, W);
|
|
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
|
|
if ((L->category == INTERFACE_BODY_LCAT) &&
|
|
(L->interface_line_identified == FALSE) &&
|
|
(Regexp__string_is_white_space(L->text) == FALSE))
|
|
Main__error_in_web(TL_IS_143, L);
|
|
|
|
}
|
|
#line 110 "inweb/Chapter 3/The Analyser.w"
|
|
;
|
|
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
|
|
switch (L->category) {
|
|
case BEGIN_DEFINITION_LCAT:
|
|
|
|
{
|
|
#line 156 "inweb/Chapter 3/The Analyser.w"
|
|
Analyser__analyse_as_code(W, L, L->text_operand2, ANY_USAGE, 0);
|
|
while ((L->next_line) && (L->next_line->category == CONT_DEFINITION_LCAT)) {
|
|
L = L->next_line;
|
|
Analyser__analyse_as_code(W, L, L->text, ANY_USAGE, 0);
|
|
}
|
|
|
|
}
|
|
#line 117 "inweb/Chapter 3/The Analyser.w"
|
|
;
|
|
break;
|
|
case CODE_BODY_LCAT:
|
|
|
|
{
|
|
#line 153 "inweb/Chapter 3/The Analyser.w"
|
|
Analyser__analyse_as_code(W, L, L->text, ANY_USAGE, 0);
|
|
|
|
}
|
|
#line 120 "inweb/Chapter 3/The Analyser.w"
|
|
;
|
|
break;
|
|
case PREFORM_GRAMMAR_LCAT:
|
|
|
|
{
|
|
#line 169 "inweb/Chapter 3/The Analyser.w"
|
|
Analyser__analyse_as_code(W, L, L->text_operand2, ANY_USAGE, 0);
|
|
Analyser__analyse_as_code(W, L, L->text_operand, PREFORM_IN_CODE_USAGE, PREFORM_IN_GRAMMAR_USAGE);
|
|
|
|
}
|
|
#line 123 "inweb/Chapter 3/The Analyser.w"
|
|
;
|
|
break;
|
|
}
|
|
|
|
LanguageMethods__late_preweave_analysis(W->main_language, W);
|
|
W->analysed = TRUE;
|
|
}
|
|
|
|
#line 185 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__analyse_as_code(web *W, source_line *L, text_stream *text, int mask, int transf) {
|
|
int start_at = -1, element_follows = FALSE;
|
|
for (int i = 0; i < Str__len(text); i++) {
|
|
if ((Regexp__identifier_char(Str__get_at(text, i))) ||
|
|
((Str__get_at(text, i) == '-') && (Str__get_at(text, i+1) != '>'))) {
|
|
if (start_at == -1) start_at = i;
|
|
} else {
|
|
if (start_at != -1) {
|
|
int u = MISC_USAGE;
|
|
if (element_follows) u = ELEMENT_ACCESS_USAGE;
|
|
else if (Str__get_at(text, i) == '(') u = FCALL_USAGE;
|
|
else if ((Str__get_at(text, i) == '>') && (start_at > 0) && (Str__get_at(text, start_at-1) == '<'))
|
|
u = PREFORM_IN_CODE_USAGE;
|
|
if (u & mask) {
|
|
if (transf) u = transf;
|
|
TEMPORARY_TEXT(identifier_found);
|
|
for (int j = 0; start_at + j < i; j++)
|
|
PUT_TO(identifier_found, Str__get_at(text, start_at + j));
|
|
Analyser__analyse_find(W, L, identifier_found, u);
|
|
DISCARD_TEXT(identifier_found);
|
|
}
|
|
start_at = -1; element_follows = FALSE;
|
|
}
|
|
if (Str__get_at(text, i) == '.') element_follows = TRUE;
|
|
else if ((Str__get_at(text, i) == '-') && (Str__get_at(text, i+1) == '>')) {
|
|
element_follows = TRUE; i++;
|
|
} else element_follows = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 227 "inweb/Chapter 3/The Analyser.w"
|
|
int Analyser__hash_code_from_word(text_stream *text) {
|
|
unsigned int hash_code = 0;
|
|
string_position p = Str__start(text);
|
|
switch(Str__get(p)) {
|
|
case '-': if (Str__len(text) == 1) break; /* an isolated minus sign is an ordinary word */
|
|
/* and otherwise fall into... */
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
case '5': case '6': case '7': case '8': case '9': {
|
|
int numeric = TRUE;
|
|
/* the first character may prove to be the start of a number: is this true? */
|
|
for (p = Str__forward(p); Str__in_range(p); p = Str__forward(p))
|
|
if (isdigit(Str__get(p)) == FALSE) numeric = FALSE;
|
|
if (numeric) return NUMBER_HASH;
|
|
}
|
|
}
|
|
for (p=Str__start(text); Str__in_range(p); p = Str__forward(p))
|
|
hash_code = (unsigned int) ((int) (hash_code*30011) + (Str__get(p)));
|
|
return (int) (1+(hash_code % (HASH_TAB_SIZE-1))); /* result of X 30011, plus 1 */
|
|
}
|
|
|
|
#line 254 "inweb/Chapter 3/The Analyser.w"
|
|
|
|
#line 264 "inweb/Chapter 3/The Analyser.w"
|
|
|
|
#line 271 "inweb/Chapter 3/The Analyser.w"
|
|
hash_table_entry *Analyser__find_hash_entry(hash_table *HT, text_stream *text, int create) {
|
|
int h = Analyser__hash_code_from_word(text);
|
|
if (h == NUMBER_HASH) return NULL;
|
|
if (HT->analysis_hash_initialised == FALSE) {
|
|
for (int i=0; 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"
|
|
void Analyser__mark_reserved_word(hash_table *HT, text_stream *p, int e) {
|
|
hash_table_entry *hte = Analyser__find_hash_entry(HT, p, TRUE);
|
|
hte->reserved_word |= (1 << e);
|
|
}
|
|
|
|
void Analyser__mark_reserved_word_for_section(section *S, text_stream *p, int e) {
|
|
Analyser__mark_reserved_word(&(S->sect_target->symbols), p, e);
|
|
}
|
|
|
|
int Analyser__is_reserved_word(hash_table *HT, text_stream *p, int e) {
|
|
hash_table_entry *hte = Analyser__find_hash_entry(HT, p, FALSE);
|
|
if ((hte) && (hte->reserved_word & (1 << e))) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
int Analyser__is_reserved_word_for_section(section *S, text_stream *p, int e) {
|
|
return Analyser__is_reserved_word(&(S->sect_target->symbols), p, e);
|
|
}
|
|
|
|
#line 336 "inweb/Chapter 3/The Analyser.w"
|
|
|
|
#line 340 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__analyse_find(web *W, source_line *L, text_stream *identifier, int u) {
|
|
hash_table_entry *hte =
|
|
Analyser__find_hash_entry_for_section(L->owning_section, identifier, FALSE);
|
|
if (hte == NULL) return;
|
|
hash_table_entry_usage *hteu = NULL;
|
|
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
|
|
if (L->owning_paragraph == hteu->usage_recorded_at)
|
|
break;
|
|
if (hteu == NULL) {
|
|
hteu = CREATE(hash_table_entry_usage);
|
|
hteu->form_of_usage = 0;
|
|
hteu->usage_recorded_at = L->owning_paragraph;
|
|
ADD_TO_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages);
|
|
}
|
|
hteu->form_of_usage |= u;
|
|
}
|
|
|
|
#line 362 "inweb/Chapter 3/The Analyser.w"
|
|
void Analyser__write_makefile(web *W, filename *F, module_search *I) {
|
|
filename *prototype = Filenames__in_folder(W->md->path_to_web, TL_IS_144);
|
|
if (!(TextFiles__exists(prototype)))
|
|
prototype = Filenames__in_folder(path_to_inweb_materials, TL_IS_145);
|
|
Makefiles__write(W, prototype, F, I);
|
|
}
|
|
|
|
void Analyser__write_gitignore(web *W, filename *F) {
|
|
filename *prototype = Filenames__in_folder(W->md->path_to_web, TL_IS_146);
|
|
if (!(TextFiles__exists(prototype)))
|
|
prototype = Filenames__in_folder(path_to_inweb_materials, TL_IS_147);
|
|
Git__write_gitignore(W, prototype, F);
|
|
}
|
|
|
|
#line 18 "inweb/Chapter 3/The Swarm.w"
|
|
weave_target *swarm_leader = NULL; /* the most inclusive one we weave */
|
|
|
|
void Swarm__weave(web *W, text_stream *range, int swarm_mode, theme_tag *tag,
|
|
weave_pattern *pattern, filename *to, pathname *into, int docs_mode,
|
|
linked_list *breadcrumbs, filename *navigation) {
|
|
swarm_leader = NULL;
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
if (C->md->imported == FALSE) {
|
|
if (swarm_mode == SWARM_CHAPTERS_SWM)
|
|
if ((W->md->chaptered == TRUE) && (Reader__range_within(C->md->ch_range, range))) {
|
|
C->ch_weave = Swarm__weave_subset(W,
|
|
C->md->ch_range, FALSE, tag, pattern, to, into, docs_mode,
|
|
breadcrumbs, navigation);
|
|
if (Str__len(range) > 0) swarm_leader = C->ch_weave;
|
|
}
|
|
if (swarm_mode == SWARM_SECTIONS_SWM)
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)
|
|
if (Reader__range_within(S->sect_range, range))
|
|
S->sect_weave = Swarm__weave_subset(W,
|
|
S->sect_range, FALSE, tag, pattern, to, into, docs_mode,
|
|
breadcrumbs, navigation);
|
|
}
|
|
|
|
Swarm__weave_index_templates(W, range, pattern, (to)?TRUE:FALSE, into, navigation,
|
|
breadcrumbs, docs_mode);
|
|
}
|
|
|
|
#line 52 "inweb/Chapter 3/The Swarm.w"
|
|
weave_target *Swarm__weave_subset(web *W, text_stream *range, int open_afterwards,
|
|
theme_tag *tag, weave_pattern *pattern, filename *to, pathname *into, int docs_mode,
|
|
linked_list *breadcrumbs, filename *navigation) {
|
|
weave_target *wt = NULL;
|
|
if (no_inweb_errors == 0) {
|
|
Analyser__analyse_code(W);
|
|
|
|
{
|
|
#line 88 "inweb/Chapter 3/The Swarm.w"
|
|
wt = CREATE(weave_target);
|
|
wt->weave_web = W;
|
|
wt->weave_range = Str__duplicate(range);
|
|
wt->pattern = pattern;
|
|
wt->theme_match = tag;
|
|
wt->booklet_title = Str__new();
|
|
wt->format = pattern->pattern_format;
|
|
wt->post_processing_results = NULL;
|
|
wt->cover_sheet_to_use = Str__new();
|
|
wt->self_contained = FALSE;
|
|
wt->docs_mode = docs_mode;
|
|
wt->navigation = navigation;
|
|
wt->breadcrumbs = breadcrumbs;
|
|
if (Reader__web_has_one_section(W)) wt->self_contained = TRUE;
|
|
Str__copy(wt->cover_sheet_to_use, TL_IS_148);
|
|
|
|
TEMPORARY_TEXT(leafname);
|
|
|
|
{
|
|
#line 124 "inweb/Chapter 3/The Swarm.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Str__eq_wide_string(range, L"0")) {
|
|
wt->booklet_title = Str__new_from_wide_string(L"Complete Program");
|
|
if (W->md->single_file) {
|
|
Filenames__write_unextended_leafname(leafname, W->md->single_file);
|
|
} else {
|
|
WRITE_TO(leafname, "Complete");
|
|
}
|
|
if (wt->theme_match)
|
|
{
|
|
#line 156 "inweb/Chapter 3/The Swarm.w"
|
|
Str__clear(wt->booklet_title);
|
|
WRITE_TO(wt->booklet_title, "Extracts: %S", wt->theme_match->tag_name);
|
|
Str__copy(leafname, wt->theme_match->tag_name);
|
|
|
|
}
|
|
#line 132 "inweb/Chapter 3/The Swarm.w"
|
|
;
|
|
} else if (Regexp__match(&mr, range, L"%d+")) {
|
|
Str__clear(wt->booklet_title);
|
|
WRITE_TO(wt->booklet_title, "Chapter %S", range);
|
|
Str__copy(leafname, wt->booklet_title);
|
|
} else if (Regexp__match(&mr, range, L"%[A-O]")) {
|
|
Str__clear(wt->booklet_title);
|
|
WRITE_TO(wt->booklet_title, "Appendix %S", range);
|
|
Str__copy(leafname, wt->booklet_title);
|
|
} else if (Str__eq_wide_string(range, L"P")) {
|
|
wt->booklet_title = Str__new_from_wide_string(L"Preliminaries");
|
|
Str__copy(leafname, wt->booklet_title);
|
|
} else {
|
|
Str__copy(wt->booklet_title, range);
|
|
Str__copy(leafname, wt->booklet_title);
|
|
Str__clear(wt->cover_sheet_to_use);
|
|
}
|
|
LOOP_THROUGH_TEXT(P, leafname)
|
|
if ((Str__get(P) == '/') || (Str__get(P) == ' '))
|
|
Str__put(P, '-');
|
|
WRITE_TO(leafname, "%S", Formats__file_extension(wt->format));
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 105 "inweb/Chapter 3/The Swarm.w"
|
|
;
|
|
pathname *H = W->redirect_weaves_to;
|
|
if (H == NULL) H = into;
|
|
if (H == NULL) {
|
|
if (W->md->single_file == NULL)
|
|
H = Reader__woven_folder(W);
|
|
else
|
|
H = Filenames__get_path_to(W->md->single_file);
|
|
}
|
|
if (to) {
|
|
wt->weave_to = to;
|
|
wt->self_contained = TRUE;
|
|
} else wt->weave_to = Filenames__in_folder(H, leafname);
|
|
DISCARD_TEXT(leafname);
|
|
|
|
}
|
|
#line 58 "inweb/Chapter 3/The Swarm.w"
|
|
;
|
|
if (Weaver__weave_source(W, wt) == 0) /* i.e., the number of lines woven was zero */
|
|
Errors__fatal("empty weave request");
|
|
Formats__post_process_weave(wt, open_afterwards); /* e.g., run through TeX */
|
|
|
|
{
|
|
#line 163 "inweb/Chapter 3/The Swarm.w"
|
|
PRINT("[%S: %S -> %f", wt->booklet_title, wt->format->format_name, wt->weave_to);
|
|
Formats__report_on_post_processing(wt);
|
|
PRINT("]\n");
|
|
|
|
}
|
|
#line 62 "inweb/Chapter 3/The Swarm.w"
|
|
;
|
|
}
|
|
return wt;
|
|
}
|
|
|
|
#line 86 "inweb/Chapter 3/The Swarm.w"
|
|
|
|
#line 172 "inweb/Chapter 3/The Swarm.w"
|
|
void Swarm__weave_index_templates(web *W, text_stream *range, weave_pattern *pattern,
|
|
int self_contained, pathname *into, filename *F, linked_list *crumbs, int docs) {
|
|
if (!(Bibliographic__data_exists(W->md, TL_IS_149)))
|
|
Bibliographic__set_datum(W->md, TL_IS_150, TL_IS_151);
|
|
text_stream *index_leaf = NULL;
|
|
if (W->md->chaptered) index_leaf = TL_IS_152;
|
|
else index_leaf = TL_IS_153;
|
|
filename *OUT = Patterns__obtain_filename(pattern, index_leaf);
|
|
if (OUT == NULL) OUT = Patterns__obtain_filename(pattern, TL_IS_154);
|
|
if (OUT) Indexer__run(W, range, OUT, TL_IS_155, NULL, pattern, into, F, crumbs, docs);
|
|
if (self_contained == FALSE) Patterns__copy_payloads_into_weave(W, pattern);
|
|
}
|
|
|
|
#line 11 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__cover_sheet_maker(OUTPUT_STREAM, web *W, text_stream *unextended_leafname,
|
|
weave_target *wt, int halves) {
|
|
cover_sheet_state state;
|
|
|
|
{
|
|
#line 40 "inweb/Chapter 3/The Indexer.w"
|
|
state.halves = halves;
|
|
state.WEAVE_COVER_TO = OUT;
|
|
state.target = wt;
|
|
|
|
}
|
|
#line 14 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
|
|
TEMPORARY_TEXT(extended_leafname);
|
|
WRITE_TO(extended_leafname, "%S%S", unextended_leafname, Formats__file_extension(wt->format));
|
|
filename *cs_filename = Patterns__obtain_filename(wt->pattern, extended_leafname);
|
|
DISCARD_TEXT(extended_leafname);
|
|
|
|
TextFiles__read(cs_filename, FALSE, "can't open cover sheet file", TRUE,
|
|
Indexer__scan_cover_line, NULL, (void *) &state);
|
|
}
|
|
|
|
#line 38 "inweb/Chapter 3/The Indexer.w"
|
|
|
|
#line 49 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__scan_cover_line(text_stream *line, text_file_position *tfp, void *v_state) {
|
|
cover_sheet_state *state = (cover_sheet_state *) v_state;
|
|
text_stream *OUT = state->WEAVE_COVER_TO;
|
|
int include = FALSE;
|
|
if (((state->halves & WEAVE_FIRST_HALF) &&
|
|
((state->halves & IN_SECOND_HALF) == 0)) ||
|
|
((state->halves & WEAVE_SECOND_HALF) &&
|
|
(state->halves & IN_SECOND_HALF))) include = TRUE;
|
|
|
|
TEMPORARY_TEXT(matter);
|
|
Str__copy(matter, line);
|
|
match_results mr = Regexp__create_mr();
|
|
if ((include) && ((state->target->self_contained) || (state->target->pattern->embed_CSS)) &&
|
|
(Regexp__match(&mr, matter, L" *%<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"Cover Sheet")) {
|
|
if (include)
|
|
{
|
|
#line 99 "inweb/Chapter 3/The Indexer.w"
|
|
if (state->target->pattern->based_on) {
|
|
weave_pattern *saved = state->target->pattern;
|
|
state->target->pattern = state->target->pattern->based_on;
|
|
Indexer__cover_sheet_maker(OUT, state->target->weave_web,
|
|
TL_IS_156, state->target,
|
|
(state->halves & (WEAVE_FIRST_HALF + WEAVE_SECOND_HALF)));
|
|
state->target->pattern = saved;
|
|
} else {
|
|
Errors__in_text_file("cover sheet recursively includes itself", tfp);
|
|
}
|
|
|
|
}
|
|
#line 86 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else if (Regexp__match(&mr2, command, L"Navigation")) {
|
|
if (include)
|
|
{
|
|
#line 111 "inweb/Chapter 3/The Indexer.w"
|
|
pathname *P = Filenames__get_path_to(state->target->weave_to);
|
|
Indexer__nav_column(OUT, P, state->target->weave_web, state->target->weave_range,
|
|
state->target->pattern, state->target->navigation);
|
|
|
|
}
|
|
#line 88 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else if (Regexp__match(&mr2, command, L"Template (%c*?)")) {
|
|
if (include)
|
|
{
|
|
#line 116 "inweb/Chapter 3/The Indexer.w"
|
|
pathname *P = Filenames__get_path_to(state->target->weave_to);
|
|
filename *CF = Patterns__obtain_filename(state->target->pattern, mr2.exp[0]);
|
|
if (CF == NULL)
|
|
Errors__in_text_file("pattern does not provide this template file", tfp);
|
|
else
|
|
Indexer__run(state->target->weave_web, state->target->weave_range,
|
|
CF, NULL, OUT, state->target->pattern, P, state->target->navigation,
|
|
NULL, FALSE);
|
|
|
|
}
|
|
#line 90 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else if (Bibliographic__data_exists(state->target->weave_web->md, command)) {
|
|
if (include)
|
|
{
|
|
#line 126 "inweb/Chapter 3/The Indexer.w"
|
|
WRITE("%S", Bibliographic__get_datum(state->target->weave_web->md, command));
|
|
|
|
}
|
|
#line 92 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else {
|
|
if (include) WRITE("%S", command);
|
|
}
|
|
Regexp__dispose_of(&mr2);
|
|
|
|
}
|
|
#line 72 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
Str__copy(matter, right);
|
|
}
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
if (include) WRITE("%S\n", matter);
|
|
DISCARD_TEXT(matter);
|
|
}
|
|
|
|
#line 131 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__nav_column(OUTPUT_STREAM, pathname *P, web *W, text_stream *range,
|
|
weave_pattern *pattern, filename *nav) {
|
|
if (nav) {
|
|
if (TextFiles__exists(nav))
|
|
Indexer__run(W, range, nav, NULL, OUT, pattern, P, NULL, NULL, FALSE);
|
|
else
|
|
Errors__fatal_with_file("unable to find navigation file", nav);
|
|
} else {
|
|
if (pattern->hierarchical) {
|
|
filename *F = Filenames__in_folder(Pathnames__up(P), TL_IS_157);
|
|
if (TextFiles__exists(F))
|
|
Indexer__run(W, range, F, NULL, OUT, pattern, P, NULL, NULL, FALSE);
|
|
}
|
|
filename *F = Filenames__in_folder(P, TL_IS_158);
|
|
if (TextFiles__exists(F))
|
|
Indexer__run(W, range, F, NULL, OUT, pattern, P, NULL, NULL, FALSE);
|
|
}
|
|
}
|
|
|
|
#line 180 "inweb/Chapter 3/The Indexer.w"
|
|
|
|
contents_processor Indexer__new_processor(text_stream *range) {
|
|
contents_processor cp;
|
|
cp.no_tlines = 0;
|
|
cp.restrict_to_range = Str__duplicate(range);
|
|
cp.stack_pointer = 0;
|
|
return cp;
|
|
}
|
|
|
|
#line 194 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__run(web *W, text_stream *range,
|
|
filename *template_filename, text_stream *contents_page_leafname,
|
|
text_stream *write_to, weave_pattern *pattern, pathname *P, filename *nav_file,
|
|
linked_list *crumbs, int docs) {
|
|
contents_processor actual_cp = Indexer__new_processor(range);
|
|
actual_cp.nav_web = W;
|
|
actual_cp.nav_pattern = pattern;
|
|
actual_cp.nav_path = P;
|
|
actual_cp.nav_file = nav_file;
|
|
actual_cp.crumbs = crumbs;
|
|
actual_cp.docs_mode = docs;
|
|
contents_processor *cp = &actual_cp;
|
|
text_stream TO_struct; text_stream *OUT = &TO_struct;
|
|
|
|
{
|
|
#line 249 "inweb/Chapter 3/The Indexer.w"
|
|
TextFiles__read(template_filename, FALSE,
|
|
"can't find contents template", TRUE, Indexer__save_template_line, NULL, cp);
|
|
if (TRACE_CI_EXECUTION)
|
|
PRINT("Read template <%f>: %d line(s)\n", template_filename, cp->no_tlines);
|
|
|
|
}
|
|
#line 207 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
|
|
{
|
|
#line 264 "inweb/Chapter 3/The Indexer.w"
|
|
pathname *H = W->redirect_weaves_to;
|
|
if (H == NULL) H = Reader__woven_folder(W);
|
|
if (write_to) OUT = write_to;
|
|
else {
|
|
filename *Contents = Filenames__in_folder(H, contents_page_leafname);
|
|
if (STREAM_OPEN_TO_FILE(OUT, Contents, ISO_ENC) == FALSE)
|
|
Errors__fatal_with_file("unable to write contents file", Contents);
|
|
if (W->as_ebook)
|
|
Epub__note_page(W->as_ebook, Contents, TL_IS_159, TL_IS_160);
|
|
PRINT("[Index file: %f]\n", Contents);
|
|
}
|
|
|
|
}
|
|
#line 208 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
|
|
int lpos = 0; /* This is our program counter: a line number in the template */
|
|
while (lpos < cp->no_tlines) {
|
|
match_results mr = Regexp__create_mr();
|
|
TEMPORARY_TEXT(tl);
|
|
Str__copy(tl, cp->tlines[lpos++]); /* Fetch the line at the program counter and advance */
|
|
|
|
{
|
|
#line 225 "inweb/Chapter 3/The Indexer.w"
|
|
if (Regexp__match(&mr, tl, L"(%c*?) ")) Str__copy(tl, mr.exp[0]); /* Strip trailing spaces */
|
|
if (TRACE_CI_EXECUTION)
|
|
|
|
{
|
|
#line 279 "inweb/Chapter 3/The Indexer.w"
|
|
PRINT("%04d: %S\nStack:", lpos-1, tl);
|
|
for (int j=0; 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))->sect_range,
|
|
((section *) CONTENT_IN_ITEM(cp->repeat_stack_threshold[j], section))->sect_range);
|
|
}
|
|
PRINT("\n");
|
|
|
|
}
|
|
#line 227 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
if ((pattern->embed_CSS) &&
|
|
(Regexp__match(&mr, tl, L" *%<link href=%\"(%c+?)\"%c*"))) {
|
|
filename *CSS_file = Patterns__obtain_filename(pattern, mr.exp[0]);
|
|
Indexer__transcribe_CSS(OUT, CSS_file);
|
|
Str__clear(tl);
|
|
}
|
|
if ((Regexp__match(&mr, tl, L"%[%[(%c+)%]%]")) ||
|
|
(Regexp__match(&mr, tl, L" %[%[(%c+)%]%]"))) {
|
|
TEMPORARY_TEXT(command);
|
|
Str__copy(command, mr.exp[0]);
|
|
|
|
{
|
|
#line 297 "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->sect_range, mr.exp[0])) {
|
|
Indexer__start_CI_loop(cp, SECTION_LEVEL, S_item, S_item, lpos);
|
|
Regexp__dispose_of(&mr);
|
|
goto CYCLE;
|
|
}
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
if (Str__eq(C->md->ch_range, mr.exp[0])) {
|
|
Indexer__start_CI_loop(cp, CHAPTER_LEVEL, C_item, C_item, lpos);
|
|
Regexp__dispose_of(&mr);
|
|
goto CYCLE;
|
|
}
|
|
Errors__at_position("don't recognise the chapter or section abbreviation range",
|
|
template_filename, lpos);
|
|
Regexp__dispose_of(&mr);
|
|
goto CYCLE;
|
|
}
|
|
|
|
}
|
|
#line 238 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
|
|
{
|
|
#line 323 "inweb/Chapter 3/The Indexer.w"
|
|
int loop_level = 0;
|
|
if (Regexp__match(&mr, command, L"Repeat Chapter")) loop_level = CHAPTER_LEVEL;
|
|
if (Regexp__match(&mr, command, L"Repeat Section")) loop_level = SECTION_LEVEL;
|
|
if (loop_level != 0) {
|
|
linked_list_item *from = NULL, *to = NULL;
|
|
linked_list_item *CI = FIRST_ITEM_IN_LINKED_LIST(chapter, W->chapters);
|
|
while ((CI) && (CONTENT_IN_ITEM(CI, chapter)->md->imported))
|
|
CI = NEXT_ITEM_IN_LINKED_LIST(CI, chapter);
|
|
if (loop_level == CHAPTER_LEVEL) {
|
|
from = CI;
|
|
to = LAST_ITEM_IN_LINKED_LIST(chapter, W->chapters);
|
|
if (Str__eq_wide_string(cp->restrict_to_range, L"0") == FALSE) {
|
|
chapter *C;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
if (Str__eq(C->md->ch_range, cp->restrict_to_range)) {
|
|
from = C_item; to = from;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (loop_level == SECTION_LEVEL) {
|
|
chapter *within_chapter =
|
|
CONTENT_IN_ITEM(Indexer__heading_topmost_on_stack(cp, CHAPTER_LEVEL), chapter);
|
|
if (within_chapter == NULL) {
|
|
if (CI) {
|
|
chapter *C = CONTENT_IN_ITEM(CI, chapter);
|
|
from = FIRST_ITEM_IN_LINKED_LIST(section, C->sections);
|
|
}
|
|
chapter *LC = LAST_IN_LINKED_LIST(chapter, W->chapters);
|
|
if (LC) to = LAST_ITEM_IN_LINKED_LIST(section, LC->sections);
|
|
} else {
|
|
from = FIRST_ITEM_IN_LINKED_LIST(section, within_chapter->sections);
|
|
to = LAST_ITEM_IN_LINKED_LIST(section, within_chapter->sections);
|
|
}
|
|
}
|
|
if (from) Indexer__start_CI_loop(cp, loop_level, from, to, lpos);
|
|
goto CYCLE;
|
|
}
|
|
|
|
}
|
|
#line 239 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
|
|
{
|
|
#line 365 "inweb/Chapter 3/The Indexer.w"
|
|
if ((Regexp__match(&mr, command, L"End Repeat")) || (Regexp__match(&mr, command, L"End Select"))) {
|
|
if (cp->stack_pointer <= 0)
|
|
Errors__at_position("stack underflow on contents template", template_filename, lpos);
|
|
if (cp->repeat_stack_level[cp->stack_pointer-1] == SECTION_LEVEL) {
|
|
linked_list_item *SI = cp->repeat_stack_variable[cp->stack_pointer-1];
|
|
if ((SI == cp->repeat_stack_threshold[cp->stack_pointer-1]) ||
|
|
(NEXT_ITEM_IN_LINKED_LIST(SI, section) == NULL))
|
|
Indexer__end_CI_loop(cp);
|
|
else {
|
|
cp->repeat_stack_variable[cp->stack_pointer-1] =
|
|
NEXT_ITEM_IN_LINKED_LIST(SI, section);
|
|
lpos = cp->repeat_stack_startpos[cp->stack_pointer-1]; /* Back round loop */
|
|
}
|
|
} else {
|
|
linked_list_item *CI = cp->repeat_stack_variable[cp->stack_pointer-1];
|
|
if (CI == cp->repeat_stack_threshold[cp->stack_pointer-1])
|
|
Indexer__end_CI_loop(cp);
|
|
else {
|
|
cp->repeat_stack_variable[cp->stack_pointer-1] =
|
|
NEXT_ITEM_IN_LINKED_LIST(CI, chapter);
|
|
lpos = cp->repeat_stack_startpos[cp->stack_pointer-1]; /* Back round loop */
|
|
}
|
|
}
|
|
goto CYCLE;
|
|
}
|
|
|
|
}
|
|
#line 240 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
DISCARD_TEXT(command);
|
|
}
|
|
|
|
{
|
|
#line 394 "inweb/Chapter 3/The Indexer.w"
|
|
for (int rstl = cp->stack_pointer-1; rstl >= 0; rstl--)
|
|
if (cp->repeat_stack_level[cp->stack_pointer-1] == SECTION_LEVEL) {
|
|
linked_list_item *SI = cp->repeat_stack_threshold[cp->stack_pointer-1];
|
|
if (NEXT_ITEM_IN_LINKED_LIST(SI, section) ==
|
|
cp->repeat_stack_variable[cp->stack_pointer-1])
|
|
goto CYCLE;
|
|
}
|
|
|
|
}
|
|
#line 243 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
|
|
{
|
|
#line 440 "inweb/Chapter 3/The Indexer.w"
|
|
int slen, spos;
|
|
while ((spos = Regexp__find_expansion(tl, '[', '[', ']', ']', &slen)) >= 0) {
|
|
TEMPORARY_TEXT(left_part);
|
|
TEMPORARY_TEXT(varname);
|
|
TEMPORARY_TEXT(right_part);
|
|
|
|
Str__substr(left_part, Str__start(tl), Str__at(tl, spos));
|
|
Str__substr(varname, Str__at(tl, spos+2), Str__at(tl, spos+slen-2));
|
|
Str__substr(right_part, Str__at(tl, spos+slen), Str__end(tl));
|
|
|
|
TEMPORARY_TEXT(substituted);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Bibliographic__data_exists(W->md, varname)) {
|
|
|
|
{
|
|
#line 495 "inweb/Chapter 3/The Indexer.w"
|
|
Str__copy(substituted, Bibliographic__get_datum(W->md, varname));
|
|
|
|
}
|
|
#line 453 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else if (Regexp__match(&mr, varname, L"Navigation")) {
|
|
Indexer__nav_column(substituted, cp->nav_path, cp->nav_web,
|
|
cp->restrict_to_range, cp->nav_pattern, cp->nav_file);
|
|
} else if (Regexp__match(&mr, varname, L"Breadcrumbs")) {
|
|
HTMLFormat__drop_initial_breadcrumbs(substituted, cp->crumbs, cp->docs_mode);
|
|
} else if (Regexp__match(&mr, varname, L"Modules")) {
|
|
|
|
{
|
|
#line 554 "inweb/Chapter 3/The Indexer.w"
|
|
module *M = W->md->as_module;
|
|
int L = LinkedLists__len(M->dependencies);
|
|
if (L > 0) {
|
|
WRITE_TO(substituted,
|
|
"<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 460 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else if (Regexp__match(&mr, varname, L"Chapter (%c+)")) {
|
|
text_stream *detail = mr.exp[0];
|
|
chapter *C = CONTENT_IN_ITEM(
|
|
Indexer__heading_topmost_on_stack(cp, CHAPTER_LEVEL), chapter);
|
|
if (C == NULL)
|
|
Errors__at_position("no chapter is currently selected",
|
|
template_filename, lpos);
|
|
else
|
|
{
|
|
#line 507 "inweb/Chapter 3/The Indexer.w"
|
|
if (Str__eq_wide_string(detail, L"Title")) {
|
|
Str__copy(substituted, C->md->ch_title);
|
|
} else if (Str__eq_wide_string(detail, L"Code")) {
|
|
Str__copy(substituted, C->md->ch_range);
|
|
} else if (Str__eq_wide_string(detail, L"Purpose")) {
|
|
Str__copy(substituted, C->md->rubric);
|
|
} else if (Formats__substitute_post_processing_data(substituted, C->ch_weave, detail, pattern)) {
|
|
;
|
|
} else {
|
|
WRITE_TO(substituted, "%S for %S", varname, C->md->ch_title);
|
|
}
|
|
|
|
}
|
|
#line 468 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else if (Regexp__match(&mr, varname, L"Section (%c+)")) {
|
|
text_stream *detail = mr.exp[0];
|
|
section *S = CONTENT_IN_ITEM(
|
|
Indexer__heading_topmost_on_stack(cp, SECTION_LEVEL), section);
|
|
if (S == NULL)
|
|
Errors__at_position("no section is currently selected",
|
|
template_filename, lpos);
|
|
else
|
|
{
|
|
#line 522 "inweb/Chapter 3/The Indexer.w"
|
|
if (Str__eq_wide_string(detail, L"Title")) {
|
|
Str__copy(substituted, S->md->sect_title);
|
|
} else if (Str__eq_wide_string(detail, L"Purpose")) {
|
|
Str__copy(substituted, S->sect_purpose);
|
|
} else if (Str__eq_wide_string(detail, L"Code")) {
|
|
Str__copy(substituted, S->sect_range);
|
|
} else if (Str__eq_wide_string(detail, L"Lines")) {
|
|
WRITE_TO(substituted, "%d", S->sect_extent);
|
|
} else if (Str__eq_wide_string(detail, L"Source")) {
|
|
WRITE_TO(substituted, "%f", S->md->source_file_for_section);
|
|
} else if (Str__eq_wide_string(detail, L"Page")) {
|
|
TEMPORARY_TEXT(linkto);
|
|
Str__copy(linkto, S->sect_range);
|
|
LOOP_THROUGH_TEXT(P, linkto)
|
|
if ((Str__get(P) == '/') || (Str__get(P) == ' '))
|
|
Str__put(P, '-');
|
|
WRITE_TO(linkto, ".html");
|
|
Str__copy(substituted, linkto);
|
|
DISCARD_TEXT(linkto);
|
|
} else if (Str__eq_wide_string(detail, L"Paragraphs")) {
|
|
WRITE_TO(substituted, "%d", S->sect_paragraphs);
|
|
} else if (Str__eq_wide_string(detail, L"Mean")) {
|
|
int denom = S->sect_paragraphs;
|
|
if (denom == 0) denom = 1;
|
|
WRITE_TO(substituted, "%d", S->sect_extent/denom);
|
|
} else if (Formats__substitute_post_processing_data(substituted, S->sect_weave, detail, pattern)) {
|
|
;
|
|
} else {
|
|
WRITE_TO(substituted, "%S for %S", varname, S->md->sect_title);
|
|
}
|
|
|
|
}
|
|
#line 476 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else if (Regexp__match(&mr, varname, L"Complete (%c+)")) {
|
|
text_stream *detail = mr.exp[0];
|
|
|
|
{
|
|
#line 500 "inweb/Chapter 3/The Indexer.w"
|
|
if (swarm_leader)
|
|
if (Formats__substitute_post_processing_data(substituted, swarm_leader, detail, pattern) == FALSE)
|
|
WRITE_TO(substituted, "%S for complete web", detail);
|
|
|
|
}
|
|
#line 479 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
} else {
|
|
WRITE_TO(substituted, "<b>%S</b>", varname);
|
|
}
|
|
Str__clear(tl);
|
|
WRITE_TO(tl, "%S%S%S", left_part, substituted, right_part);
|
|
Regexp__dispose_of(&mr);
|
|
DISCARD_TEXT(left_part);
|
|
DISCARD_TEXT(varname);
|
|
DISCARD_TEXT(substituted);
|
|
DISCARD_TEXT(right_part);
|
|
}
|
|
|
|
}
|
|
#line 244 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
|
|
}
|
|
#line 215 "inweb/Chapter 3/The Indexer.w"
|
|
;
|
|
WRITE("%S\n", tl); /* Copy the now finished line to the output */
|
|
DISCARD_TEXT(tl);
|
|
CYCLE: ;
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
if (write_to == NULL) STREAM_CLOSE(OUT);
|
|
}
|
|
|
|
#line 257 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__save_template_line(text_stream *line, text_file_position *tfp, void *void_cp) {
|
|
contents_processor *cp = (contents_processor *) void_cp;
|
|
if (cp->no_tlines < MAX_TEMPLATE_LINES)
|
|
cp->tlines[cp->no_tlines++] = Str__duplicate(line);
|
|
}
|
|
|
|
#line 409 "inweb/Chapter 3/The Indexer.w"
|
|
linked_list_item *Indexer__heading_topmost_on_stack(contents_processor *cp, int level) {
|
|
for (int rstl = cp->stack_pointer-1; rstl >= 0; rstl--)
|
|
if (cp->repeat_stack_level[rstl] == level)
|
|
return cp->repeat_stack_variable[rstl];
|
|
return NULL;
|
|
}
|
|
|
|
#line 420 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__start_CI_loop(contents_processor *cp, int level,
|
|
linked_list_item *from, linked_list_item *to, int pos) {
|
|
if (cp->stack_pointer < CI_STACK_CAPACITY) {
|
|
cp->repeat_stack_level[cp->stack_pointer] = level;
|
|
cp->repeat_stack_variable[cp->stack_pointer] = from;
|
|
cp->repeat_stack_threshold[cp->stack_pointer] = to;
|
|
cp->repeat_stack_startpos[cp->stack_pointer++] = pos;
|
|
}
|
|
}
|
|
|
|
void Indexer__end_CI_loop(contents_processor *cp) {
|
|
cp->stack_pointer--;
|
|
}
|
|
|
|
#line 566 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__list_module(OUTPUT_STREAM, module *M, int list_this) {
|
|
if (list_this) {
|
|
WRITE("<li><p>%S - ", M->module_name);
|
|
TEMPORARY_TEXT(url);
|
|
WRITE_TO(url, "%p", M->module_location);
|
|
Readme__write_var(OUT, url, TL_IS_161);
|
|
DISCARD_TEXT(url);
|
|
WRITE("</p></li>");
|
|
}
|
|
module *N;
|
|
LOOP_OVER_LINKED_LIST(N, module, M->dependencies)
|
|
Indexer__list_module(OUT, N, TRUE);
|
|
}
|
|
|
|
#line 583 "inweb/Chapter 3/The Indexer.w"
|
|
void Indexer__transcribe_CSS(OUTPUT_STREAM, filename *CSS_file) {
|
|
WRITE("<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 16 "inweb/Chapter 3/The Weaver.w"
|
|
int Weaver__weave_source(web *W, weave_target *wv) {
|
|
text_stream TO_struct;
|
|
text_stream *OUT = &TO_struct;
|
|
if (STREAM_OPEN_TO_FILE(OUT, wv->weave_to, UTF8_ENC) == FALSE)
|
|
Errors__fatal_with_file("unable to write woven file", wv->weave_to);
|
|
|
|
|
|
{
|
|
#line 37 "inweb/Chapter 3/The Weaver.w"
|
|
TEMPORARY_TEXT(banner);
|
|
WRITE_TO(banner, "Weave of '%S' generated by %s", wv->booklet_title, INWEB_BUILD);
|
|
Formats__top(OUT, wv, banner);
|
|
DISCARD_TEXT(banner);
|
|
|
|
}
|
|
#line 22 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
if ((Str__len(wv->cover_sheet_to_use) > 0) && (Reader__web_has_one_section(W) == FALSE))
|
|
|
|
{
|
|
#line 43 "inweb/Chapter 3/The Weaver.w"
|
|
if (!(Bibliographic__data_exists(W->md, TL_IS_162)))
|
|
Bibliographic__set_datum(W->md, TL_IS_163, wv->booklet_title);
|
|
Indexer__cover_sheet_maker(OUT, W, wv->cover_sheet_to_use, wv, WEAVE_FIRST_HALF);
|
|
|
|
}
|
|
#line 24 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
int lines_woven = 0;
|
|
section *latest_section = NULL;
|
|
|
|
{
|
|
#line 48 "inweb/Chapter 3/The Weaver.w"
|
|
weaver_state state_at; weaver_state *state = &state_at;
|
|
|
|
{
|
|
#line 99 "inweb/Chapter 3/The Weaver.w"
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
state->line_break_pending = FALSE;
|
|
state->next_heading_without_vertical_skip = FALSE;
|
|
state->show_section_toc_soon = FALSE;
|
|
state->horizontal_rule_just_drawn = FALSE;
|
|
state->in_run_of_definitions = FALSE;
|
|
state->last_extract_from = NULL;
|
|
state->last_endnoted_para = NULL;
|
|
state->substantive_comment = FALSE;
|
|
state->chaptermark = Str__new();
|
|
state->sectionmark = Str__new();
|
|
|
|
}
|
|
#line 49 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(C, chapter, W->chapters)
|
|
if (C->md->imported == FALSE) {
|
|
Str__clear(state->chaptermark);
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)
|
|
if (Reader__range_within(S->sect_range, wv->weave_range)) {
|
|
latest_section = S;
|
|
LanguageMethods__begin_weave(S, wv);
|
|
Str__clear(state->sectionmark);
|
|
|
|
{
|
|
#line 114 "inweb/Chapter 3/The Weaver.w"
|
|
paragraph *current_paragraph = NULL;
|
|
for (source_line *L = S->first_line; L; L = L->next_line) {
|
|
if ((Tags__tagged_with(L->owning_paragraph, wv->theme_match)) &&
|
|
(LanguageMethods__skip_in_weaving(S->sect_language, wv, L) == FALSE)) {
|
|
lines_woven++;
|
|
|
|
{
|
|
#line 126 "inweb/Chapter 3/The Weaver.w"
|
|
/* In principle, all of these source lines should be woven, but... */
|
|
|
|
{
|
|
#line 150 "inweb/Chapter 3/The Weaver.w"
|
|
if (L->category == INTERFACE_BODY_LCAT) continue;
|
|
if (L->category == PURPOSE_BODY_LCAT) continue;
|
|
if (L->category == BEGIN_CODE_LCAT) {
|
|
state->line_break_pending = FALSE;
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 127 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 161 "inweb/Chapter 3/The Weaver.w"
|
|
if (L->category == COMMAND_LCAT) {
|
|
if (L->command_code == PAGEBREAK_CMD) Formats__pagebreak(OUT, wv);
|
|
if (L->command_code == GRAMMAR_INDEX_CMD) InCSupport__weave_grammar_index(OUT);
|
|
if (L->command_code == FIGURE_CMD)
|
|
{
|
|
#line 170 "inweb/Chapter 3/The Weaver.w"
|
|
text_stream *figname = L->text_operand;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, figname, L"(%d+)cm: (%c+)")) {
|
|
if (S->md->using_syntax > V1_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "[[Figure: Xcm:...]]", V1_SYNTAX);
|
|
Formats__figure(OUT, wv, mr.exp[1], Str__atoi(mr.exp[0], 0), -1, NULL);
|
|
} else if (Regexp__match(&mr, figname, L"(%c+) width (%d+)cm")) {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "[[F width Xcm]]", V2_SYNTAX);
|
|
Formats__figure(OUT, wv, mr.exp[0], Str__atoi(mr.exp[1], 0), -1, NULL);
|
|
} else if (Regexp__match(&mr, figname, L"(%c+) height (%d+)cm")) {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "[[F height Xcm]]", V2_SYNTAX);
|
|
Formats__figure(OUT, wv, mr.exp[0], -1, Str__atoi(mr.exp[1], 0), NULL);
|
|
} else if (Regexp__match(&mr, figname, L"(%c+txt) as (%c+)")) {
|
|
if (S->md->using_syntax < V2_SYNTAX)
|
|
Parser__wrong_version(S->md->using_syntax, L, "[[F as L]]", V2_SYNTAX);
|
|
programming_language *pl = Languages__find_by_name(mr.exp[1]);
|
|
Formats__figure(OUT, wv, mr.exp[0], -1, -1, pl);
|
|
} else {
|
|
Formats__figure(OUT, wv, figname, -1, -1, NULL);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 164 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
/* Otherwise assume it was a tangler command, and ignore it here */
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 128 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
/* Some of the more baroque front matter of a section... */
|
|
|
|
{
|
|
#line 200 "inweb/Chapter 3/The Weaver.w"
|
|
if (L->category == PURPOSE_LCAT) {
|
|
Formats__subheading(OUT, wv, 2, S->sect_purpose, NULL);
|
|
Weaver__weave_table_of_contents(OUT, wv, S);
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 131 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 209 "inweb/Chapter 3/The Weaver.w"
|
|
if ((state->show_section_toc_soon == 1) && (Regexp__string_is_white_space(L->text))) {
|
|
state->show_section_toc_soon = FALSE;
|
|
if (Weaver__weave_table_of_contents(OUT, wv, S))
|
|
state->horizontal_rule_just_drawn = TRUE;
|
|
else
|
|
state->horizontal_rule_just_drawn = FALSE;
|
|
}
|
|
|
|
}
|
|
#line 132 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 221 "inweb/Chapter 3/The Weaver.w"
|
|
if (L->category == INTERFACE_LCAT) {
|
|
state->horizontal_rule_just_drawn = FALSE;
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 133 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 229 "inweb/Chapter 3/The Weaver.w"
|
|
if (L->category == DEFINITIONS_LCAT) {
|
|
Formats__subheading(OUT, wv, 2, TL_IS_166, NULL);
|
|
state->next_heading_without_vertical_skip = TRUE;
|
|
state->horizontal_rule_just_drawn = FALSE;
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 134 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 241 "inweb/Chapter 3/The Weaver.w"
|
|
if (L->category == BAR_LCAT) {
|
|
|
|
{
|
|
#line 643 "inweb/Chapter 3/The Weaver.w"
|
|
int mode_now = state->kind_of_material;
|
|
if (state->kind_of_material != REGULAR_MATERIAL) {
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
Formats__change_material(OUT, wv, mode_now, state->kind_of_material, TRUE);
|
|
}
|
|
if ((current_paragraph) && (current_paragraph != state->last_endnoted_para)) {
|
|
state->last_endnoted_para = current_paragraph;
|
|
Weaver__show_endnotes_on_previous_paragraph(OUT, wv, current_paragraph);
|
|
}
|
|
if (L) current_paragraph = L->owning_paragraph;
|
|
|
|
}
|
|
#line 242 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
state->next_heading_without_vertical_skip = TRUE;
|
|
if (state->horizontal_rule_just_drawn == FALSE) Formats__bar(OUT, wv);
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 135 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
/* The crucial junction point between modes... */
|
|
|
|
{
|
|
#line 492 "inweb/Chapter 3/The Weaver.w"
|
|
if ((L->category == HEADING_START_LCAT) ||
|
|
(L->category == PARAGRAPH_START_LCAT) ||
|
|
(L->category == CHAPTER_HEADING_LCAT) ||
|
|
(L->category == SECTION_HEADING_LCAT)) {
|
|
state->in_run_of_definitions = FALSE;
|
|
|
|
{
|
|
#line 643 "inweb/Chapter 3/The Weaver.w"
|
|
int mode_now = state->kind_of_material;
|
|
if (state->kind_of_material != REGULAR_MATERIAL) {
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
Formats__change_material(OUT, wv, mode_now, state->kind_of_material, TRUE);
|
|
}
|
|
if ((current_paragraph) && (current_paragraph != state->last_endnoted_para)) {
|
|
state->last_endnoted_para = current_paragraph;
|
|
Weaver__show_endnotes_on_previous_paragraph(OUT, wv, current_paragraph);
|
|
}
|
|
if (L) current_paragraph = L->owning_paragraph;
|
|
|
|
}
|
|
#line 497 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
if (wv->theme_match)
|
|
|
|
{
|
|
#line 527 "inweb/Chapter 3/The Weaver.w"
|
|
if ((L->owning_paragraph) &&
|
|
(L->owning_paragraph->starts_on_new_page)) Formats__pagebreak(OUT, wv);
|
|
|
|
}
|
|
#line 499 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
LanguageMethods__reset_syntax_colouring(S->sect_language); /* a precaution: limits bad colouring accidents to one para */
|
|
int weight = 0;
|
|
if (L->category == HEADING_START_LCAT) weight = 1;
|
|
if (L->category == SECTION_HEADING_LCAT) weight = 2;
|
|
if (L->category == CHAPTER_HEADING_LCAT) weight = 3;
|
|
|
|
|
|
{
|
|
#line 540 "inweb/Chapter 3/The Weaver.w"
|
|
if (weight == 3) {
|
|
Str__copy(state->chaptermark, L->text_operand);
|
|
Str__clear(state->sectionmark);
|
|
}
|
|
if (weight == 2) {
|
|
Str__copy(state->sectionmark, L->text_operand);
|
|
if (wv->pattern->show_abbrevs == FALSE) Str__clear(state->chaptermark);
|
|
else if (Str__len(S->sect_range) > 0) Str__copy(state->chaptermark, S->sect_range);
|
|
if (Str__len(state->chaptermark) > 0) {
|
|
Str__clear(state->sectionmark);
|
|
WRITE_TO(state->sectionmark, " - %S", L->text_operand);
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 506 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
text_stream *TeX_macro = NULL;
|
|
|
|
{
|
|
#line 570 "inweb/Chapter 3/The Weaver.w"
|
|
switch (weight) {
|
|
case 0: TeX_macro = TL_IS_173; break;
|
|
case 1: TeX_macro = TL_IS_174; break;
|
|
case 2: TeX_macro = TL_IS_175; break;
|
|
default: TeX_macro = TL_IS_176; break;
|
|
}
|
|
if (wv->theme_match)
|
|
{
|
|
#line 589 "inweb/Chapter 3/The Weaver.w"
|
|
switch (weight) {
|
|
case 0: TeX_macro = TL_IS_179; break;
|
|
case 1: TeX_macro = TL_IS_180; break;
|
|
case 2: TeX_macro = TL_IS_181; break;
|
|
default: TeX_macro = TL_IS_182; break;
|
|
}
|
|
if (weight >= 0) { weight = 0; }
|
|
text_stream *cap = Tags__retrieve_caption(L->owning_paragraph, wv->theme_match);
|
|
if (Str__len(cap) > 0) {
|
|
Formats__subheading(OUT, wv, 1, cap, C->md->ch_title);
|
|
state->last_extract_from = S;
|
|
} else if (state->last_extract_from != S) {
|
|
state->last_extract_from = S;
|
|
TEMPORARY_TEXT(extr);
|
|
WRITE_TO(extr, "From %S: %S", C->md->ch_title, S->md->sect_title);
|
|
Formats__subheading(OUT, wv, 1, extr, C->md->ch_title);
|
|
DISCARD_TEXT(extr);
|
|
}
|
|
|
|
}
|
|
#line 576 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
if ((state->next_heading_without_vertical_skip) && (weight < 2)) {
|
|
state->next_heading_without_vertical_skip = FALSE;
|
|
switch (weight) {
|
|
case 0: TeX_macro = TL_IS_177; break;
|
|
case 1: TeX_macro = TL_IS_178; break;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 509 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
TEMPORARY_TEXT(heading_text);
|
|
|
|
{
|
|
#line 609 "inweb/Chapter 3/The Weaver.w"
|
|
if (weight == 3) {
|
|
TEMPORARY_TEXT(brief_title);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, C->md->ch_title, L"%c*?: (%c*)"))
|
|
Str__copy(brief_title, mr.exp[0]);
|
|
else
|
|
Str__copy(brief_title, C->md->ch_title);
|
|
WRITE_TO(heading_text, "%S: %S", C->md->ch_range, brief_title);
|
|
DISCARD_TEXT(brief_title);
|
|
Regexp__dispose_of(&mr);
|
|
} else if ((weight == 2) && (Reader__web_has_one_section(W))) {
|
|
Str__copy(heading_text, Bibliographic__get_datum(W->md, TL_IS_183));
|
|
} else {
|
|
if ((weight == 2) && (wv->pattern->number_sections) && (S->printed_number >= 0))
|
|
WRITE_TO(heading_text, "%d. ", S->printed_number);
|
|
WRITE_TO(heading_text, "%S", L->text_operand);
|
|
}
|
|
|
|
}
|
|
#line 512 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
Formats__paragraph_heading(OUT, wv, TeX_macro, S, L->owning_paragraph,
|
|
heading_text, state->chaptermark, state->sectionmark, weight);
|
|
DISCARD_TEXT(heading_text);
|
|
|
|
if (weight == 0) state->substantive_comment = FALSE;
|
|
else state->substantive_comment = TRUE;
|
|
|
|
|
|
{
|
|
#line 631 "inweb/Chapter 3/The Weaver.w"
|
|
if (Str__len(L->text_operand2) > 0) {
|
|
TEMPORARY_TEXT(matter);
|
|
WRITE_TO(matter, "%S\n", L->text_operand2);
|
|
Formats__text(OUT, wv, matter);
|
|
DISCARD_TEXT(matter);
|
|
state->substantive_comment = TRUE;
|
|
}
|
|
|
|
}
|
|
#line 520 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
if (weight == 3) Formats__chapter_title_page(OUT, wv, C);
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 138 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
/* With all exotica dealt with, we now just have material to weave verbatim... */
|
|
TEMPORARY_TEXT(matter); Str__copy(matter, L->text);
|
|
if (L->is_commentary)
|
|
{
|
|
#line 254 "inweb/Chapter 3/The Weaver.w"
|
|
|
|
{
|
|
#line 266 "inweb/Chapter 3/The Weaver.w"
|
|
if (L->category == SOURCE_DISPLAY_LCAT) {
|
|
Formats__display_line(OUT, wv, L->text_operand);
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 254 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 275 "inweb/Chapter 3/The Weaver.w"
|
|
if (Regexp__string_is_white_space(matter)) {
|
|
if ((L->next_line) && (L->next_line->category == COMMENT_BODY_LCAT) &&
|
|
(state->substantive_comment)) {
|
|
match_results mr = Regexp__create_mr();
|
|
if ((state->kind_of_material != CODE_MATERIAL) ||
|
|
(Regexp__match(&mr, matter, L"\t|(%c*)|(%c*?)")))
|
|
Formats__blank_line(OUT, wv, TRUE);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 255 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 291 "inweb/Chapter 3/The Weaver.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, matter, L"%(...%) (%c*)")) { /* continue single */
|
|
Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL,
|
|
state->substantive_comment);
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
Formats__item(OUT, wv, 1, TL_IS_167);
|
|
Str__copy(matter, mr.exp[0]);
|
|
} else if (Regexp__match(&mr, matter, L"%(-...%) (%c*)")) { /* continue double */
|
|
Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL,
|
|
state->substantive_comment);
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
Formats__item(OUT, wv, 2, TL_IS_168);
|
|
Str__copy(matter, mr.exp[0]);
|
|
} else if (Regexp__match(&mr, matter, L"%((%i+)%) (%c*)")) { /* begin single */
|
|
Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL,
|
|
state->substantive_comment);
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
Formats__item(OUT, wv, 1, mr.exp[0]);
|
|
Str__copy(matter, mr.exp[1]);
|
|
} else if (Regexp__match(&mr, matter, L"%(-(%i+)%) (%c*)")) { /* begin double */
|
|
Formats__change_material(OUT, wv, state->kind_of_material, REGULAR_MATERIAL,
|
|
state->substantive_comment);
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
Formats__item(OUT, wv, 2, mr.exp[0]);
|
|
Str__copy(matter, mr.exp[1]);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 256 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 323 "inweb/Chapter 3/The Weaver.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, matter, L"\t|(%c*)|(%c*?)")) {
|
|
if (state->kind_of_material != CODE_MATERIAL) {
|
|
Formats__change_material(OUT, wv, state->kind_of_material, CODE_MATERIAL, TRUE);
|
|
state->kind_of_material = CODE_MATERIAL;
|
|
}
|
|
TEMPORARY_TEXT(original);
|
|
Str__copy(original, mr.exp[0]);
|
|
Str__copy(matter, mr.exp[1]);
|
|
TEMPORARY_TEXT(colouring);
|
|
for (int i=0; i<Str__len(original); i++) PUT_TO(colouring, PLAIN_COLOUR);
|
|
Formats__source_code(OUT, wv, 1, TL_IS_169, original, colouring, TL_IS_170, TRUE, TRUE, FALSE);
|
|
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);
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 257 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
state->substantive_comment = TRUE;
|
|
WRITE_TO(matter, "\n");
|
|
Formats__text(OUT, wv, matter);
|
|
continue;
|
|
|
|
}
|
|
#line 142 "inweb/Chapter 3/The Weaver.w"
|
|
|
|
else
|
|
{
|
|
#line 351 "inweb/Chapter 3/The Weaver.w"
|
|
|
|
{
|
|
#line 387 "inweb/Chapter 3/The Weaver.w"
|
|
int mode_now = state->kind_of_material;
|
|
if (state->kind_of_material != CODE_MATERIAL) {
|
|
if (L->category == MACRO_DEFINITION_LCAT)
|
|
state->kind_of_material = MACRO_MATERIAL;
|
|
else if ((L->category == BEGIN_DEFINITION_LCAT) ||
|
|
(L->category == CONT_DEFINITION_LCAT))
|
|
state->kind_of_material = DEFINITION_MATERIAL;
|
|
else if ((state->kind_of_material == DEFINITION_MATERIAL) &&
|
|
((L->category == CODE_BODY_LCAT) || (L->category == COMMENT_BODY_LCAT)) &&
|
|
(Str__len(L->text) == 0))
|
|
state->kind_of_material = DEFINITION_MATERIAL;
|
|
else
|
|
state->kind_of_material = CODE_MATERIAL;
|
|
Formats__change_material(OUT, wv, mode_now, state->kind_of_material,
|
|
state->substantive_comment);
|
|
state->line_break_pending = FALSE;
|
|
}
|
|
|
|
}
|
|
#line 351 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 409 "inweb/Chapter 3/The Weaver.w"
|
|
if (state->line_break_pending) {
|
|
Formats__blank_line(OUT, wv, FALSE);
|
|
state->line_break_pending = FALSE;
|
|
}
|
|
if (Regexp__string_is_white_space(matter)) {
|
|
state->line_break_pending = TRUE;
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 352 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
int tab_stops_of_indentation = 0;
|
|
|
|
{
|
|
#line 422 "inweb/Chapter 3/The Weaver.w"
|
|
int spaces_in = 0;
|
|
while (Characters__is_space_or_tab(Str__get_first_char(matter))) {
|
|
if (Str__get_first_char(matter) == '\t') {
|
|
spaces_in = 0;
|
|
tab_stops_of_indentation++;
|
|
} else {
|
|
spaces_in++;
|
|
if (spaces_in == 4) {
|
|
tab_stops_of_indentation++;
|
|
spaces_in = 0;
|
|
}
|
|
}
|
|
Str__delete_first_character(matter);
|
|
}
|
|
|
|
}
|
|
#line 355 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
TEMPORARY_TEXT(prefatory);
|
|
TEMPORARY_TEXT(concluding_comment);
|
|
|
|
{
|
|
#line 442 "inweb/Chapter 3/The Weaver.w"
|
|
TEMPORARY_TEXT(part_before_comment);
|
|
TEMPORARY_TEXT(part_within_comment);
|
|
programming_language *pl = S->sect_language;
|
|
if (L->category == TEXT_EXTRACT_LCAT) pl = L->colour_as;
|
|
if ((pl) && (LanguageMethods__parse_comment(pl,
|
|
matter, part_before_comment, part_within_comment))) {
|
|
Str__copy(matter, part_before_comment);
|
|
Str__copy(concluding_comment, part_within_comment);
|
|
}
|
|
DISCARD_TEXT(part_before_comment);
|
|
DISCARD_TEXT(part_within_comment);
|
|
|
|
}
|
|
#line 359 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 457 "inweb/Chapter 3/The Weaver.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if ((Regexp__match(&mr, matter, L"@d (%c*)")) || (Regexp__match(&mr, matter, L"@define (%c*)"))) {
|
|
Str__copy(prefatory, TL_IS_171);
|
|
Str__copy(matter, mr.exp[0]);
|
|
} else if ((Regexp__match(&mr, matter, L"@e (%c*)")) || (Regexp__match(&mr, matter, L"@enum (%c*)"))) {
|
|
Str__copy(prefatory, TL_IS_172);
|
|
Str__copy(matter, mr.exp[0]);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 360 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
if (LanguageMethods__weave_code_line(OUT, S->sect_language, wv,
|
|
W, C, S, L, matter, concluding_comment)) continue;
|
|
|
|
TEMPORARY_TEXT(colouring);
|
|
LanguageMethods__syntax_colour(OUT, S->sect_language, wv, W, C, S, L, matter, colouring);
|
|
|
|
int found = 0;
|
|
|
|
{
|
|
#line 468 "inweb/Chapter 3/The Weaver.w"
|
|
match_results mr = Regexp__create_mr();
|
|
while (Regexp__match(&mr, matter, L"(%c*?)%@%<(%c*?)%@%>(%c*)")) {
|
|
Str__copy(matter, mr.exp[2]);
|
|
para_macro *pmac = Macros__find_by_name(mr.exp[1], S);
|
|
Formats__source_code(OUT, wv, tab_stops_of_indentation, prefatory,
|
|
mr.exp[0], colouring, concluding_comment, (found == 0)?TRUE:FALSE, FALSE, TRUE);
|
|
LanguageMethods__reset_syntax_colouring(S->sect_language);
|
|
found++;
|
|
int defn = (L->owning_paragraph == pmac->defining_paragraph)?TRUE:FALSE;
|
|
if (defn) state->in_run_of_definitions = FALSE;
|
|
Formats__para_macro(OUT, wv, pmac, defn);
|
|
if (defn) Str__clear(matter);
|
|
TEMPORARY_TEXT(temp);
|
|
int L = Str__len(colouring);
|
|
for (int i = L - Str__len(matter); i < L; i++)
|
|
PUT_TO(temp, Str__get_at(colouring, i));
|
|
Str__copy(colouring, temp);
|
|
DISCARD_TEXT(temp);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 369 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
if (Str__len(prefatory) > 0) {
|
|
state->in_run_of_definitions = TRUE;
|
|
} else {
|
|
if (state->in_run_of_definitions) Formats__after_definitions(OUT, wv);
|
|
state->in_run_of_definitions = FALSE;
|
|
}
|
|
Formats__source_code(OUT, wv, tab_stops_of_indentation, prefatory,
|
|
matter, colouring, concluding_comment, (found == 0)?TRUE:FALSE, TRUE, TRUE);
|
|
DISCARD_TEXT(colouring);
|
|
DISCARD_TEXT(concluding_comment);
|
|
DISCARD_TEXT(prefatory);
|
|
continue;
|
|
|
|
}
|
|
#line 143 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
DISCARD_TEXT(matter);
|
|
|
|
}
|
|
#line 119 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
}
|
|
}
|
|
source_line *L = NULL;
|
|
|
|
{
|
|
#line 643 "inweb/Chapter 3/The Weaver.w"
|
|
int mode_now = state->kind_of_material;
|
|
if (state->kind_of_material != REGULAR_MATERIAL) {
|
|
state->kind_of_material = REGULAR_MATERIAL;
|
|
Formats__change_material(OUT, wv, mode_now, state->kind_of_material, TRUE);
|
|
}
|
|
if ((current_paragraph) && (current_paragraph != state->last_endnoted_para)) {
|
|
state->last_endnoted_para = current_paragraph;
|
|
Weaver__show_endnotes_on_previous_paragraph(OUT, wv, current_paragraph);
|
|
}
|
|
if (L) current_paragraph = L->owning_paragraph;
|
|
|
|
}
|
|
#line 123 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
}
|
|
#line 60 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 27 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
if ((Str__len(wv->cover_sheet_to_use) > 0) && (Reader__web_has_one_section(W) == FALSE))
|
|
|
|
{
|
|
#line 65 "inweb/Chapter 3/The Weaver.w"
|
|
if (!(Bibliographic__data_exists(W->md, TL_IS_164)))
|
|
Bibliographic__set_datum(W->md, TL_IS_165, wv->booklet_title);
|
|
Indexer__cover_sheet_maker(OUT, W, wv->cover_sheet_to_use, wv, WEAVE_SECOND_HALF);
|
|
|
|
}
|
|
#line 29 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
{
|
|
#line 70 "inweb/Chapter 3/The Weaver.w"
|
|
TEMPORARY_TEXT(rennab);
|
|
WRITE_TO(rennab, "End of weave");
|
|
Formats__tail(OUT, wv, rennab, latest_section);
|
|
DISCARD_TEXT(rennab);
|
|
|
|
}
|
|
#line 30 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
|
|
STREAM_CLOSE(OUT);
|
|
return lines_woven;
|
|
}
|
|
|
|
#line 82 "inweb/Chapter 3/The Weaver.w"
|
|
|
|
#line 97 "inweb/Chapter 3/The Weaver.w"
|
|
|
|
#line 659 "inweb/Chapter 3/The Weaver.w"
|
|
void Weaver__show_endnotes_on_previous_paragraph(OUTPUT_STREAM, weave_target *wv, paragraph *P) {
|
|
Tags__show_endnote_on_ifdefs(OUT, wv, P);
|
|
if (P->defines_macro)
|
|
|
|
{
|
|
#line 672 "inweb/Chapter 3/The Weaver.w"
|
|
Formats__endnote(OUT, wv, 1);
|
|
Formats__text(OUT, wv, TL_IS_184);
|
|
int ct = 0;
|
|
macro_usage *mu;
|
|
LOOP_OVER_LINKED_LIST(mu, macro_usage, P->defines_macro->macro_usages)
|
|
ct++;
|
|
if (ct == 1) Formats__text(OUT, wv, TL_IS_185);
|
|
else {
|
|
int k = 0, used_flag = FALSE;
|
|
LOOP_OVER_LINKED_LIST(mu, macro_usage, P->defines_macro->macro_usages)
|
|
if (P != mu->used_in_paragraph) {
|
|
if (used_flag) {
|
|
if (k < ct-1) Formats__text(OUT, wv, TL_IS_186);
|
|
else Formats__text(OUT, wv, TL_IS_187);
|
|
} else {
|
|
Formats__text(OUT, wv, TL_IS_188);
|
|
}
|
|
Formats__locale(OUT, wv, mu->used_in_paragraph, NULL);
|
|
used_flag = TRUE; k++;
|
|
switch (mu->multiplicity) {
|
|
case 1: break;
|
|
case 2: Formats__text(OUT, wv, TL_IS_189); break;
|
|
case 3: Formats__text(OUT, wv, TL_IS_190); break;
|
|
case 4: Formats__text(OUT, wv, TL_IS_191); break;
|
|
case 5: Formats__text(OUT, wv, TL_IS_192); break;
|
|
default: {
|
|
TEMPORARY_TEXT(mt);
|
|
WRITE_TO(mt, " (%d times)", mu->multiplicity);
|
|
Formats__text(OUT, wv, mt);
|
|
DISCARD_TEXT(mt);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Formats__text(OUT, wv, TL_IS_193);
|
|
Formats__endnote(OUT, wv, 2);
|
|
|
|
}
|
|
#line 662 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
function *fn;
|
|
LOOP_OVER_LINKED_LIST(fn, function, P->functions)
|
|
|
|
{
|
|
#line 711 "inweb/Chapter 3/The Weaver.w"
|
|
Formats__endnote(OUT, wv, 1);
|
|
hash_table_entry *hte =
|
|
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
|
|
fn->function_name, FALSE);
|
|
Formats__text(OUT, wv, TL_IS_194);
|
|
Formats__text(OUT, wv, fn->function_name);
|
|
int used_flag = FALSE;
|
|
hash_table_entry_usage *hteu = NULL;
|
|
section *last_cited_in = NULL;
|
|
int count_under = 0;
|
|
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
|
|
if ((P != hteu->usage_recorded_at) &&
|
|
(P->under_section == hteu->usage_recorded_at->under_section))
|
|
|
|
{
|
|
#line 735 "inweb/Chapter 3/The Weaver.w"
|
|
if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_198);
|
|
used_flag = TRUE;
|
|
section *S = hteu->usage_recorded_at->under_section;
|
|
if ((S != last_cited_in) && (S != P->under_section)) {
|
|
count_under = 0;
|
|
if (last_cited_in) {
|
|
if (last_cited_in != P->under_section) Formats__text(OUT, wv, TL_IS_199);
|
|
else Formats__text(OUT, wv, TL_IS_200);
|
|
}
|
|
Formats__text(OUT, wv, hteu->usage_recorded_at->under_section->sect_range);
|
|
Formats__text(OUT, wv, TL_IS_201);
|
|
}
|
|
if (count_under++ > 0) Formats__text(OUT, wv, TL_IS_202);
|
|
Formats__locale(OUT, wv, hteu->usage_recorded_at, NULL);
|
|
last_cited_in = hteu->usage_recorded_at->under_section;
|
|
|
|
}
|
|
#line 724 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
|
|
if (P->under_section != hteu->usage_recorded_at->under_section)
|
|
|
|
{
|
|
#line 735 "inweb/Chapter 3/The Weaver.w"
|
|
if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_198);
|
|
used_flag = TRUE;
|
|
section *S = hteu->usage_recorded_at->under_section;
|
|
if ((S != last_cited_in) && (S != P->under_section)) {
|
|
count_under = 0;
|
|
if (last_cited_in) {
|
|
if (last_cited_in != P->under_section) Formats__text(OUT, wv, TL_IS_199);
|
|
else Formats__text(OUT, wv, TL_IS_200);
|
|
}
|
|
Formats__text(OUT, wv, hteu->usage_recorded_at->under_section->sect_range);
|
|
Formats__text(OUT, wv, TL_IS_201);
|
|
}
|
|
if (count_under++ > 0) Formats__text(OUT, wv, TL_IS_202);
|
|
Formats__locale(OUT, wv, hteu->usage_recorded_at, NULL);
|
|
last_cited_in = hteu->usage_recorded_at->under_section;
|
|
|
|
}
|
|
#line 727 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
if (used_flag == FALSE) Formats__text(OUT, wv, TL_IS_195);
|
|
if ((last_cited_in != P->under_section) && (last_cited_in))
|
|
Formats__text(OUT, wv, TL_IS_196);
|
|
Formats__text(OUT, wv, TL_IS_197);
|
|
Formats__endnote(OUT, wv, 2);
|
|
|
|
}
|
|
#line 665 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
c_structure *st;
|
|
LOOP_OVER_LINKED_LIST(st, c_structure, P->structures)
|
|
|
|
{
|
|
#line 752 "inweb/Chapter 3/The Weaver.w"
|
|
Formats__endnote(OUT, wv, 1);
|
|
Formats__text(OUT, wv, TL_IS_203);
|
|
Formats__text(OUT, wv, st->structure_name);
|
|
|
|
section *S;
|
|
LOOP_OVER(S, section) S->scratch_flag = FALSE;
|
|
structure_element *elt;
|
|
LOOP_OVER_LINKED_LIST(elt, structure_element, st->elements) {
|
|
hash_table_entry *hte =
|
|
Analyser__find_hash_entry_for_section(elt->element_created_at->owning_section,
|
|
elt->element_name, FALSE);
|
|
if (hte) {
|
|
hash_table_entry_usage *hteu;
|
|
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
|
|
if (hteu->form_of_usage & ELEMENT_ACCESS_USAGE)
|
|
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
|
|
}
|
|
}
|
|
|
|
int usage_count = 0, external = 0;
|
|
LOOP_OVER(S, section)
|
|
if (S->scratch_flag) {
|
|
usage_count++;
|
|
if (S != P->under_section) external++;
|
|
}
|
|
if (external == 0) Formats__text(OUT, wv, TL_IS_204);
|
|
else {
|
|
Formats__text(OUT, wv, TL_IS_205);
|
|
int c = 0;
|
|
LOOP_OVER(S, section)
|
|
if ((S->scratch_flag) && (S != P->under_section)) {
|
|
if (c++ > 0) Formats__text(OUT, wv, TL_IS_206);
|
|
Formats__text(OUT, wv, S->sect_range);
|
|
}
|
|
if (P->under_section->scratch_flag) Formats__text(OUT, wv, TL_IS_207);
|
|
}
|
|
Formats__text(OUT, wv, TL_IS_208);
|
|
Formats__endnote(OUT, wv, 2);
|
|
|
|
}
|
|
#line 668 "inweb/Chapter 3/The Weaver.w"
|
|
;
|
|
}
|
|
|
|
#line 796 "inweb/Chapter 3/The Weaver.w"
|
|
int Weaver__weave_table_of_contents(OUTPUT_STREAM, weave_target *wv, section *S) {
|
|
int noteworthy = 0;
|
|
paragraph *P;
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
if ((P->weight > 0) && ((S->barred == FALSE) || (P->above_bar == FALSE)))
|
|
noteworthy++;
|
|
if (noteworthy == 0) return FALSE;
|
|
|
|
Formats__toc(OUT, wv, 1, S->sect_range, TL_IS_209, NULL);
|
|
noteworthy = 0;
|
|
LOOP_OVER_LINKED_LIST(P, paragraph, S->paragraphs)
|
|
if ((P->weight > 0) && ((S->barred == FALSE) || (P->above_bar == FALSE))) {
|
|
if (noteworthy > 0) Formats__toc(OUT, wv, 2, TL_IS_210, TL_IS_211, NULL);
|
|
TEMPORARY_TEXT(loc);
|
|
WRITE_TO(loc, "%S%S", P->ornament, P->paragraph_number);
|
|
Formats__toc(OUT, wv, 3, loc, P->first_line_in_paragraph->text_operand, P);
|
|
DISCARD_TEXT(loc);
|
|
noteworthy++;
|
|
}
|
|
Formats__toc(OUT, wv, 4, TL_IS_212, TL_IS_213, NULL);
|
|
return TRUE;
|
|
}
|
|
|
|
#line 14 "inweb/Chapter 3/The Tangler.w"
|
|
void Tangler__go(web *W, tangle_target *target, filename *dest_file) {
|
|
programming_language *lang = target->tangle_language;
|
|
PRINT(" tangling <%/f> (written in %S)\n", dest_file, lang->language_name);
|
|
|
|
text_stream TO_struct;
|
|
text_stream *OUT = &TO_struct;
|
|
if (STREAM_OPEN_TO_FILE(OUT, dest_file, ISO_ENC) == FALSE)
|
|
Errors__fatal_with_file("unable to write tangled file", dest_file);
|
|
|
|
{
|
|
#line 39 "inweb/Chapter 3/The Tangler.w"
|
|
/* (a) The shebang line, a header for scripting languages, and other heading matter */
|
|
LanguageMethods__shebang(OUT, lang, W, target);
|
|
LanguageMethods__disclaimer(OUT, lang, W, target);
|
|
LanguageMethods__additional_early_matter(OUT, lang, W, target);
|
|
chapter *C; section *S; paragraph *P;
|
|
LOOP_OVER_PARAGRAPHS(C, S, target, P)
|
|
if ((P->placed_very_early) && (P->defines_macro == NULL))
|
|
Tangler__tangle_paragraph(OUT, P);
|
|
|
|
/* (b) Results of |@d| declarations */
|
|
|
|
{
|
|
#line 71 "inweb/Chapter 3/The Tangler.w"
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, target)
|
|
if (L->category == BEGIN_DEFINITION_LCAT)
|
|
if (L->default_defn == FALSE)
|
|
|
|
{
|
|
#line 87 "inweb/Chapter 3/The Tangler.w"
|
|
if (L->owning_paragraph == NULL) Main__error_in_web(TL_IS_214, L);
|
|
else Tags__open_ifdefs(OUT, L->owning_paragraph);
|
|
LanguageMethods__start_definition(OUT, lang,
|
|
L->text_operand,
|
|
L->text_operand2, S, L);
|
|
while ((L->next_line) && (L->next_line->category == CONT_DEFINITION_LCAT)) {
|
|
L = L->next_line;
|
|
LanguageMethods__prolong_definition(OUT, lang, L->text, S, L);
|
|
}
|
|
LanguageMethods__end_definition(OUT, lang, S, L);
|
|
if (L->owning_paragraph) Tags__close_ifdefs(OUT, L->owning_paragraph);
|
|
|
|
}
|
|
#line 76 "inweb/Chapter 3/The Tangler.w"
|
|
;
|
|
LOOP_WITHIN_TANGLE(C, S, target)
|
|
if (L->category == BEGIN_DEFINITION_LCAT)
|
|
if (L->default_defn) {
|
|
LanguageMethods__open_ifdef(OUT, lang, L->text_operand, FALSE);
|
|
|
|
{
|
|
#line 87 "inweb/Chapter 3/The Tangler.w"
|
|
if (L->owning_paragraph == NULL) Main__error_in_web(TL_IS_214, L);
|
|
else Tags__open_ifdefs(OUT, L->owning_paragraph);
|
|
LanguageMethods__start_definition(OUT, lang,
|
|
L->text_operand,
|
|
L->text_operand2, S, L);
|
|
while ((L->next_line) && (L->next_line->category == CONT_DEFINITION_LCAT)) {
|
|
L = L->next_line;
|
|
LanguageMethods__prolong_definition(OUT, lang, L->text, S, L);
|
|
}
|
|
LanguageMethods__end_definition(OUT, lang, S, L);
|
|
if (L->owning_paragraph) Tags__close_ifdefs(OUT, L->owning_paragraph);
|
|
|
|
}
|
|
#line 81 "inweb/Chapter 3/The Tangler.w"
|
|
;
|
|
LanguageMethods__close_ifdef(OUT, lang, L->text_operand, FALSE);
|
|
}
|
|
Enumerations__define_extents(OUT, target, lang);
|
|
|
|
}
|
|
#line 49 "inweb/Chapter 3/The Tangler.w"
|
|
;
|
|
|
|
/* (c) Miscellaneous automated C predeclarations */
|
|
LanguageMethods__additional_predeclarations(OUT, lang, W);
|
|
|
|
/* (d) Above-the-bar code from all of the sections (global variables, and such) */
|
|
LOOP_OVER_PARAGRAPHS(C, S, target, P)
|
|
if ((P->placed_early) && (P->defines_macro == NULL))
|
|
Tangler__tangle_paragraph(OUT, P);
|
|
|
|
/* (e) Below-the-bar code: the bulk of the program itself */
|
|
LOOP_OVER_PARAGRAPHS(C, S, target, P)
|
|
if ((P->placed_early == FALSE) && (P->placed_very_early == FALSE) && (P->defines_macro == NULL))
|
|
Tangler__tangle_paragraph(OUT, P);
|
|
|
|
/* (f) Opposite of the shebang: a footer */
|
|
LanguageMethods__gnabehs(OUT, lang, W);
|
|
|
|
}
|
|
#line 22 "inweb/Chapter 3/The Tangler.w"
|
|
;
|
|
STREAM_CLOSE(OUT);
|
|
|
|
|
|
{
|
|
#line 100 "inweb/Chapter 3/The Tangler.w"
|
|
filename *F;
|
|
LOOP_OVER_LINKED_LIST(F, filename, W->headers)
|
|
Shell__copy(F, Reader__tangled_folder(W), "");
|
|
|
|
}
|
|
#line 25 "inweb/Chapter 3/The Tangler.w"
|
|
;
|
|
LanguageMethods__additional_tangling(lang, W, target);
|
|
}
|
|
|
|
#line 109 "inweb/Chapter 3/The Tangler.w"
|
|
void Tangler__tangle_paragraph(OUTPUT_STREAM, paragraph *P) {
|
|
Tags__open_ifdefs(OUT, P);
|
|
int contiguous = FALSE;
|
|
for (source_line *L = P->first_line_in_paragraph;
|
|
((L) && (L->owning_paragraph == P)); L = L->next_line) {
|
|
if (LanguageMethods__will_insert_in_tangle(P->under_section->sect_language, L)) {
|
|
|
|
{
|
|
#line 134 "inweb/Chapter 3/The Tangler.w"
|
|
if (contiguous == FALSE) {
|
|
contiguous = TRUE;
|
|
LanguageMethods__insert_line_marker(OUT, P->under_section->sect_language, L);
|
|
}
|
|
|
|
}
|
|
#line 115 "inweb/Chapter 3/The Tangler.w"
|
|
;
|
|
LanguageMethods__insert_in_tangle(OUT, P->under_section->sect_language, L);
|
|
}
|
|
if ((L->category != CODE_BODY_LCAT) || (L->suppress_tangling)) {
|
|
contiguous = FALSE;
|
|
} else {
|
|
|
|
{
|
|
#line 134 "inweb/Chapter 3/The Tangler.w"
|
|
if (contiguous == FALSE) {
|
|
contiguous = TRUE;
|
|
LanguageMethods__insert_line_marker(OUT, P->under_section->sect_language, L);
|
|
}
|
|
|
|
}
|
|
#line 121 "inweb/Chapter 3/The Tangler.w"
|
|
;
|
|
Tangler__tangle_code(OUT, L->text, P->under_section, L); WRITE("\n");
|
|
}
|
|
}
|
|
Tags__close_ifdefs(OUT, P);
|
|
}
|
|
|
|
#line 144 "inweb/Chapter 3/The Tangler.w"
|
|
void Tangler__tangle_code(OUTPUT_STREAM, text_stream *original, section *S, source_line *L) {
|
|
int mlen, slen;
|
|
int mpos = Regexp__find_expansion(original, '@', '<', '@', '>', &mlen);
|
|
int spos = Regexp__find_expansion(original, '[', '[', ']', ']', &slen);
|
|
if ((mpos >= 0) && ((spos == -1) || (mpos <= spos)) &&
|
|
(LanguageMethods__allow_expansion(S->sect_language, original)))
|
|
|
|
{
|
|
#line 176 "inweb/Chapter 3/The Tangler.w"
|
|
TEMPORARY_TEXT(temp);
|
|
Str__copy(temp, original); Str__truncate(temp, mpos);
|
|
LanguageMethods__tangle_code(OUT, S->sect_language, temp);
|
|
|
|
programming_language *lang = S->sect_language;
|
|
for (int i=0; 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_215, L);
|
|
WRITE_TO(STDERR, "Macro is '%S'\n", temp);
|
|
LanguageMethods__comment(OUT, lang, temp); /* recover by putting macro name in comment */
|
|
}
|
|
TEMPORARY_TEXT(rest);
|
|
Str__substr(rest, Str__at(original, mpos + mlen), Str__end(original));
|
|
Tangler__tangle_code(OUT, rest, S, L);
|
|
DISCARD_TEXT(rest);
|
|
DISCARD_TEXT(temp);
|
|
|
|
}
|
|
#line 150 "inweb/Chapter 3/The Tangler.w"
|
|
|
|
else if (spos >= 0)
|
|
|
|
{
|
|
#line 216 "inweb/Chapter 3/The Tangler.w"
|
|
web *W = S->owning_web;
|
|
|
|
TEMPORARY_TEXT(temp);
|
|
for (int i=0; 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) {
|
|
programming_language *pl;
|
|
|
|
{
|
|
#line 21 "inweb/Chapter 4/Programming Languages.w"
|
|
LOOP_OVER(pl, programming_language)
|
|
if (Str__eq(lname, pl->language_name))
|
|
return pl;
|
|
|
|
}
|
|
#line 12 "inweb/Chapter 4/Programming Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 26 "inweb/Chapter 4/Programming Languages.w"
|
|
pathname *P = Languages__default_directory();
|
|
TEMPORARY_TEXT(leaf);
|
|
WRITE_TO(leaf, "%S.ildf", lname);
|
|
filename *F = Filenames__in_folder(P, leaf);
|
|
DISCARD_TEXT(leaf);
|
|
if (TextFiles__exists(F) == FALSE)
|
|
Errors__fatal_with_text(
|
|
"unsupported programming language '%S'", lname);
|
|
pl = Languages__read_definition(F);
|
|
|
|
}
|
|
#line 13 "inweb/Chapter 4/Programming Languages.w"
|
|
;
|
|
if (Str__ne(pl->language_name, lname))
|
|
Errors__fatal_with_text(
|
|
"definition of programming language '%S' is for something else", lname);
|
|
return pl;
|
|
}
|
|
|
|
#line 39 "inweb/Chapter 4/Programming Languages.w"
|
|
programming_language *Languages__default(void) {
|
|
return Languages__find_by_name(TL_IS_216);
|
|
}
|
|
|
|
void Languages__show(OUTPUT_STREAM) {
|
|
WRITE("Inweb can see the following programming language definitions:\n\n");
|
|
programming_language *pl;
|
|
LOOP_OVER(pl, programming_language)
|
|
WRITE("%S: %S\n", pl->language_name, pl->language_details);
|
|
}
|
|
|
|
#line 53 "inweb/Chapter 4/Programming Languages.w"
|
|
void Languages__read_definitions(pathname *P) {
|
|
if (P == NULL) P = Languages__default_directory();
|
|
scan_directory *D = Directories__open(P);
|
|
TEMPORARY_TEXT(leafname);
|
|
while (Directories__next(D, leafname)) {
|
|
if (Str__get_last_char(leafname) != FOLDER_SEPARATOR) {
|
|
filename *F = Filenames__in_folder(P, leafname);
|
|
Languages__read_definition(F);
|
|
}
|
|
}
|
|
DISCARD_TEXT(leafname);
|
|
Directories__close(D);
|
|
}
|
|
|
|
pathname *Languages__default_directory(void) {
|
|
return Pathnames__subfolder(path_to_inweb, TL_IS_217);
|
|
}
|
|
|
|
#line 114 "inweb/Chapter 4/Programming Languages.w"
|
|
|
|
#line 126 "inweb/Chapter 4/Programming Languages.w"
|
|
|
|
programming_language *Languages__read_definition(filename *F) {
|
|
programming_language *pl = CREATE(programming_language);
|
|
|
|
{
|
|
#line 140 "inweb/Chapter 4/Programming Languages.w"
|
|
pl->language_name = NULL;
|
|
pl->file_extension = NULL;
|
|
pl->supports_namespaces = FALSE;
|
|
pl->line_comment = NULL;
|
|
pl->whole_line_comment = NULL;
|
|
pl->multiline_comment_open = NULL;
|
|
pl->multiline_comment_close = NULL;
|
|
pl->string_literal = NULL;
|
|
pl->string_literal_escape = NULL;
|
|
pl->character_literal = NULL;
|
|
pl->character_literal_escape = NULL;
|
|
pl->binary_literal_prefix = NULL;
|
|
pl->octal_literal_prefix = NULL;
|
|
pl->hexadecimal_literal_prefix = NULL;
|
|
pl->negative_literal_prefix = NULL;
|
|
pl->shebang = NULL;
|
|
pl->line_marker = NULL;
|
|
pl->before_macro_expansion = NULL;
|
|
pl->after_macro_expansion = NULL;
|
|
pl->start_definition = NULL;
|
|
pl->prolong_definition = NULL;
|
|
pl->end_definition = NULL;
|
|
pl->start_ifdef = NULL;
|
|
pl->end_ifdef = NULL;
|
|
pl->start_ifndef = NULL;
|
|
pl->end_ifndef = NULL;
|
|
pl->C_like = FALSE;
|
|
pl->suppress_disclaimer = FALSE;
|
|
|
|
pl->reserved_words = NEW_LINKED_LIST(reserved_word);
|
|
pl->built_in_keywords.analysis_hash_initialised = FALSE;
|
|
pl->program = NULL;
|
|
pl->methods = Methods__new_set();
|
|
|
|
}
|
|
#line 129 "inweb/Chapter 4/Programming Languages.w"
|
|
;
|
|
language_reader_state lrs;
|
|
lrs.defining = pl;
|
|
lrs.current_block = NULL;
|
|
TextFiles__read(F, FALSE, "can't open programming language definition file",
|
|
TRUE, Languages__read_definition_line, NULL, (void *) &lrs);
|
|
|
|
{
|
|
#line 183 "inweb/Chapter 4/Programming Languages.w"
|
|
if (pl->C_like) CLike__make_c_like(pl);
|
|
if (Str__eq(pl->language_name, TL_IS_218)) InCSupport__add_features(pl);
|
|
ACMESupport__add_fallbacks(pl);
|
|
|
|
}
|
|
#line 135 "inweb/Chapter 4/Programming Languages.w"
|
|
;
|
|
return pl;
|
|
}
|
|
|
|
#line 190 "inweb/Chapter 4/Programming Languages.w"
|
|
void Languages__read_definition_line(text_stream *line, text_file_position *tfp, void *v_state) {
|
|
language_reader_state *state = (language_reader_state *) v_state;
|
|
programming_language *pl = state->defining;
|
|
|
|
Str__trim_white_space(line); /* ignore trailing space */
|
|
if (Str__len(line) == 0) return; /* ignore blank lines */
|
|
if (Str__get_first_char(line) == '#') return; /* lines opening with |#| are comments */
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (state->current_block)
|
|
{
|
|
#line 287 "inweb/Chapter 4/Programming Languages.w"
|
|
if (Str__eq(line, TL_IS_248)) {
|
|
state->current_block = state->current_block->parent;
|
|
} else if (Regexp__match(&mr, line, L"characters {")) {
|
|
colouring_rule *rule = Languages__new_rule(state->current_block);
|
|
rule->execute_block =
|
|
Languages__new_block(state->current_block, CHARACTERS_CRULE_RUN);
|
|
state->current_block = rule->execute_block;
|
|
} else if (Regexp__match(&mr, line, L"runs of (%c+) {")) {
|
|
colouring_rule *rule = Languages__new_rule(state->current_block);
|
|
int r = UNQUOTED_COLOUR;
|
|
if (Str__ne(mr.exp[0], TL_IS_249)) r = Languages__colour(mr.exp[0], tfp);
|
|
rule->execute_block = Languages__new_block(state->current_block, r);
|
|
state->current_block = rule->execute_block;
|
|
} else if (Regexp__match(&mr, line, L"instances of (%c+) {")) {
|
|
colouring_rule *rule = Languages__new_rule(state->current_block);
|
|
rule->execute_block = Languages__new_block(state->current_block, INSTANCES_CRULE_RUN);
|
|
rule->execute_block->run_instance = Languages__text(mr.exp[0], tfp);
|
|
state->current_block = rule->execute_block;
|
|
} else {
|
|
int at = -1, quoted = FALSE;
|
|
for (int i=0; i<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 199 "inweb/Chapter 4/Programming Languages.w"
|
|
|
|
else
|
|
{
|
|
#line 208 "inweb/Chapter 4/Programming Languages.w"
|
|
if (Regexp__match(&mr, line, L"colouring {")) {
|
|
if (pl->program) Errors__in_text_file("duplicate colouring program", tfp);
|
|
pl->program = Languages__new_block(NULL, WHOLE_LINE_CRULE_RUN);
|
|
state->current_block = pl->program;
|
|
} else if (Regexp__match(&mr, line, L"keyword (%C+) of (%c+?)")) {
|
|
Languages__reserved(pl, mr.exp[0], Languages__colour(mr.exp[1], tfp), tfp);
|
|
} else if (Regexp__match(&mr, line, L"keyword (%C+)")) {
|
|
Languages__reserved(pl, mr.exp[0], RESERVED_COLOUR, tfp);
|
|
} else if (Regexp__match(&mr, line, L"(%c+) *: *(%c+?)")) {
|
|
text_stream *key = mr.exp[0], *value = Str__duplicate(mr.exp[1]);
|
|
if (Str__eq(key, TL_IS_219)) pl->language_name = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_220))
|
|
pl->language_details = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_221))
|
|
pl->file_extension = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_222))
|
|
pl->line_comment = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_223))
|
|
pl->whole_line_comment = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_224))
|
|
pl->multiline_comment_open = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_225))
|
|
pl->multiline_comment_close = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_226))
|
|
pl->string_literal = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_227))
|
|
pl->string_literal_escape = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_228))
|
|
pl->character_literal = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_229))
|
|
pl->character_literal_escape = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_230))
|
|
pl->binary_literal_prefix = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_231))
|
|
pl->octal_literal_prefix = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_232))
|
|
pl->hexadecimal_literal_prefix = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_233))
|
|
pl->negative_literal_prefix = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_234))
|
|
pl->shebang = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_235))
|
|
pl->line_marker = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_236))
|
|
pl->before_macro_expansion = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_237))
|
|
pl->after_macro_expansion = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_238))
|
|
pl->start_definition = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_239))
|
|
pl->prolong_definition = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_240))
|
|
pl->end_definition = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_241))
|
|
pl->start_ifdef = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_242))
|
|
pl->start_ifndef = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_243))
|
|
pl->end_ifdef = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_244))
|
|
pl->end_ifndef = Languages__text(value, tfp);
|
|
else if (Str__eq(key, TL_IS_245))
|
|
pl->C_like = Languages__boolean(value, tfp);
|
|
else if (Str__eq(key, TL_IS_246))
|
|
pl->suppress_disclaimer = Languages__boolean(value, tfp);
|
|
else if (Str__eq(key, TL_IS_247))
|
|
pl->supports_namespaces = Languages__boolean(value, tfp);
|
|
else {
|
|
Errors__in_text_file("unknown property name before ':'", tfp);
|
|
}
|
|
} else {
|
|
Errors__in_text_file("line in language definition illegible", tfp);
|
|
}
|
|
|
|
}
|
|
#line 200 "inweb/Chapter 4/Programming Languages.w"
|
|
;
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 342 "inweb/Chapter 4/Programming Languages.w"
|
|
|
|
#line 344 "inweb/Chapter 4/Programming Languages.w"
|
|
colouring_language_block *Languages__new_block(colouring_language_block *within, int r) {
|
|
colouring_language_block *block = CREATE(colouring_language_block);
|
|
block->rules = NEW_LINKED_LIST(colouring_rule);
|
|
block->parent = within;
|
|
block->run = r;
|
|
block->run_instance = NULL;
|
|
return block;
|
|
}
|
|
|
|
#line 386 "inweb/Chapter 4/Programming Languages.w"
|
|
|
|
#line 388 "inweb/Chapter 4/Programming Languages.w"
|
|
colouring_rule *Languages__new_rule(colouring_language_block *within) {
|
|
if (within == NULL) internal_error("rule outside block");
|
|
colouring_rule *rule = CREATE(colouring_rule);
|
|
ADD_TO_LINKED_LIST(rule, colouring_rule, within->rules);
|
|
rule->match_colour = NOT_A_COLOUR;
|
|
rule->match_text = NULL;
|
|
rule->match_prefix = NOT_A_RULE_PREFIX;
|
|
rule->match_keyword_of_colour = NOT_A_COLOUR;
|
|
|
|
rule->set_to_colour = NOT_A_COLOUR;
|
|
rule->set_prefix_to_colour = NOT_A_COLOUR;
|
|
rule->execute_block = NULL;
|
|
rule->debug = FALSE;
|
|
return rule;
|
|
}
|
|
|
|
#line 405 "inweb/Chapter 4/Programming Languages.w"
|
|
void Languages__parse_rule(language_reader_state *state, text_stream *premiss,
|
|
text_stream *action, text_file_position *tfp) {
|
|
match_results mr = Regexp__create_mr();
|
|
colouring_rule *rule = Languages__new_rule(state->current_block);
|
|
Str__trim_white_space(premiss); Str__trim_white_space(action);
|
|
|
|
{
|
|
#line 416 "inweb/Chapter 4/Programming Languages.w"
|
|
if (Regexp__match(&mr, premiss, L"keyword of (%c+)")) {
|
|
PRINT("Keyw of %S\n", mr.exp[0]);
|
|
rule->match_keyword_of_colour = Languages__colour(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"keyword")) {
|
|
Errors__in_text_file("ambiguous: make it keyword of !reserved or \"keyword\"", tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"prefix (%c+)")) {
|
|
rule->match_prefix = UNSPACED_RULE_PREFIX;
|
|
rule->match_text = Languages__text(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"spaced prefix (%c+)")) {
|
|
rule->match_prefix = SPACED_RULE_PREFIX;
|
|
rule->match_text = Languages__text(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"optionally spaced prefix (%c+)")) {
|
|
rule->match_prefix = OPTIONALLY_SPACED_RULE_PREFIX;
|
|
rule->match_text = Languages__text(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"suffix (%c+)")) {
|
|
rule->match_prefix = UNSPACED_RULE_SUFFIX;
|
|
rule->match_text = Languages__text(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"spaced suffix (%c+)")) {
|
|
rule->match_prefix = SPACED_RULE_SUFFIX;
|
|
rule->match_text = Languages__text(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"optionally spaced suffix (%c+)")) {
|
|
rule->match_prefix = OPTIONALLY_SPACED_RULE_SUFFIX;
|
|
rule->match_text = Languages__text(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, premiss, L"colou*r (%c+)")) {
|
|
rule->match_colour = Languages__colour(mr.exp[0], tfp);
|
|
} else if (Str__len(premiss) > 0) {
|
|
rule->match_text = Languages__text(premiss, tfp);
|
|
}
|
|
|
|
}
|
|
#line 410 "inweb/Chapter 4/Programming Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 446 "inweb/Chapter 4/Programming Languages.w"
|
|
if (Str__eq(action, TL_IS_250)) {
|
|
rule->execute_block =
|
|
Languages__new_block(state->current_block, WHOLE_LINE_CRULE_RUN);
|
|
state->current_block = rule->execute_block;
|
|
} else if (Regexp__match(&mr, action, L"(!%c+) on prefix")) {
|
|
rule->set_prefix_to_colour = Languages__colour(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, action, L"(!%c+) on suffix")) {
|
|
rule->set_prefix_to_colour = Languages__colour(mr.exp[0], tfp);
|
|
} else if (Regexp__match(&mr, action, L"(!%c+) on both")) {
|
|
rule->set_to_colour = Languages__colour(mr.exp[0], tfp);
|
|
rule->set_prefix_to_colour = rule->set_to_colour;
|
|
} else if (Str__get_first_char(action) == '!') {
|
|
rule->set_to_colour = Languages__colour(action, tfp);
|
|
} else if (Str__eq(action, TL_IS_251)) {
|
|
rule->debug = TRUE;
|
|
} else {
|
|
Errors__in_text_file("action after '=>' illegible", tfp);
|
|
}
|
|
|
|
}
|
|
#line 411 "inweb/Chapter 4/Programming Languages.w"
|
|
;
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 474 "inweb/Chapter 4/Programming Languages.w"
|
|
|
|
reserved_word *Languages__reserved(programming_language *pl, text_stream *W, int C,
|
|
text_file_position *tfp) {
|
|
reserved_word *rw;
|
|
LOOP_OVER_LINKED_LIST(rw, reserved_word, pl->reserved_words)
|
|
if (Str__eq(rw->word, W)) {
|
|
Errors__in_text_file("duplicate reserved word", tfp);
|
|
}
|
|
rw = CREATE(reserved_word);
|
|
rw->word = Str__duplicate(W);
|
|
rw->colour = C;
|
|
ADD_TO_LINKED_LIST(rw, reserved_word, pl->reserved_words);
|
|
Analyser__mark_reserved_word(&(pl->built_in_keywords), rw->word, C);
|
|
return rw;
|
|
}
|
|
|
|
#line 511 "inweb/Chapter 4/Programming Languages.w"
|
|
int Languages__colour(text_stream *T, text_file_position *tfp) {
|
|
if (Str__get_first_char(T) != '!') {
|
|
Errors__in_text_file("colour names must begin with !", tfp);
|
|
return PLAIN_COLOUR;
|
|
}
|
|
if (Str__eq(T, TL_IS_252)) return STRING_COLOUR;
|
|
else if (Str__eq(T, TL_IS_253)) return FUNCTION_COLOUR;
|
|
else if (Str__eq(T, TL_IS_254)) return DEFINITION_COLOUR;
|
|
else if (Str__eq(T, TL_IS_255)) return RESERVED_COLOUR;
|
|
else if (Str__eq(T, TL_IS_256)) return ELEMENT_COLOUR;
|
|
else if (Str__eq(T, TL_IS_257)) return IDENTIFIER_COLOUR;
|
|
else if (Str__eq(T, TL_IS_258)) return CHAR_LITERAL_COLOUR;
|
|
else if (Str__eq(T, TL_IS_259)) return CONSTANT_COLOUR;
|
|
else if (Str__eq(T, TL_IS_260)) return PLAIN_COLOUR;
|
|
else if (Str__eq(T, TL_IS_261)) return EXTRACT_COLOUR;
|
|
else if (Str__eq(T, TL_IS_262)) return COMMENT_COLOUR;
|
|
else {
|
|
Errors__in_text_file("no such !colour", tfp);
|
|
return PLAIN_COLOUR;
|
|
}
|
|
}
|
|
|
|
#line 536 "inweb/Chapter 4/Programming Languages.w"
|
|
int Languages__boolean(text_stream *T, text_file_position *tfp) {
|
|
if (Str__eq(T, TL_IS_263)) return TRUE;
|
|
else if (Str__eq(T, TL_IS_264)) return FALSE;
|
|
else {
|
|
Errors__in_text_file("must be true or false", tfp);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
#line 550 "inweb/Chapter 4/Programming Languages.w"
|
|
text_stream *Languages__text(text_stream *T, text_file_position *tfp) {
|
|
text_stream *V = Str__new();
|
|
if (Str__len(T) > 0) {
|
|
int bareword = TRUE, from = 0, to = Str__len(T)-1;
|
|
if ((to > from) &&
|
|
(Str__get_at(T, from) == '"') && (Str__get_at(T, to) == '"')) {
|
|
bareword = FALSE; from++; to--;
|
|
}
|
|
for (int i=from; i<=to; i++) {
|
|
wchar_t c = Str__get_at(T, i);
|
|
if ((c == '\\') && (Str__get_at(T, i+1) == 'n')) {
|
|
PUT_TO(V, '\n');
|
|
i++;
|
|
} else if ((c == '\\') && (Str__get_at(T, i+1) == 's')) {
|
|
PUT_TO(V, ' ');
|
|
i++;
|
|
} else if ((c == '\\') && (Str__get_at(T, i+1) == 't')) {
|
|
PUT_TO(V, '\t');
|
|
i++;
|
|
} else if ((c == '\\') && (Str__get_at(T, i+1) == '\\')) {
|
|
PUT_TO(V, '\\');
|
|
i++;
|
|
} else if ((bareword == FALSE) && (c == '\\') && (Str__get_at(T, i+1) == '"')) {
|
|
PUT_TO(V, '"');
|
|
i++;
|
|
} else if ((bareword == FALSE) && (c == '"')) {
|
|
Errors__in_text_file(
|
|
"backslash needed before internal double-quotation mark", tfp);
|
|
} else {
|
|
PUT_TO(V, c);
|
|
}
|
|
}
|
|
}
|
|
return V;
|
|
}
|
|
|
|
#line 38 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(FURTHER_PARSING_PAR_MTID, programming_language *pl, web *W)
|
|
void LanguageMethods__further_parsing(web *W, programming_language *pl) {
|
|
VMETHOD_CALL(pl, FURTHER_PARSING_PAR_MTID, W);
|
|
}
|
|
|
|
#line 49 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 51 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(SUBCATEGORISE_LINE_PAR_MTID, programming_language *pl, source_line *L)
|
|
void LanguageMethods__subcategorise_line(programming_language *pl, source_line *L) {
|
|
VMETHOD_CALL(pl, SUBCATEGORISE_LINE_PAR_MTID, L);
|
|
}
|
|
|
|
#line 62 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 64 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(PARSE_COMMENT_TAN_MTID, programming_language *pl, text_stream *line, text_stream *before, text_stream *within)
|
|
|
|
int LanguageMethods__parse_comment(programming_language *pl,
|
|
text_stream *line, text_stream *before, text_stream *within) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, PARSE_COMMENT_TAN_MTID, line, before, within);
|
|
return rv;
|
|
}
|
|
|
|
#line 82 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 84 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(SHEBANG_TAN_MTID, programming_language *pl, text_stream *OUT, web *W, tangle_target *target)
|
|
void LanguageMethods__shebang(OUTPUT_STREAM, programming_language *pl, web *W, tangle_target *target) {
|
|
VMETHOD_CALL(pl, SHEBANG_TAN_MTID, OUT, W, target);
|
|
}
|
|
|
|
#line 93 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 95 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(SUPPRESS_DISCLAIMER_TAN_MTID, programming_language *pl)
|
|
void LanguageMethods__disclaimer(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALLV(rv, pl, SUPPRESS_DISCLAIMER_TAN_MTID);
|
|
if (rv == FALSE)
|
|
LanguageMethods__comment(OUT, pl, TL_IS_265);
|
|
}
|
|
|
|
#line 107 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 109 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(ADDITIONAL_EARLY_MATTER_TAN_MTID, programming_language *pl, text_stream *OUT, web *W, tangle_target *target)
|
|
void LanguageMethods__additional_early_matter(text_stream *OUT, programming_language *pl, web *W, tangle_target *target) {
|
|
VMETHOD_CALL(pl, ADDITIONAL_EARLY_MATTER_TAN_MTID, OUT, W, target);
|
|
}
|
|
|
|
#line 123 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 125 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(START_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *term, text_stream *start, section *S, source_line *L)
|
|
IMETHOD_TYPE(PROLONG_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *more, section *S, source_line *L)
|
|
IMETHOD_TYPE(END_DEFN_TAN_MTID, programming_language *pl, text_stream *OUT, section *S, source_line *L)
|
|
|
|
void LanguageMethods__start_definition(OUTPUT_STREAM, programming_language *pl,
|
|
text_stream *term, text_stream *start, section *S, source_line *L) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, START_DEFN_TAN_MTID, OUT, term, start, S, L);
|
|
if (rv == FALSE)
|
|
Main__error_in_web(TL_IS_266, L);
|
|
}
|
|
|
|
void LanguageMethods__prolong_definition(OUTPUT_STREAM, programming_language *pl,
|
|
text_stream *more, section *S, source_line *L) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, PROLONG_DEFN_TAN_MTID, OUT, more, S, L);
|
|
if (rv == FALSE)
|
|
Main__error_in_web(TL_IS_267, L);
|
|
}
|
|
|
|
void LanguageMethods__end_definition(OUTPUT_STREAM, programming_language *pl,
|
|
section *S, source_line *L) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, END_DEFN_TAN_MTID, OUT, S, L);
|
|
}
|
|
|
|
#line 155 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 157 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(ADDITIONAL_PREDECLARATIONS_TAN_MTID, programming_language *pl, text_stream *OUT, web *W)
|
|
void LanguageMethods__additional_predeclarations(OUTPUT_STREAM, programming_language *pl, web *W) {
|
|
VMETHOD_CALL(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, OUT, W);
|
|
}
|
|
|
|
#line 168 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 170 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(SUPPRESS_EXPANSION_TAN_MTID, programming_language *pl, text_stream *material)
|
|
int LanguageMethods__allow_expansion(programming_language *pl, text_stream *material) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, SUPPRESS_EXPANSION_TAN_MTID, material);
|
|
return (rv)?FALSE:TRUE;
|
|
}
|
|
|
|
#line 182 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 184 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(TANGLE_COMMAND_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *data)
|
|
|
|
int LanguageMethods__special_tangle_command(OUTPUT_STREAM, programming_language *pl, text_stream *data) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, TANGLE_COMMAND_TAN_MTID, OUT, data);
|
|
return rv;
|
|
}
|
|
|
|
#line 199 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 201 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(WILL_TANGLE_EXTRA_LINE_TAN_MTID, programming_language *pl, source_line *L)
|
|
VMETHOD_TYPE(TANGLE_EXTRA_LINE_TAN_MTID, programming_language *pl, text_stream *OUT, source_line *L)
|
|
int LanguageMethods__will_insert_in_tangle(programming_language *pl, source_line *L) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, WILL_TANGLE_EXTRA_LINE_TAN_MTID, L);
|
|
return rv;
|
|
}
|
|
void LanguageMethods__insert_in_tangle(OUTPUT_STREAM, programming_language *pl, source_line *L) {
|
|
VMETHOD_CALL(pl, TANGLE_EXTRA_LINE_TAN_MTID, OUT, L);
|
|
}
|
|
|
|
#line 218 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 220 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(INSERT_LINE_MARKER_TAN_MTID, programming_language *pl, text_stream *OUT, source_line *L)
|
|
void LanguageMethods__insert_line_marker(OUTPUT_STREAM, programming_language *pl, source_line *L) {
|
|
VMETHOD_CALL(pl, INSERT_LINE_MARKER_TAN_MTID, OUT, L);
|
|
}
|
|
|
|
#line 231 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 233 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(BEFORE_MACRO_EXPANSION_TAN_MTID, programming_language *pl, text_stream *OUT, para_macro *pmac)
|
|
VMETHOD_TYPE(AFTER_MACRO_EXPANSION_TAN_MTID, programming_language *pl, text_stream *OUT, para_macro *pmac)
|
|
void LanguageMethods__before_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) {
|
|
VMETHOD_CALL(pl, BEFORE_MACRO_EXPANSION_TAN_MTID, OUT, pmac);
|
|
}
|
|
void LanguageMethods__after_macro_expansion(OUTPUT_STREAM, programming_language *pl, para_macro *pmac) {
|
|
VMETHOD_CALL(pl, AFTER_MACRO_EXPANSION_TAN_MTID, OUT, pmac);
|
|
}
|
|
|
|
#line 248 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 250 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(OPEN_IFDEF_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *symbol, int sense)
|
|
VMETHOD_TYPE(CLOSE_IFDEF_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *symbol, int sense)
|
|
void LanguageMethods__open_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) {
|
|
VMETHOD_CALL(pl, OPEN_IFDEF_TAN_MTID, OUT, symbol, sense);
|
|
}
|
|
void LanguageMethods__close_ifdef(OUTPUT_STREAM, programming_language *pl, text_stream *symbol, int sense) {
|
|
VMETHOD_CALL(pl, CLOSE_IFDEF_TAN_MTID, OUT, symbol, sense);
|
|
}
|
|
|
|
#line 262 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 264 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(COMMENT_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *comm)
|
|
void LanguageMethods__comment(OUTPUT_STREAM, programming_language *pl, text_stream *comm) {
|
|
VMETHOD_CALL(pl, COMMENT_TAN_MTID, OUT, comm);
|
|
}
|
|
|
|
#line 274 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 276 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(TANGLE_CODE_UNUSUALLY_TAN_MTID, programming_language *pl, text_stream *OUT, text_stream *original)
|
|
void LanguageMethods__tangle_code(OUTPUT_STREAM, programming_language *pl, text_stream *original) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, TANGLE_CODE_UNUSUALLY_TAN_MTID, OUT, original);
|
|
if (rv == FALSE) WRITE("%S", original);
|
|
}
|
|
|
|
#line 286 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 288 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(GNABEHS_TAN_MTID, programming_language *pl, text_stream *OUT, web *W)
|
|
void LanguageMethods__gnabehs(OUTPUT_STREAM, programming_language *pl, web *W) {
|
|
VMETHOD_CALL(pl, GNABEHS_TAN_MTID, OUT, W);
|
|
}
|
|
|
|
#line 298 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 300 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(ADDITIONAL_TANGLING_TAN_MTID, programming_language *pl, web *W, tangle_target *target)
|
|
void LanguageMethods__additional_tangling(programming_language *pl, web *W, tangle_target *target) {
|
|
VMETHOD_CALL(pl, ADDITIONAL_TANGLING_TAN_MTID, W, target);
|
|
}
|
|
|
|
#line 310 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 312 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(BEGIN_WEAVE_WEA_MTID, programming_language *pl, section *S, weave_target *wv)
|
|
void LanguageMethods__begin_weave(section *S, weave_target *wv) {
|
|
VMETHOD_CALL(S->sect_language, BEGIN_WEAVE_WEA_MTID, S, wv);
|
|
}
|
|
|
|
#line 320 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 322 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(SKIP_IN_WEAVING_WEA_MTID, programming_language *pl, weave_target *wv, source_line *L)
|
|
int LanguageMethods__skip_in_weaving(programming_language *pl, weave_target *wv, source_line *L) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, SKIP_IN_WEAVING_WEA_MTID, wv, L);
|
|
return rv;
|
|
}
|
|
|
|
#line 335 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 337 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(RESET_SYNTAX_COLOURING_WEA_MTID, programming_language *pl)
|
|
void LanguageMethods__reset_syntax_colouring(programming_language *pl) {
|
|
VMETHOD_CALLV(pl, RESET_SYNTAX_COLOURING_WEA_MTID);
|
|
}
|
|
|
|
#line 345 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 347 "inweb/Chapter 4/Language Methods.w"
|
|
int colouring_state = PLAIN_COLOUR;
|
|
|
|
IMETHOD_TYPE(SYNTAX_COLOUR_WEA_MTID, programming_language *pl, text_stream *OUT, weave_target *wv, web *W,
|
|
chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring)
|
|
int LanguageMethods__syntax_colour(OUTPUT_STREAM, programming_language *pl, weave_target *wv,
|
|
web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *colouring) {
|
|
Str__copy(colouring, matter);
|
|
for (int i=0; i < Str__len(matter); i++) Str__put_at(colouring, i, PLAIN_COLOUR);
|
|
int rv = FALSE;
|
|
programming_language *colour_as = pl;
|
|
if (L->category == TEXT_EXTRACT_LCAT) colour_as = L->colour_as;
|
|
if (colour_as)
|
|
IMETHOD_CALL(rv, colour_as, SYNTAX_COLOUR_WEA_MTID, OUT, wv, W, C, S, L, matter, colouring);
|
|
return rv;
|
|
}
|
|
|
|
#line 368 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 370 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(WEAVE_CODE_LINE_WEA_MTID, programming_language *pl, text_stream *OUT, weave_target *wv, web *W,
|
|
chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment)
|
|
int LanguageMethods__weave_code_line(OUTPUT_STREAM, programming_language *pl, weave_target *wv,
|
|
web *W, chapter *C, section *S, source_line *L, text_stream *matter, text_stream *concluding_comment) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, WEAVE_CODE_LINE_WEA_MTID, OUT, wv, W, C, S, L, matter, concluding_comment);
|
|
return rv;
|
|
}
|
|
|
|
#line 382 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 384 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(NOTIFY_NEW_TAG_WEA_MTID, programming_language *pl, theme_tag *tag)
|
|
void LanguageMethods__new_tag_declared(theme_tag *tag) {
|
|
programming_language *pl;
|
|
LOOP_OVER(pl, programming_language)
|
|
VMETHOD_CALL(pl, NOTIFY_NEW_TAG_WEA_MTID, tag);
|
|
}
|
|
|
|
#line 400 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 402 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(CATALOGUE_ANA_MTID, programming_language *pl, section *S, int functions_too)
|
|
void LanguageMethods__catalogue(programming_language *pl, section *S, int functions_too) {
|
|
VMETHOD_CALL(pl, CATALOGUE_ANA_MTID, S, functions_too);
|
|
}
|
|
|
|
#line 415 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 417 "inweb/Chapter 4/Language Methods.w"
|
|
VMETHOD_TYPE(EARLY_PREWEAVE_ANALYSIS_ANA_MTID, programming_language *pl, web *W)
|
|
VMETHOD_TYPE(LATE_PREWEAVE_ANALYSIS_ANA_MTID, programming_language *pl, web *W)
|
|
void LanguageMethods__early_preweave_analysis(programming_language *pl, web *W) {
|
|
VMETHOD_CALL(pl, EARLY_PREWEAVE_ANALYSIS_ANA_MTID, W);
|
|
}
|
|
void LanguageMethods__late_preweave_analysis(programming_language *pl, web *W) {
|
|
VMETHOD_CALL(pl, LATE_PREWEAVE_ANALYSIS_ANA_MTID, W);
|
|
}
|
|
|
|
#line 430 "inweb/Chapter 4/Language Methods.w"
|
|
|
|
#line 432 "inweb/Chapter 4/Language Methods.w"
|
|
IMETHOD_TYPE(SHARE_ELEMENT_ANA_MTID, programming_language *pl, text_stream *element_name)
|
|
int LanguageMethods__share_element(programming_language *pl, text_stream *element_name) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pl, SHARE_ELEMENT_ANA_MTID, element_name);
|
|
return rv;
|
|
}
|
|
|
|
#line 442 "inweb/Chapter 4/Language Methods.w"
|
|
int LanguageMethods__supports_definitions(programming_language *pl) {
|
|
if (Str__len(pl->start_definition) > 0) return TRUE;
|
|
if (Str__len(pl->prolong_definition) > 0) return TRUE;
|
|
if (Str__len(pl->end_definition) > 0) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
#line 16 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__add_fallbacks(programming_language *pl) {
|
|
if (Methods__provided(pl->methods, PARSE_COMMENT_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, PARSE_COMMENT_TAN_MTID, ACMESupport__parse_comment);
|
|
if (Methods__provided(pl->methods, COMMENT_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, COMMENT_TAN_MTID, ACMESupport__comment);
|
|
if (Methods__provided(pl->methods, SHEBANG_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, SHEBANG_TAN_MTID, ACMESupport__shebang);
|
|
if (Methods__provided(pl->methods, BEFORE_MACRO_EXPANSION_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, BEFORE_MACRO_EXPANSION_TAN_MTID, ACMESupport__before_macro_expansion);
|
|
if (Methods__provided(pl->methods, AFTER_MACRO_EXPANSION_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, AFTER_MACRO_EXPANSION_TAN_MTID, ACMESupport__after_macro_expansion);
|
|
if (Methods__provided(pl->methods, START_DEFN_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, START_DEFN_TAN_MTID, ACMESupport__start_definition);
|
|
if (Methods__provided(pl->methods, PROLONG_DEFN_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, PROLONG_DEFN_TAN_MTID, ACMESupport__prolong_definition);
|
|
if (Methods__provided(pl->methods, END_DEFN_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, END_DEFN_TAN_MTID, ACMESupport__end_definition);
|
|
if (Methods__provided(pl->methods, OPEN_IFDEF_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, OPEN_IFDEF_TAN_MTID, ACMESupport__I6_open_ifdef);
|
|
if (Methods__provided(pl->methods, CLOSE_IFDEF_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, CLOSE_IFDEF_TAN_MTID, ACMESupport__I6_close_ifdef);
|
|
if (Methods__provided(pl->methods, INSERT_LINE_MARKER_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, INSERT_LINE_MARKER_TAN_MTID, ACMESupport__insert_line_marker);
|
|
if (Methods__provided(pl->methods, SUPPRESS_DISCLAIMER_TAN_MTID) == FALSE)
|
|
METHOD_ADD(pl, SUPPRESS_DISCLAIMER_TAN_MTID, ACMESupport__suppress_disclaimer);
|
|
if (Methods__provided(pl->methods, BEGIN_WEAVE_WEA_MTID) == FALSE)
|
|
METHOD_ADD(pl, BEGIN_WEAVE_WEA_MTID, ACMESupport__begin_weave);
|
|
if (Methods__provided(pl->methods, RESET_SYNTAX_COLOURING_WEA_MTID) == FALSE)
|
|
METHOD_ADD(pl, RESET_SYNTAX_COLOURING_WEA_MTID, ACMESupport__reset_syntax_colouring);
|
|
if (Methods__provided(pl->methods, SYNTAX_COLOUR_WEA_MTID) == FALSE)
|
|
METHOD_ADD(pl, SYNTAX_COLOUR_WEA_MTID, ACMESupport__syntax_colour);
|
|
}
|
|
|
|
#line 54 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__expand(OUTPUT_STREAM, text_stream *prototype, text_stream *S,
|
|
int N, filename *F) {
|
|
if (Str__len(prototype) > 0) {
|
|
for (int i=0; i<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 78 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__shebang(programming_language *pl, text_stream *OUT, web *W,
|
|
tangle_target *target) {
|
|
ACMESupport__expand(OUT, pl->shebang, NULL, -1, NULL);
|
|
}
|
|
|
|
void ACMESupport__before_macro_expansion(programming_language *pl,
|
|
OUTPUT_STREAM, para_macro *pmac) {
|
|
ACMESupport__expand(OUT, pl->before_macro_expansion, NULL, -1, NULL);
|
|
}
|
|
|
|
void ACMESupport__after_macro_expansion(programming_language *pl,
|
|
OUTPUT_STREAM, para_macro *pmac) {
|
|
ACMESupport__expand(OUT, pl->after_macro_expansion, NULL, -1, NULL);
|
|
}
|
|
|
|
int ACMESupport__start_definition(programming_language *pl, text_stream *OUT,
|
|
text_stream *term, text_stream *start, section *S, source_line *L) {
|
|
if (LanguageMethods__supports_definitions(pl)) {
|
|
ACMESupport__expand(OUT, pl->start_definition, term, -1, NULL);
|
|
Tangler__tangle_code(OUT, start, S, L);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int ACMESupport__prolong_definition(programming_language *pl,
|
|
text_stream *OUT, text_stream *more, section *S, source_line *L) {
|
|
if (LanguageMethods__supports_definitions(pl)) {
|
|
ACMESupport__expand(OUT, pl->prolong_definition, NULL, -1, NULL);
|
|
Tangler__tangle_code(OUT, more, S, L);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int ACMESupport__end_definition(programming_language *pl,
|
|
text_stream *OUT, section *S, source_line *L) {
|
|
if (LanguageMethods__supports_definitions(pl)) {
|
|
ACMESupport__expand(OUT, pl->end_definition, NULL, -1, NULL);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void ACMESupport__I6_open_ifdef(programming_language *pl,
|
|
text_stream *OUT, text_stream *symbol, int sense) {
|
|
if (sense) ACMESupport__expand(OUT, pl->start_ifdef, symbol, -1, NULL);
|
|
else ACMESupport__expand(OUT, pl->start_ifndef, symbol, -1, NULL);
|
|
}
|
|
|
|
void ACMESupport__I6_close_ifdef(programming_language *pl,
|
|
text_stream *OUT, text_stream *symbol, int sense) {
|
|
if (sense) ACMESupport__expand(OUT, pl->end_ifdef, symbol, -1, NULL);
|
|
else ACMESupport__expand(OUT, pl->end_ifndef, symbol, -1, NULL);
|
|
}
|
|
|
|
void ACMESupport__insert_line_marker(programming_language *pl,
|
|
text_stream *OUT, source_line *L) {
|
|
ACMESupport__expand(OUT, pl->line_marker, NULL,
|
|
L->source.line_count, L->source.text_file_filename);
|
|
}
|
|
|
|
void ACMESupport__comment(programming_language *pl,
|
|
text_stream *OUT, text_stream *comm) {
|
|
if (Str__len(pl->multiline_comment_open) > 0) {
|
|
ACMESupport__expand(OUT, pl->multiline_comment_open, NULL, -1, NULL);
|
|
WRITE(" %S ", comm);
|
|
ACMESupport__expand(OUT, pl->multiline_comment_close, NULL, -1, NULL);
|
|
WRITE("\n");
|
|
} else if (Str__len(pl->line_comment) > 0) {
|
|
ACMESupport__expand(OUT, pl->line_comment, NULL, -1, NULL);
|
|
WRITE(" %S\n", comm);
|
|
} else if (Str__len(pl->whole_line_comment) > 0) {
|
|
ACMESupport__expand(OUT, pl->whole_line_comment, NULL, -1, NULL);
|
|
WRITE(" %S\n", comm);
|
|
}
|
|
}
|
|
|
|
int ACMESupport__parse_comment(programming_language *pl,
|
|
text_stream *line, text_stream *part_before_comment, text_stream *part_within_comment) {
|
|
int q_mode = 0, c_mode = FALSE, non_white_space = FALSE, c_position = -1, c_end = -1;
|
|
for (int i=0; i<Str__len(line); i++) {
|
|
wchar_t c = Str__get_at(line, i);
|
|
if (c_mode == 2) {
|
|
if (ACMESupport__text_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 (c == Str__get_first_char(pl->character_literal)) {
|
|
if (q_mode == 0) q_mode = 1;
|
|
else if (q_mode == 1) q_mode = 0;
|
|
}
|
|
if (ACMESupport__text_at(line, i, pl->multiline_comment_open)) {
|
|
c_mode = 2; c_position = i; non_white_space = FALSE;
|
|
i += Str__len(pl->multiline_comment_open) - 1;
|
|
}
|
|
if (ACMESupport__text_at(line, i, pl->line_comment)) {
|
|
c_mode = 1; c_position = i; c_end = Str__len(line); non_white_space = FALSE;
|
|
i += Str__len(pl->line_comment) - 1;
|
|
}
|
|
if (ACMESupport__text_at(line, i, pl->whole_line_comment)) {
|
|
int material_exists = FALSE;
|
|
for (int j=0; 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(part_within_comment);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int ACMESupport__text_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 222 "inweb/Chapter 4/ACME Support.w"
|
|
int ACMESupport__suppress_disclaimer(programming_language *pl) {
|
|
return pl->suppress_disclaimer;
|
|
}
|
|
|
|
#line 229 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__begin_weave(programming_language *pl, section *S, weave_target *wv) {
|
|
reserved_word *rw;
|
|
LOOP_OVER_LINKED_LIST(rw, reserved_word, pl->reserved_words)
|
|
Analyser__mark_reserved_word_for_section(S, rw->word, rw->colour);
|
|
}
|
|
|
|
#line 238 "inweb/Chapter 4/ACME Support.w"
|
|
void ACMESupport__reset_syntax_colouring(programming_language *pl) {
|
|
Painter__reset_syntax_colouring(pl);
|
|
}
|
|
|
|
int ACMESupport__syntax_colour(programming_language *pl, text_stream *OUT, weave_target *wv,
|
|
web *W, chapter *C, section *S, source_line *L, text_stream *matter,
|
|
text_stream *colouring) {
|
|
hash_table *ht = &(S->sect_target->symbols);
|
|
if ((L->category == TEXT_EXTRACT_LCAT) && (pl != S->sect_language))
|
|
ht = &(pl->built_in_keywords);
|
|
return Painter__syntax_colour(pl, OUT, ht, matter, colouring, FALSE);
|
|
}
|
|
|
|
#line 16 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__reset_syntax_colouring(programming_language *pl) {
|
|
colouring_state = PLAIN_COLOUR;
|
|
}
|
|
|
|
#line 36 "inweb/Chapter 4/The Painter.w"
|
|
int Painter__syntax_colour(programming_language *pl, text_stream *OUT,
|
|
hash_table *HT, text_stream *matter, text_stream *colouring, int with_comments) {
|
|
int from = 0, to = Str__len(matter) - 1;
|
|
if (with_comments) {
|
|
TEMPORARY_TEXT(part_before_comment);
|
|
TEMPORARY_TEXT(part_within_comment);
|
|
if (LanguageMethods__parse_comment(pl,
|
|
matter, part_before_comment, part_within_comment)) {
|
|
int N = Str__len(matter);
|
|
for (int i=Str__len(part_before_comment); 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, OUT, HT, matter, colouring, from, to);
|
|
return FALSE;
|
|
}
|
|
|
|
void Painter__syntax_colour_inner(programming_language *pl, text_stream *OUT,
|
|
hash_table *HT, text_stream *matter, text_stream *colouring, int from, int to) {
|
|
|
|
{
|
|
#line 64 "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 = 0, one_off = -1, will_be = -1;
|
|
switch (colouring_state) {
|
|
case PLAIN_COLOUR: {
|
|
wchar_t c = Str__get_at(matter, i);
|
|
if (c == dquote) {
|
|
colouring_state = STRING_COLOUR;
|
|
break;
|
|
}
|
|
if (c == squote) {
|
|
colouring_state = CHAR_LITERAL_COLOUR;
|
|
break;
|
|
}
|
|
if (Painter__identifier_at(pl, matter, colouring, i))
|
|
one_off = IDENTIFIER_COLOUR;
|
|
break;
|
|
}
|
|
case CHAR_LITERAL_COLOUR: {
|
|
wchar_t c = Str__get_at(matter, i);
|
|
if (c == squote) will_be = PLAIN_COLOUR;
|
|
if (c == squote_escape) skip = 1;
|
|
break;
|
|
}
|
|
case STRING_COLOUR: {
|
|
wchar_t c = Str__get_at(matter, i);
|
|
if (c == dquote) will_be = PLAIN_COLOUR;
|
|
if (c == dquote_escape) skip = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (one_off >= 0) Str__put_at(colouring, i, (char) one_off);
|
|
else Str__put_at(colouring, i, (char) colouring_state);
|
|
if (will_be >= 0) colouring_state = (char) will_be;
|
|
if (skip > 0) i += skip;
|
|
}
|
|
|
|
}
|
|
#line 58 "inweb/Chapter 4/The Painter.w"
|
|
;
|
|
|
|
{
|
|
#line 105 "inweb/Chapter 4/The Painter.w"
|
|
int base = -1, dec_possible = TRUE;
|
|
for (int i=from; i <= to; i++) {
|
|
if ((Str__get_at(colouring, i) == PLAIN_COLOUR) ||
|
|
(Str__get_at(colouring, i) == IDENTIFIER_COLOUR)) {
|
|
wchar_t c = Str__get_at(matter, i);
|
|
if (ACMESupport__text_at(matter, i, pl->binary_literal_prefix)) {
|
|
base = 2;
|
|
for (int j=0; j<Str__len(pl->binary_literal_prefix); j++)
|
|
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
|
|
dec_possible = TRUE;
|
|
continue;
|
|
} else if (ACMESupport__text_at(matter, i, pl->octal_literal_prefix)) {
|
|
base = 8;
|
|
for (int j=0; j<Str__len(pl->octal_literal_prefix); j++)
|
|
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
|
|
dec_possible = TRUE;
|
|
continue;
|
|
} else if (ACMESupport__text_at(matter, i, pl->hexadecimal_literal_prefix)) {
|
|
base = 16;
|
|
for (int j=0; j<Str__len(pl->hexadecimal_literal_prefix); j++)
|
|
Str__put_at(colouring, i+j, (char) CONSTANT_COLOUR);
|
|
dec_possible = TRUE;
|
|
continue;
|
|
}
|
|
if ((ACMESupport__text_at(matter, i, pl->negative_literal_prefix)) &&
|
|
(dec_possible) && (base == 0)) {
|
|
base = 10;
|
|
Str__put_at(colouring, i, (char) CONSTANT_COLOUR);
|
|
continue;
|
|
}
|
|
int pass = FALSE;
|
|
switch (base) {
|
|
case -1:
|
|
if ((dec_possible) && (Characters__isdigit(c))) {
|
|
base = 10; pass = TRUE;
|
|
}
|
|
break;
|
|
case 2: if ((c == '0') || (c == '1')) pass = TRUE; break;
|
|
case 10: if (Characters__isdigit(c)) pass = TRUE; break;
|
|
case 16: if (Characters__isdigit(c)) pass = TRUE;
|
|
int d = Characters__tolower(c);
|
|
if ((d == 'a') || (d == 'b') || (d == 'c') ||
|
|
(d == 'd') || (d == 'e') || (d == 'f')) pass = TRUE;
|
|
break;
|
|
}
|
|
if (pass) {
|
|
Str__put_at(colouring, i, (char) CONSTANT_COLOUR);
|
|
} else {
|
|
if (Characters__is_whitespace(c)) dec_possible = TRUE;
|
|
else dec_possible = FALSE;
|
|
base = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 59 "inweb/Chapter 4/The Painter.w"
|
|
;
|
|
|
|
{
|
|
#line 190 "inweb/Chapter 4/The Painter.w"
|
|
if (pl->program)
|
|
Painter__execute(HT, pl->program, matter, colouring, from, to);
|
|
|
|
}
|
|
#line 60 "inweb/Chapter 4/The Painter.w"
|
|
;
|
|
}
|
|
|
|
#line 166 "inweb/Chapter 4/The Painter.w"
|
|
int Painter__identifier_at(programming_language *pl,
|
|
text_stream *matter, text_stream *colouring, int i) {
|
|
wchar_t c = Str__get_at(matter, i);
|
|
if ((i > 0) && (Str__get_at(colouring, i-1) == IDENTIFIER_COLOUR)) {
|
|
if ((c == '_') ||
|
|
((c >= 'A') && (c <= 'Z')) ||
|
|
((c >= 'a') && (c <= 'z')) ||
|
|
((c >= '0') && (c <= '9'))) return TRUE;
|
|
if ((c == ':') && (pl->supports_namespaces)) return TRUE;
|
|
} else {
|
|
wchar_t d = 0;
|
|
if (i > 0) d = Str__get_at(matter, i);
|
|
if ((d >= '0') && (d <= '9')) return FALSE;
|
|
if ((c == '_') ||
|
|
((c >= 'A') && (c <= 'Z')) ||
|
|
((c >= 'a') && (c <= 'z'))) return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#line 199 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__execute(hash_table *HT, colouring_language_block *block, text_stream *matter,
|
|
text_stream *colouring, int from, int to) {
|
|
if (block == NULL) internal_error("no block");
|
|
TEMPORARY_TEXT(colouring_at_start);
|
|
Str__copy(colouring_at_start, colouring);
|
|
colouring_rule *rule;
|
|
LOOP_OVER_LINKED_LIST(rule, colouring_rule, block->rules) {
|
|
switch (block->run) {
|
|
case WHOLE_LINE_CRULE_RUN:
|
|
Painter__execute_rule(HT, rule, matter, colouring, from, to);
|
|
break;
|
|
case CHARACTERS_CRULE_RUN:
|
|
for (int i=from; i<=to; i++)
|
|
Painter__execute_rule(HT, rule, matter, colouring, i, i);
|
|
break;
|
|
case INSTANCES_CRULE_RUN: {
|
|
int L = Str__len(block->run_instance) - 1;
|
|
if (L >= 0)
|
|
for (int i=from; i<=to - L; i++)
|
|
if (ACMESupport__text_at(matter, i, block->run_instance)) {
|
|
Painter__execute_rule(HT, rule, matter, colouring, i, i+L);
|
|
i += L;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
int ident_from = -1;
|
|
for (int i=from; i<=to; i++) {
|
|
int col = Str__get_at(colouring_at_start, i);
|
|
if ((col == block->run) ||
|
|
((block->run == UNQUOTED_COLOUR) &&
|
|
((col != STRING_COLOUR) && (col != CHAR_LITERAL_COLOUR)))) {
|
|
if (ident_from == -1) ident_from = i;
|
|
} else {
|
|
if (ident_from >= 0)
|
|
Painter__execute_rule(HT, rule, matter, colouring, ident_from, i-1);
|
|
ident_from = -1;
|
|
}
|
|
}
|
|
if (ident_from >= 0)
|
|
Painter__execute_rule(HT, rule, matter, colouring, ident_from, to);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
DISCARD_TEXT(colouring_at_start);
|
|
}
|
|
|
|
#line 250 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__execute_rule(hash_table *HT, colouring_rule *rule, text_stream *matter,
|
|
text_stream *colouring, int from, int to) {
|
|
if (Painter__satisfies(HT, rule, matter, colouring, from, to))
|
|
Painter__follow(HT, rule, matter, colouring, from, to);
|
|
}
|
|
|
|
#line 267 "inweb/Chapter 4/The Painter.w"
|
|
int Painter__satisfies(hash_table *HT, colouring_rule *rule, text_stream *matter,
|
|
text_stream *colouring, int from, int to) {
|
|
if (Str__len(rule->match_text) > 0) {
|
|
if ((rule->match_prefix == UNSPACED_RULE_PREFIX) ||
|
|
(rule->match_prefix == SPACED_RULE_PREFIX) ||
|
|
(rule->match_prefix == OPTIONALLY_SPACED_RULE_PREFIX)) {
|
|
int pos = from;
|
|
if (rule->match_prefix != UNSPACED_RULE_PREFIX) {
|
|
while ((pos > 0) && (Characters__is_whitespace(pos-1))) pos--;
|
|
if ((rule->match_prefix == SPACED_RULE_PREFIX) && (pos == from))
|
|
return FALSE;
|
|
}
|
|
if (ACMESupport__text_at(matter,
|
|
pos-Str__len(rule->match_text), rule->match_text) == FALSE)
|
|
return FALSE;
|
|
rule->fix_position = pos-Str__len(rule->match_text);
|
|
} else if ((rule->match_prefix == UNSPACED_RULE_SUFFIX) ||
|
|
(rule->match_prefix == SPACED_RULE_SUFFIX) ||
|
|
(rule->match_prefix == OPTIONALLY_SPACED_RULE_SUFFIX)) {
|
|
int pos = from + Str__len(rule->match_text);
|
|
if (rule->match_prefix != UNSPACED_RULE_SUFFIX) {
|
|
while ((pos < Str__len(rule->match_text)) && (Characters__is_whitespace(pos))) pos++;
|
|
if ((rule->match_prefix == SPACED_RULE_SUFFIX) && (pos == from))
|
|
return FALSE;
|
|
}
|
|
if (ACMESupport__text_at(matter, pos, rule->match_text) == FALSE)
|
|
return FALSE;
|
|
rule->fix_position = pos;
|
|
} else {
|
|
if (Str__ne(matter, rule->match_text)) return FALSE;
|
|
}
|
|
} else if (rule->match_keyword_of_colour != NOT_A_COLOUR) {
|
|
TEMPORARY_TEXT(id);
|
|
Str__substr(id, Str__at(matter, from), Str__at(matter, to+1));
|
|
int rw = Analyser__is_reserved_word(HT, id, rule->match_keyword_of_colour);
|
|
DISCARD_TEXT(id);
|
|
if (rw == FALSE) return FALSE;
|
|
} else if (rule->match_colour != NOT_A_COLOUR) {
|
|
for (int i=from; i<=to; i++)
|
|
if (Str__get_at(colouring, i) != rule->match_colour)
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
#line 315 "inweb/Chapter 4/The Painter.w"
|
|
void Painter__follow(hash_table *HT, colouring_rule *rule, text_stream *matter,
|
|
text_stream *colouring, int from, int to) {
|
|
if (rule->execute_block)
|
|
Painter__execute(HT, rule->execute_block, matter, colouring, from, to);
|
|
else if (rule->debug)
|
|
{
|
|
#line 331 "inweb/Chapter 4/The Painter.w"
|
|
PRINT("[%d, %d] text: ", from, to);
|
|
for (int i=from; i<=to; i++)
|
|
PUT_TO(STDOUT, Str__get_at(matter, i));
|
|
PRINT("\n[%d, %d] cols: ", from, to);
|
|
for (int i=from; i<=to; i++)
|
|
PUT_TO(STDOUT, Str__get_at(colouring, i));
|
|
PRINT("\n");
|
|
|
|
}
|
|
#line 319 "inweb/Chapter 4/The Painter.w"
|
|
|
|
else {
|
|
if (rule->set_to_colour != NOT_A_COLOUR)
|
|
for (int i=from; i<=to; i++)
|
|
Str__put_at(colouring, i, rule->set_to_colour);
|
|
if (rule->set_prefix_to_colour != NOT_A_COLOUR)
|
|
for (int i=rule->fix_position; i<rule->fix_position+Str__len(rule->match_text); i++)
|
|
Str__put_at(colouring, i, rule->set_prefix_to_colour);
|
|
}
|
|
}
|
|
|
|
#line 9 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__make_c_like(programming_language *pl) {
|
|
METHOD_ADD(pl, FURTHER_PARSING_PAR_MTID, CLike__further_parsing);
|
|
METHOD_ADD(pl, SUBCATEGORISE_LINE_PAR_MTID, CLike__subcategorise_code);
|
|
|
|
METHOD_ADD(pl, ADDITIONAL_EARLY_MATTER_TAN_MTID, CLike__additional_early_matter);
|
|
METHOD_ADD(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, CLike__additional_predeclarations);
|
|
|
|
METHOD_ADD(pl, CATALOGUE_ANA_MTID, CLike__catalogue);
|
|
METHOD_ADD(pl, EARLY_PREWEAVE_ANALYSIS_ANA_MTID, CLike__analyse_code);
|
|
METHOD_ADD(pl, LATE_PREWEAVE_ANALYSIS_ANA_MTID, CLike__post_analysis);
|
|
}
|
|
|
|
#line 37 "inweb/Chapter 4/C-Like Languages.w"
|
|
int cc_sp = 0;
|
|
source_line *cc_stack[MAX_CONDITIONAL_COMPILATION_STACK];
|
|
c_structure *first_cst_alphabetically = NULL;
|
|
|
|
void CLike__further_parsing(programming_language *self, web *W) {
|
|
|
|
{
|
|
#line 97 "inweb/Chapter 4/C-Like Languages.w"
|
|
c_structure *current_str = NULL;
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
|
|
match_results mr = Regexp__create_mr();
|
|
|
|
if (Regexp__match(&mr, L->text, L"typedef struct (%i+) %c*{%c*")) {
|
|
|
|
{
|
|
#line 134 "inweb/Chapter 4/C-Like Languages.w"
|
|
c_structure *str = CREATE(c_structure);
|
|
|
|
{
|
|
#line 142 "inweb/Chapter 4/C-Like Languages.w"
|
|
str->structure_name = Str__duplicate(mr.exp[0]);
|
|
str->typedef_begins = L;
|
|
str->tangled = FALSE;
|
|
str->typedef_ends = NULL;
|
|
str->incorporates = NEW_LINKED_LIST(c_structure);
|
|
str->elements = NEW_LINKED_LIST(structure_element);
|
|
|
|
}
|
|
#line 135 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
Analyser__mark_reserved_word_for_section(L->owning_section, str->structure_name, RESERVED_COLOUR);
|
|
|
|
{
|
|
#line 150 "inweb/Chapter 4/C-Like Languages.w"
|
|
ADD_TO_LINKED_LIST(str, c_structure, W->c_structures);
|
|
ADD_TO_LINKED_LIST(str, c_structure, L->owning_paragraph->structures);
|
|
|
|
}
|
|
#line 137 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 154 "inweb/Chapter 4/C-Like Languages.w"
|
|
str->next_cst_alphabetically = NULL;
|
|
if (first_cst_alphabetically == NULL) first_cst_alphabetically = str;
|
|
else {
|
|
int placed = FALSE;
|
|
c_structure *last = NULL;
|
|
for (c_structure *seq = first_cst_alphabetically; seq;
|
|
seq = seq->next_cst_alphabetically) {
|
|
if (Str__cmp(str->structure_name, seq->structure_name) < 0) {
|
|
if (seq == first_cst_alphabetically) {
|
|
str->next_cst_alphabetically = first_cst_alphabetically;
|
|
first_cst_alphabetically = str;
|
|
} else {
|
|
last->next_cst_alphabetically = str;
|
|
str->next_cst_alphabetically = seq;
|
|
}
|
|
placed = TRUE;
|
|
break;
|
|
}
|
|
last = seq;
|
|
}
|
|
if (placed == FALSE) last->next_cst_alphabetically = str;
|
|
}
|
|
|
|
}
|
|
#line 138 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
current_str = str;
|
|
|
|
}
|
|
#line 104 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
Tags__add_by_name(L->owning_paragraph, TL_IS_271);
|
|
} else if ((Str__get_first_char(L->text) == '}') && (current_str)) {
|
|
current_str->typedef_ends = L;
|
|
current_str = NULL;
|
|
} else if ((current_str) && (current_str->typedef_ends == NULL)) {
|
|
|
|
{
|
|
#line 185 "inweb/Chapter 4/C-Like Languages.w"
|
|
TEMPORARY_TEXT(p);
|
|
Str__copy(p, L->text);
|
|
Str__trim_white_space(p);
|
|
|
|
{
|
|
#line 207 "inweb/Chapter 4/C-Like Languages.w"
|
|
wchar_t *modifier_patterns[] = {
|
|
L"(struct )(%C%c*)", L"(signed )(%C%c*)", L"(unsigned )(%C%c*)",
|
|
L"(short )(%C%c*)", L"(long )(%C%c*)", L"(static )(%C%c*)", NULL };
|
|
int seek_modifiers = TRUE;
|
|
while (seek_modifiers) {
|
|
seek_modifiers = FALSE;
|
|
for (int i = 0; modifier_patterns[i]; i++)
|
|
if (Regexp__match(&mr, p, modifier_patterns[i])) {
|
|
Str__copy(p, mr.exp[1]);
|
|
seek_modifiers = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 188 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
string_position pos = Str__start(p);
|
|
if (Str__get(pos) != '/') { /* a slash must introduce a comment here */
|
|
|
|
{
|
|
#line 225 "inweb/Chapter 4/C-Like Languages.w"
|
|
while ((Str__get(pos)) && (Characters__is_space_or_tab(Str__get(pos)) == FALSE))
|
|
pos = Str__forward(pos);
|
|
|
|
}
|
|
#line 191 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 231 "inweb/Chapter 4/C-Like Languages.w"
|
|
while ((Characters__is_space_or_tab(Str__get(pos))) || (Str__get(pos) == '*') ||
|
|
(Str__get(pos) == '(') || (Str__get(pos) == ')')) pos = Str__forward(pos);
|
|
|
|
}
|
|
#line 192 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
if (Str__in_range(pos)) {
|
|
match_results mr = Regexp__create_mr();
|
|
TEMPORARY_TEXT(elname);
|
|
|
|
{
|
|
#line 238 "inweb/Chapter 4/C-Like Languages.w"
|
|
Str__substr(elname, pos, Str__end(p));
|
|
if (Regexp__match(&mr, elname, L"(%i+)%c*")) Str__copy(elname, mr.exp[0]);
|
|
|
|
}
|
|
#line 196 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 259 "inweb/Chapter 4/C-Like Languages.w"
|
|
Analyser__mark_reserved_word_for_section(L->owning_section, elname, ELEMENT_COLOUR);
|
|
structure_element *elt = CREATE(structure_element);
|
|
elt->element_name = Str__duplicate(elname);
|
|
elt->allow_sharing = FALSE;
|
|
elt->element_created_at = L;
|
|
if (LanguageMethods__share_element(W->main_language, elname)) elt->allow_sharing = TRUE;
|
|
ADD_TO_LINKED_LIST(elt, structure_element, current_str->elements);
|
|
|
|
}
|
|
#line 197 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
DISCARD_TEXT(elname);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
}
|
|
DISCARD_TEXT(p);
|
|
|
|
}
|
|
#line 110 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
} else if ((Regexp__match(&mr, L->text, L"typedef %c+")) &&
|
|
(Regexp__match(&mr, L->text, L"%c+##%c+") == FALSE)) {
|
|
if (L->owning_paragraph->placed_very_early == FALSE)
|
|
L->category = TYPEDEF_LCAT;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
}
|
|
#line 42 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 281 "inweb/Chapter 4/C-Like Languages.w"
|
|
c_structure *current_str;
|
|
LOOP_OVER(current_str, c_structure) {
|
|
for (source_line *L = current_str->typedef_begins;
|
|
((L) && (L != current_str->typedef_ends));
|
|
L = L->next_line) {
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L" struct (%i+) %i%c*"))
|
|
|
|
{
|
|
#line 294 "inweb/Chapter 4/C-Like Languages.w"
|
|
text_stream *used_structure = mr.exp[0];
|
|
c_structure *str;
|
|
LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures)
|
|
if ((str != current_str) &&
|
|
(Str__eq(used_structure, str->structure_name)))
|
|
ADD_TO_LINKED_LIST(str, c_structure, current_str->incorporates);
|
|
|
|
}
|
|
#line 288 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 43 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
cc_sp = 0;
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
|
|
if ((L->category == CODE_BODY_LCAT) ||
|
|
(L->category == BEGIN_DEFINITION_LCAT) ||
|
|
(L->category == CONT_DEFINITION_LCAT)) {
|
|
|
|
{
|
|
#line 59 "inweb/Chapter 4/C-Like Languages.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if ((Regexp__match(&mr, L->text, L" *#ifn*def %c+")) ||
|
|
(Regexp__match(&mr, L->text, L" *#IFN*DEF %c+"))) {
|
|
if (cc_sp >= MAX_CONDITIONAL_COMPILATION_STACK)
|
|
Main__error_in_web(TL_IS_269, L);
|
|
else
|
|
cc_stack[cc_sp++] = L;
|
|
}
|
|
if ((Regexp__match(&mr, L->text, L" *#endif *")) ||
|
|
(Regexp__match(&mr, L->text, L" *#ENDIF *"))) {
|
|
if (cc_sp <= 0)
|
|
Main__error_in_web(TL_IS_270, L);
|
|
else
|
|
cc_sp--;
|
|
}
|
|
|
|
}
|
|
#line 51 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 312 "inweb/Chapter 4/C-Like Languages.w"
|
|
if (!(Characters__is_space_or_tab(Str__get_first_char(L->text)))) {
|
|
TEMPORARY_TEXT(qualifiers);
|
|
TEMPORARY_TEXT(modified);
|
|
Str__copy(modified, L->text);
|
|
|
|
{
|
|
#line 339 "inweb/Chapter 4/C-Like Languages.w"
|
|
wchar_t *modifier_patterns[] = {
|
|
L"(signed )(%C%c*)", L"(unsigned )(%C%c*)",
|
|
L"(short )(%C%c*)", L"(long )(%C%c*)", L"(static )(%C%c*)", NULL };
|
|
int seek_modifiers = TRUE;
|
|
while (seek_modifiers) {
|
|
seek_modifiers = FALSE;
|
|
match_results mr = Regexp__create_mr();
|
|
for (int i = 0; modifier_patterns[i]; i++)
|
|
if (Regexp__match(&mr, modified, modifier_patterns[i])) {
|
|
Str__concatenate(qualifiers, mr.exp[0]);
|
|
Str__copy(modified, mr.exp[1]);
|
|
seek_modifiers = TRUE; break;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
}
|
|
#line 316 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, modified, L"(%i+) (%**)(%i+)%((%c*)")) {
|
|
TEMPORARY_TEXT(ftype); Str__copy(ftype, mr.exp[0]);
|
|
TEMPORARY_TEXT(asts); Str__copy(asts, mr.exp[1]);
|
|
TEMPORARY_TEXT(fname); Str__copy(fname, mr.exp[2]);
|
|
TEMPORARY_TEXT(arguments); Str__copy(arguments, mr.exp[3]);
|
|
|
|
{
|
|
#line 356 "inweb/Chapter 4/C-Like Languages.w"
|
|
|
|
{
|
|
#line 376 "inweb/Chapter 4/C-Like Languages.w"
|
|
source_line *AL = L;
|
|
int arg_lc = 1;
|
|
while ((AL) && (arg_lc <= MAX_ARG_LINES) && (Regexp__find_open_brace(arguments) == -1)) {
|
|
if (AL->next_line == NULL) {
|
|
TEMPORARY_TEXT(err_mess);
|
|
WRITE_TO(err_mess, "Function '%S' has a malformed declaration", fname);
|
|
Main__error_in_web(err_mess, L);
|
|
DISCARD_TEXT(err_mess);
|
|
break;
|
|
}
|
|
AL = AL->next_line;
|
|
WRITE_TO(arguments, " %S", AL->text);
|
|
arg_lc++;
|
|
}
|
|
int n = Regexp__find_open_brace(arguments);
|
|
if (n >= 0) Str__truncate(arguments, n);
|
|
|
|
}
|
|
#line 356 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
Analyser__mark_reserved_word_for_section(L->owning_section, fname, FUNCTION_COLOUR);
|
|
function *fn = CREATE(function);
|
|
|
|
{
|
|
#line 413 "inweb/Chapter 4/C-Like Languages.w"
|
|
fn->function_name = Str__duplicate(fname);
|
|
fn->function_arguments = Str__duplicate(arguments);
|
|
fn->function_type = Str__new();
|
|
WRITE_TO(fn->function_type, "%S%S %S", qualifiers, ftype, asts);
|
|
fn->within_namespace = FALSE;
|
|
fn->called_from_other_sections = FALSE;
|
|
fn->call_freely = FALSE;
|
|
if (Str__eq_wide_string(fn->function_name, L"isdigit")) fn->call_freely = TRUE;
|
|
fn->function_header_at = L;
|
|
|
|
fn->no_conditionals = cc_sp;
|
|
for (int i=0; i<cc_sp; i++) fn->within_conditionals[i] = cc_stack[i];
|
|
|
|
}
|
|
#line 359 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 427 "inweb/Chapter 4/C-Like Languages.w"
|
|
paragraph *P = L->owning_paragraph;
|
|
if (P) ADD_TO_LINKED_LIST(fn, function, P->functions);
|
|
L->function_defined = fn;
|
|
|
|
}
|
|
#line 360 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
if (W->main_language->supports_namespaces)
|
|
|
|
{
|
|
#line 432 "inweb/Chapter 4/C-Like Languages.w"
|
|
text_stream *declared_namespace = NULL;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, fname, L"(%c+::)%c*")) {
|
|
declared_namespace = mr.exp[0];
|
|
fn->within_namespace = TRUE;
|
|
} else if ((Str__eq_wide_string(fname, L"main")) && (Str__eq_wide_string(S->sect_namespace, L"Main::")))
|
|
declared_namespace = TL_IS_272;
|
|
if ((Str__ne(declared_namespace, S->sect_namespace)) &&
|
|
(L->owning_paragraph->placed_very_early == FALSE)) {
|
|
TEMPORARY_TEXT(err_mess);
|
|
if (Str__len(declared_namespace) == 0)
|
|
WRITE_TO(err_mess, "Function '%S' should have namespace prefix '%S'",
|
|
fname, S->sect_namespace);
|
|
else if (Str__len(S->sect_namespace) == 0)
|
|
WRITE_TO(err_mess, "Function '%S' declared in a section with no namespace",
|
|
fname);
|
|
else
|
|
WRITE_TO(err_mess, "Function '%S' declared in a section with the wrong namespace '%S'",
|
|
fname, S->sect_namespace);
|
|
Main__error_in_web(err_mess, L);
|
|
DISCARD_TEXT(err_mess);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 362 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
}
|
|
#line 323 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
DISCARD_TEXT(ftype);
|
|
DISCARD_TEXT(asts);
|
|
DISCARD_TEXT(fname);
|
|
DISCARD_TEXT(arguments);
|
|
}
|
|
DISCARD_TEXT(qualifiers);
|
|
DISCARD_TEXT(modified);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
}
|
|
#line 52 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
}
|
|
if (cc_sp > 0)
|
|
Main__error_in_web(TL_IS_268, NULL);
|
|
}
|
|
|
|
#line 132 "inweb/Chapter 4/C-Like Languages.w"
|
|
|
|
#line 257 "inweb/Chapter 4/C-Like Languages.w"
|
|
|
|
#line 408 "inweb/Chapter 4/C-Like Languages.w"
|
|
|
|
#line 459 "inweb/Chapter 4/C-Like Languages.w"
|
|
c_structure *CLike__find_structure(web *W, text_stream *name) {
|
|
c_structure *str;
|
|
LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures)
|
|
if (Str__eq(name, str->structure_name))
|
|
return str;
|
|
return NULL;
|
|
}
|
|
|
|
#line 473 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__subcategorise_code(programming_language *self, source_line *L) {
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L"#include <(%C+)>%c*")) {
|
|
text_stream *library_file = mr.exp[0];
|
|
wchar_t *ansi_libs[] = {
|
|
L"assert.h", L"ctype.h", L"errno.h", L"float.h", L"limits.h",
|
|
L"locale.h", L"math.h", L"setjmp.h", L"signal.h", L"stdarg.h",
|
|
L"stddef.h", L"stdio.h", L"stdlib.h", L"string.h", L"time.h",
|
|
NULL
|
|
};
|
|
for (int j = 0; ansi_libs[j]; j++)
|
|
if (Str__eq_wide_string(library_file, ansi_libs[j]))
|
|
L->category = C_LIBRARY_INCLUDE_LCAT;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 502 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__additional_early_matter(programming_language *self, text_stream *OUT, web *W, tangle_target *target) {
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, target)
|
|
if (L->category == C_LIBRARY_INCLUDE_LCAT) {
|
|
Tags__open_ifdefs(OUT, L->owning_paragraph);
|
|
Tangler__tangle_code(OUT, L->text, S, L);
|
|
WRITE("\n");
|
|
Tags__close_ifdefs(OUT, L->owning_paragraph);
|
|
}
|
|
}
|
|
|
|
#line 521 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__additional_predeclarations(programming_language *self, text_stream *OUT, web *W) {
|
|
|
|
{
|
|
#line 550 "inweb/Chapter 4/C-Like Languages.w"
|
|
c_structure *str;
|
|
LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures)
|
|
str->tangled = FALSE;
|
|
LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures)
|
|
CLike__tangle_structure(OUT, self, str);
|
|
|
|
}
|
|
#line 522 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 531 "inweb/Chapter 4/C-Like Languages.w"
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
|
|
if (L->category == TYPEDEF_LCAT) {
|
|
Tags__open_ifdefs(OUT, L->owning_paragraph);
|
|
LanguageMethods__tangle_code(OUT, W->main_language, L->text);
|
|
WRITE("\n");
|
|
Tags__close_ifdefs(OUT, L->owning_paragraph);
|
|
}
|
|
|
|
}
|
|
#line 523 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
|
|
{
|
|
#line 592 "inweb/Chapter 4/C-Like Languages.w"
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W))
|
|
if ((L->function_defined) && (L->owning_paragraph->placed_very_early == FALSE)) {
|
|
function *fn = L->function_defined;
|
|
int to_close = 0;
|
|
for (int i=0; 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 524 "inweb/Chapter 4/C-Like Languages.w"
|
|
;
|
|
}
|
|
|
|
#line 559 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__tangle_structure(OUTPUT_STREAM, programming_language *self, c_structure *str) {
|
|
if (str->tangled != FALSE) return;
|
|
str->tangled = NOT_APPLICABLE;
|
|
c_structure *embodied = NULL;
|
|
LOOP_OVER_LINKED_LIST(embodied, c_structure, str->incorporates)
|
|
CLike__tangle_structure(OUT, self, embodied);
|
|
str->tangled = TRUE;
|
|
Tags__open_ifdefs(OUT, str->typedef_begins->owning_paragraph);
|
|
LanguageMethods__insert_line_marker(OUT, self, str->typedef_begins);
|
|
for (source_line *L = str->typedef_begins; L; L = L->next_line) {
|
|
WRITE("%S\n", L->text);
|
|
L->suppress_tangling = TRUE;
|
|
if (L == str->typedef_ends) break;
|
|
}
|
|
Tags__close_ifdefs(OUT, str->typedef_begins->owning_paragraph);
|
|
}
|
|
|
|
#line 626 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__catalogue(programming_language *self, section *S, int functions_too) {
|
|
c_structure *str;
|
|
LOOP_OVER(str, c_structure)
|
|
if (str->typedef_begins->owning_section == S)
|
|
PRINT(" %S ", str->structure_name);
|
|
if (functions_too) {
|
|
function *fn;
|
|
LOOP_OVER(fn, function)
|
|
if (fn->function_header_at->owning_section == S)
|
|
PRINT("\n %S", fn->function_name);
|
|
}
|
|
}
|
|
|
|
#line 643 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__analyse_code(programming_language *self, web *W) {
|
|
function *fn;
|
|
LOOP_OVER(fn, function)
|
|
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
|
|
fn->function_name, TRUE);
|
|
c_structure *str;
|
|
structure_element *elt;
|
|
LOOP_OVER_LINKED_LIST(str, c_structure, W->c_structures)
|
|
LOOP_OVER_LINKED_LIST(elt, structure_element, str->elements)
|
|
if (elt->allow_sharing == FALSE)
|
|
Analyser__find_hash_entry_for_section(elt->element_created_at->owning_section,
|
|
elt->element_name, TRUE);
|
|
}
|
|
|
|
#line 665 "inweb/Chapter 4/C-Like Languages.w"
|
|
void CLike__post_analysis(programming_language *self, web *W) {
|
|
int check_namespaces = FALSE;
|
|
if (Str__eq_wide_string(Bibliographic__get_datum(W->md, TL_IS_273), L"On")) check_namespaces = TRUE;
|
|
function *fn;
|
|
LOOP_OVER(fn, function) {
|
|
hash_table_entry *hte =
|
|
Analyser__find_hash_entry_for_section(fn->function_header_at->owning_section,
|
|
fn->function_name, FALSE);
|
|
if (hte) {
|
|
hash_table_entry_usage *hteu;
|
|
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages) {
|
|
if ((hteu->form_of_usage & FCALL_USAGE) || (fn->within_namespace))
|
|
if (hteu->usage_recorded_at->under_section != fn->function_header_at->owning_section)
|
|
fn->called_from_other_sections = TRUE;
|
|
}
|
|
}
|
|
if ((fn->within_namespace != fn->called_from_other_sections)
|
|
&& (check_namespaces)
|
|
&& (fn->call_freely == FALSE)) {
|
|
if (fn->within_namespace)
|
|
Main__error_in_web(
|
|
TL_IS_274,
|
|
fn->function_header_at);
|
|
else
|
|
Main__error_in_web(
|
|
TL_IS_275,
|
|
fn->function_header_at);
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 10 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__add_features(programming_language *pl) {
|
|
METHOD_ADD(pl, FURTHER_PARSING_PAR_MTID, InCSupport__further_parsing);
|
|
|
|
METHOD_ADD(pl, SUPPRESS_EXPANSION_TAN_MTID, InCSupport__suppress_expansion);
|
|
METHOD_ADD(pl, TANGLE_COMMAND_TAN_MTID, InCSupport__special_tangle_command);
|
|
METHOD_ADD(pl, ADDITIONAL_PREDECLARATIONS_TAN_MTID, InCSupport__additional_predeclarations);
|
|
METHOD_ADD(pl, WILL_TANGLE_EXTRA_LINE_TAN_MTID, InCSupport__will_insert_in_tangle);
|
|
METHOD_ADD(pl, TANGLE_EXTRA_LINE_TAN_MTID, InCSupport__insert_in_tangle);
|
|
METHOD_ADD(pl, TANGLE_CODE_UNUSUALLY_TAN_MTID, InCSupport__tangle_code);
|
|
METHOD_ADD(pl, GNABEHS_TAN_MTID, InCSupport__gnabehs);
|
|
METHOD_ADD(pl, ADDITIONAL_TANGLING_TAN_MTID, InCSupport__additional_tangling);
|
|
|
|
METHOD_ADD(pl, SKIP_IN_WEAVING_WEA_MTID, InCSupport__skip_in_weaving);
|
|
METHOD_ADD(pl, WEAVE_CODE_LINE_WEA_MTID, InCSupport__weave_code_line);
|
|
METHOD_ADD(pl, NOTIFY_NEW_TAG_WEA_MTID, InCSupport__new_tag_declared);
|
|
|
|
METHOD_ADD(pl, EARLY_PREWEAVE_ANALYSIS_ANA_MTID, InCSupport__analyse_code);
|
|
METHOD_ADD(pl, SHARE_ELEMENT_ANA_MTID, InCSupport__share_element);
|
|
}
|
|
|
|
#line 33 "inweb/Chapter 4/InC Support.w"
|
|
theme_tag *Preform_theme = NULL;
|
|
|
|
#line 39 "inweb/Chapter 4/InC Support.w"
|
|
preform_nonterminal *alphabetical_list_of_nonterminals = NULL;
|
|
|
|
void InCSupport__further_parsing(programming_language *self, web *W) {
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, Tangler__primary_target(W)) {
|
|
|
|
{
|
|
#line 66 "inweb/Chapter 4/InC Support.w"
|
|
int form = NOT_A_NONTERMINAL; /* one of the four values above, or a non-negative word count */
|
|
TEMPORARY_TEXT(pntname);
|
|
TEMPORARY_TEXT(header);
|
|
|
|
{
|
|
#line 79 "inweb/Chapter 4/InC Support.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L"(<%p+>) ::=%c*")) {
|
|
form = A_GRAMMAR_NONTERMINAL;
|
|
Str__copy(pntname, mr.exp[0]);
|
|
Str__copy(header, mr.exp[0]);
|
|
|
|
{
|
|
#line 217 "inweb/Chapter 4/InC Support.w"
|
|
source_line *AL;
|
|
for (AL = L; (AL) && (AL->category == CODE_BODY_LCAT); AL = AL->next_line) {
|
|
if (Regexp__string_is_white_space(AL->text)) break;
|
|
AL->category = PREFORM_GRAMMAR_LCAT;
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, AL->text, L"(%c+) ==> (%c*)")) {
|
|
AL->text_operand = Str__duplicate(mr.exp[0]);
|
|
AL->text_operand2 = Str__duplicate(mr.exp[1]);
|
|
} else {
|
|
AL->text_operand = AL->text;
|
|
AL->text_operand2 = Str__new();
|
|
}
|
|
|
|
{
|
|
#line 243 "inweb/Chapter 4/InC Support.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, AL->text_operand, L"(%c*)%/%*%c*%*%/ *"))
|
|
AL->text_operand = Str__duplicate(mr.exp[0]);
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 230 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
|
|
{
|
|
#line 253 "inweb/Chapter 4/InC Support.w"
|
|
TEMPORARY_TEXT(to_scan); Str__copy(to_scan, AL->text_operand2);
|
|
match_results mr = Regexp__create_mr();
|
|
while (Regexp__match(&mr, to_scan, L"%c*?<<(%P+?)>> =(%c*)")) {
|
|
TEMPORARY_TEXT(var_given); Str__copy(var_given, mr.exp[0]);
|
|
TEMPORARY_TEXT(type_given); WRITE_TO(type_given, "int");
|
|
Str__copy(to_scan, mr.exp[1]);
|
|
if (Regexp__match(&mr, var_given, L"(%p+):%p+")) {
|
|
Str__clear(type_given);
|
|
WRITE_TO(type_given, "%S *", mr.exp[0]);
|
|
}
|
|
nonterminal_variable *ntv;
|
|
LOOP_OVER(ntv, nonterminal_variable)
|
|
if (Str__eq(ntv->ntv_name, var_given))
|
|
break;
|
|
if (ntv == NULL)
|
|
{
|
|
#line 288 "inweb/Chapter 4/InC Support.w"
|
|
ntv = CREATE(nonterminal_variable);
|
|
ntv->ntv_name = Str__duplicate(var_given);
|
|
ntv->ntv_type = Str__duplicate(type_given);
|
|
LOOP_THROUGH_TEXT(P, var_given)
|
|
if ((Str__get(P) == '-') || (Str__get(P) == ':'))
|
|
Str__put(P, '_');
|
|
ntv->ntv_identifier = Str__new();
|
|
WRITE_TO(ntv->ntv_identifier, "%S_NTMV", var_given);
|
|
ntv->first_mention = AL;
|
|
|
|
}
|
|
#line 267 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
DISCARD_TEXT(var_given);
|
|
DISCARD_TEXT(type_given);
|
|
}
|
|
DISCARD_TEXT(to_scan);
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 231 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
}
|
|
#line 84 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
} else if (Regexp__match(&mr, L->text, L"((<%p+>) internal %?) {%c*")) {
|
|
form = A_VORACIOUS_NONTERMINAL;
|
|
Str__copy(pntname, mr.exp[1]);
|
|
Str__copy(header, mr.exp[0]);
|
|
} else if (Regexp__match(&mr, L->text, L"((<%p+>) internal) {%c*")) {
|
|
form = A_FLEXIBLE_NONTERMINAL;
|
|
Str__copy(pntname, mr.exp[1]);
|
|
Str__copy(header, mr.exp[0]);
|
|
} else if (Regexp__match(&mr, L->text, L"((<%p+>) internal (%d+)) {%c*")) {
|
|
form = Str__atoi(mr.exp[2], 0);
|
|
Str__copy(pntname, mr.exp[1]);
|
|
Str__copy(header, mr.exp[0]);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 69 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
if (form != NOT_A_NONTERMINAL)
|
|
{
|
|
#line 121 "inweb/Chapter 4/InC Support.w"
|
|
preform_nonterminal *pnt = CREATE(preform_nonterminal);
|
|
pnt->where_defined = L;
|
|
pnt->nt_name = Str__duplicate(pntname);
|
|
pnt->unangled_name = Str__duplicate(pntname);
|
|
pnt->as_C_identifier = Str__duplicate(pntname);
|
|
pnt->next_pnt_alphabetically = NULL;
|
|
|
|
{
|
|
#line 135 "inweb/Chapter 4/InC Support.w"
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, pntname, L"%<(%c*)%>")) pnt->unangled_name = Str__duplicate(mr.exp[0]);
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 127 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
|
|
{
|
|
#line 145 "inweb/Chapter 4/InC Support.w"
|
|
Str__delete_first_character(pnt->as_C_identifier);
|
|
LOOP_THROUGH_TEXT(pos, pnt->as_C_identifier) {
|
|
if (Str__get(pos) == '-') Str__put(pos, '_');
|
|
if (Str__get(pos) == '>') { Str__put(pos, 0); break; }
|
|
}
|
|
WRITE_TO(pnt->as_C_identifier, "_NTM");
|
|
|
|
}
|
|
#line 128 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
|
|
{
|
|
#line 160 "inweb/Chapter 4/InC Support.w"
|
|
pnt->voracious = FALSE; if (form == A_VORACIOUS_NONTERMINAL) pnt->voracious = TRUE;
|
|
pnt->as_function = TRUE; if (form == A_GRAMMAR_NONTERMINAL) pnt->as_function = FALSE;
|
|
|
|
pnt->takes_pointer_result = FALSE;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, pnt->nt_name, L"<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 678 "inweb/Chapter 4/InC Support.w"
|
|
if ((i > 0) && (Str__get_at(original, i) == ':') && (Str__get_at(original, i+1) == ':') &&
|
|
(isalpha(Str__get_at(original, i+2))) && (isalnum(Str__get_at(original, i-1)))) {
|
|
WRITE("__"); i++;
|
|
continue;
|
|
}
|
|
|
|
}
|
|
#line 639 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
if (Str__get_at(original, i) == '<') {
|
|
if (Str__get_at(original, i+1) == '<') {
|
|
|
|
{
|
|
#line 690 "inweb/Chapter 4/InC Support.w"
|
|
match_results mr = Regexp__create_mr();
|
|
TEMPORARY_TEXT(check_this);
|
|
Str__substr(check_this, Str__at(original, i), Str__end(original));
|
|
if (Regexp__match(&mr, check_this, L"<<(%P+)>>%c*")) {
|
|
text_stream *putative = mr.exp[0];
|
|
text_stream *pv_identifier = InCSupport__nonterminal_variable_identifier(putative);
|
|
if (pv_identifier) {
|
|
WRITE("%S", pv_identifier);
|
|
i += Str__len(putative) + 3;
|
|
DISCARD_TEXT(check_this);
|
|
continue;
|
|
}
|
|
}
|
|
DISCARD_TEXT(check_this);
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 642 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
} else {
|
|
|
|
{
|
|
#line 722 "inweb/Chapter 4/InC Support.w"
|
|
match_results mr = Regexp__create_mr();
|
|
TEMPORARY_TEXT(check_this);
|
|
Str__substr(check_this, Str__at(original, i), Str__end(original));
|
|
if (Regexp__match(&mr, check_this, L"(<%p+>)%c*")) {
|
|
text_stream *putative = mr.exp[0];
|
|
preform_nonterminal *pnt = InCSupport__nonterminal_by_name(putative);
|
|
if (pnt) {
|
|
i += Str__len(putative) - 1;
|
|
if (Str__get_at(original, i+1) == '(') {
|
|
int arity = 1;
|
|
for (int j = i+2, bl = 1; ((Str__get_at(original, j)) && (bl > 0)); j++) {
|
|
if (Str__get_at(original, j) == '(') bl++;
|
|
if (Str__get_at(original, j) == ')') { bl--; if (bl == 0) fcall_pos = j; }
|
|
if ((Str__get_at(original, j) == ',') && (bl == 1)) arity++;
|
|
}
|
|
WRITE("Preform__parse_nt_against_word_range(");
|
|
}
|
|
WRITE("%S", pnt->as_C_identifier);
|
|
if (fcall_pos >= 0) {
|
|
WRITE(", "); i++;
|
|
}
|
|
DISCARD_TEXT(check_this);
|
|
continue;
|
|
}
|
|
}
|
|
DISCARD_TEXT(check_this);
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 644 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
}
|
|
}
|
|
if (i == fcall_pos) {
|
|
fcall_pos = -1;
|
|
WRITE(", NULL, NULL");
|
|
}
|
|
PUT(Str__get_at(original, i));
|
|
}
|
|
}
|
|
|
|
#line 756 "inweb/Chapter 4/InC Support.w"
|
|
preform_nonterminal *InCSupport__nonterminal_by_name(text_stream *name) {
|
|
preform_nonterminal *pnt;
|
|
LOOP_OVER(pnt, preform_nonterminal)
|
|
if (Str__eq(name, pnt->nt_name))
|
|
return pnt;
|
|
return NULL;
|
|
}
|
|
|
|
#line 770 "inweb/Chapter 4/InC Support.w"
|
|
text_stream *InCSupport__nonterminal_variable_identifier(text_stream *name) {
|
|
if (Str__eq_wide_string(name, L"r")) return TL_IS_280;
|
|
if (Str__eq_wide_string(name, L"rp")) return TL_IS_281;
|
|
nonterminal_variable *ntv;
|
|
LOOP_OVER(ntv, nonterminal_variable)
|
|
if (Str__eq(ntv->ntv_name, name))
|
|
return ntv->ntv_identifier;
|
|
return NULL;
|
|
}
|
|
|
|
#line 791 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__additional_tangling(programming_language *self, web *W, tangle_target *target) {
|
|
if (NUMBER_CREATED(preform_nonterminal) > 0) {
|
|
pathname *P = Reader__tangled_folder(W);
|
|
filename *Syntax = Filenames__in_folder(P, TL_IS_282);
|
|
|
|
text_stream TO_struct;
|
|
text_stream *OUT = &TO_struct;
|
|
if (STREAM_OPEN_TO_FILE(OUT, Syntax, ISO_ENC) == FALSE)
|
|
Errors__fatal_with_file("unable to write Preform file", Syntax);
|
|
|
|
WRITE_TO(STDOUT, "Writing Preform syntax to: %/f\n", Syntax);
|
|
|
|
WRITE("[Preform syntax generated by inweb: do not edit.]\n\n");
|
|
|
|
if (Bibliographic__data_exists(W->md, TL_IS_283))
|
|
WRITE("language %S\n", Bibliographic__get_datum(W->md, TL_IS_284));
|
|
|
|
|
|
{
|
|
#line 826 "inweb/Chapter 4/InC Support.w"
|
|
chapter *C;
|
|
section *S;
|
|
LOOP_WITHIN_TANGLE(C, S, target)
|
|
if (L->category == PREFORM_LCAT) {
|
|
preform_nonterminal *pnt = L->preform_nonterminal_defined;
|
|
if (pnt->as_function)
|
|
WRITE("\n%S internal\n", pnt->nt_name);
|
|
else
|
|
WRITE("\n%S ::=\n", L->text_operand);
|
|
for (source_line *AL = L->next_line;
|
|
((AL) && (AL->category == PREFORM_GRAMMAR_LCAT));
|
|
AL = AL->next_line) {
|
|
WRITE("%S", AL->text_operand);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, AL->text_operand2, L"%c+Issue (%c+) problem%c+"))
|
|
WRITE("[issues %S]", mr.exp[0]);
|
|
WRITE("\n");
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 808 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
STREAM_CLOSE(OUT);
|
|
}
|
|
}
|
|
|
|
#line 853 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__weave_grammar_index(OUTPUT_STREAM) {
|
|
WRITE("\\raggedright\\tolerance=10000");
|
|
preform_nonterminal *pnt;
|
|
for (pnt = alphabetical_list_of_nonterminals; pnt;
|
|
pnt = pnt->next_pnt_alphabetically) {
|
|
WRITE("\\line{\\nonterminal{%S}%s"
|
|
"\\leaders\\hbox to 1em{\\hss.\\hss}\\hfill {\\xreffont %S}}\n",
|
|
pnt->unangled_name,
|
|
(pnt->as_function)?" (internal)":"",
|
|
pnt->where_defined->owning_section->sect_range);
|
|
int said_something = FALSE;
|
|
|
|
{
|
|
#line 900 "inweb/Chapter 4/InC Support.w"
|
|
section *S;
|
|
LOOP_OVER(S, section) S->scratch_flag = FALSE;
|
|
hash_table_entry *hte = Analyser__find_hash_entry_for_section(
|
|
pnt->where_defined->owning_section, pnt->unangled_name, FALSE);
|
|
hash_table_entry_usage *hteu;
|
|
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
|
|
if (hteu->form_of_usage & PREFORM_IN_GRAMMAR_USAGE)
|
|
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
|
|
int use_count = 0;
|
|
LOOP_OVER(S, section)
|
|
if (S->scratch_flag)
|
|
use_count++;
|
|
if (use_count > 0) {
|
|
said_something = TRUE;
|
|
WRITE("\\par\\hangindent=3em{\\it used by other nonterminals in} ");
|
|
int c = 0;
|
|
LOOP_OVER(S, section)
|
|
if (S->scratch_flag) {
|
|
if (c++ > 0) WRITE(", ");
|
|
WRITE("{\\xreffont %S}", S->sect_range);
|
|
}
|
|
WRITE("\n\n");
|
|
}
|
|
|
|
}
|
|
#line 864 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
|
|
{
|
|
#line 875 "inweb/Chapter 4/InC Support.w"
|
|
section *S;
|
|
LOOP_OVER(S, section) S->scratch_flag = FALSE;
|
|
hash_table_entry *hte = Analyser__find_hash_entry_for_section(
|
|
pnt->where_defined->owning_section, pnt->unangled_name, FALSE);
|
|
hash_table_entry_usage *hteu;
|
|
LOOP_OVER_LINKED_LIST(hteu, hash_table_entry_usage, hte->usages)
|
|
if (hteu->form_of_usage & PREFORM_IN_CODE_USAGE)
|
|
hteu->usage_recorded_at->under_section->scratch_flag = TRUE;
|
|
int use_count = 0;
|
|
LOOP_OVER(S, section)
|
|
if (S->scratch_flag)
|
|
use_count++;
|
|
if (use_count > 0) {
|
|
said_something = TRUE;
|
|
WRITE("\\par\\hangindent=3em{\\it called from} ");
|
|
int c = 0;
|
|
LOOP_OVER(S, section)
|
|
if (S->scratch_flag) {
|
|
if (c++ > 0) WRITE(", ");
|
|
WRITE("{\\xreffont %S}", S->sect_range);
|
|
}
|
|
WRITE("\n\n");
|
|
}
|
|
|
|
}
|
|
#line 865 "inweb/Chapter 4/InC Support.w"
|
|
;
|
|
if (said_something == FALSE)
|
|
WRITE("\\par\\hangindent=3em{\\it unused}\n\n");
|
|
}
|
|
WRITE("\\penalty-1000\n");
|
|
WRITE("\\smallbreak\n");
|
|
WRITE("\\hrule\\smallbreak\n");
|
|
}
|
|
|
|
#line 929 "inweb/Chapter 4/InC Support.w"
|
|
int skipping_internal = FALSE, preform_production_count = 0;
|
|
|
|
int InCSupport__skip_in_weaving(programming_language *self, weave_target *wv, source_line *L) {
|
|
if ((Preform_theme) && (wv->theme_match == Preform_theme)) {
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, L->text, L"}%c*")) {
|
|
skipping_internal = FALSE; Regexp__dispose_of(&mr); return TRUE; }
|
|
if (skipping_internal) { Regexp__dispose_of(&mr); return TRUE; }
|
|
if (Regexp__match(&mr, L->text, L"<%c*?> internal%c*")) skipping_internal = TRUE;
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#line 946 "inweb/Chapter 4/InC Support.w"
|
|
int InCSupport__weave_code_line(programming_language *self, text_stream *OUT,
|
|
weave_target *wv, web *W, chapter *C, section *S, source_line *L,
|
|
text_stream *matter, text_stream *concluding_comment) {
|
|
if ((Preform_theme) && (wv->theme_match == Preform_theme))
|
|
return Formats__preform_document(OUT, wv, W, C, S, L,
|
|
matter, concluding_comment);
|
|
return FALSE;
|
|
}
|
|
|
|
#line 960 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__new_tag_declared(programming_language *self, theme_tag *tag) {
|
|
if (Str__eq_wide_string(tag->tag_name, L"Preform")) Preform_theme = tag;
|
|
}
|
|
|
|
#line 967 "inweb/Chapter 4/InC Support.w"
|
|
void InCSupport__analyse_code(programming_language *self, web *W) {
|
|
preform_nonterminal *pnt;
|
|
LOOP_OVER(pnt, preform_nonterminal)
|
|
Analyser__find_hash_entry_for_section(pnt->where_defined->owning_section,
|
|
pnt->unangled_name, TRUE);
|
|
}
|
|
|
|
int InCSupport__share_element(programming_language *self, text_stream *elname) {
|
|
if (Str__eq_wide_string(elname, L"word_ref1")) return TRUE;
|
|
if (Str__eq_wide_string(elname, L"word_ref2")) return TRUE;
|
|
if (Str__eq_wide_string(elname, L"next")) return TRUE;
|
|
if (Str__eq_wide_string(elname, L"down")) return TRUE;
|
|
if (Str__eq_wide_string(elname, L"allocation_id")) return TRUE;
|
|
if (Str__eq_wide_string(elname, L"method_set")) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
#line 17 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
weave_format *Formats__create_weave_format(text_stream *name, text_stream *ext) {
|
|
weave_format *wf = CREATE(weave_format);
|
|
wf->format_name = Str__duplicate(name);
|
|
wf->woven_extension = Str__duplicate(ext);
|
|
ENABLE_METHOD_CALLS(wf);
|
|
return wf;
|
|
}
|
|
|
|
weave_format *Formats__find_by_name(text_stream *name) {
|
|
weave_format *wf;
|
|
LOOP_OVER(wf, weave_format)
|
|
if (Str__eq_insensitive(name, wf->format_name))
|
|
return wf;
|
|
return NULL;
|
|
}
|
|
|
|
#line 40 "inweb/Chapter 5/Weave Formats.w"
|
|
text_stream *Formats__file_extension(weave_format *wf) {
|
|
return wf->woven_extension;
|
|
}
|
|
|
|
#line 48 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__create_weave_formats(void) {
|
|
TeX__create();
|
|
PlainText__create();
|
|
HTMLFormat__create();
|
|
}
|
|
|
|
#line 67 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 69 "inweb/Chapter 5/Weave Formats.w"
|
|
IMETHOD_TYPE(BEGIN_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern)
|
|
VMETHOD_TYPE(END_WEAVING_FOR_MTID, weave_format *wf, web *W, weave_pattern *pattern)
|
|
int Formats__begin_weaving(web *W, weave_pattern *pattern) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, pattern->pattern_format, BEGIN_WEAVING_FOR_MTID, W, pattern);
|
|
if (rv) return rv;
|
|
return SWARM_OFF_SWM;
|
|
}
|
|
void Formats__end_weaving(web *W, weave_pattern *pattern) {
|
|
VMETHOD_CALL(pattern->pattern_format, END_WEAVING_FOR_MTID, W, pattern);
|
|
}
|
|
|
|
#line 89 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 91 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(TOP_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *comment)
|
|
void Formats__top(OUTPUT_STREAM, weave_target *wv, text_stream *comment) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, TOP_FOR_MTID, OUT, wv, comment);
|
|
}
|
|
|
|
#line 106 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 108 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(TOC_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
int stage, text_stream *text1, text_stream *text2, paragraph *P)
|
|
void Formats__toc(OUTPUT_STREAM, weave_target *wv, int stage, text_stream *text1,
|
|
text_stream *text2, paragraph *P) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, TOC_FOR_MTID, OUT, wv, stage, text1, text2, P);
|
|
}
|
|
|
|
#line 121 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 123 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(CHAPTER_TP_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, chapter *C)
|
|
void Formats__chapter_title_page(OUTPUT_STREAM, weave_target *wv, chapter *C) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, CHAPTER_TP_FOR_MTID, OUT, wv, C);
|
|
}
|
|
|
|
#line 141 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 143 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(SUBHEADING_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
int level, text_stream *heading, text_stream *addendum)
|
|
void Formats__subheading(OUTPUT_STREAM, weave_target *wv, int level,
|
|
text_stream *heading, text_stream *addendum) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, SUBHEADING_FOR_MTID, OUT, wv, level, heading, addendum);
|
|
}
|
|
|
|
#line 165 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 167 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(PARAGRAPH_HEADING_FOR_MTID, weave_format *wf, text_stream *OUT,
|
|
weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P,
|
|
text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark, int weight)
|
|
void Formats__paragraph_heading(OUTPUT_STREAM, weave_target *wv, text_stream *TeX_macro,
|
|
section *S, paragraph *P, text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark,
|
|
int weight) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, PARAGRAPH_HEADING_FOR_MTID, OUT, wv, TeX_macro, S, P, heading_text, chaptermark, sectionmark, weight);
|
|
}
|
|
|
|
#line 183 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 185 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(SOURCE_CODE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter,
|
|
text_stream *colouring, text_stream *concluding_comment, int starts, int finishes,
|
|
int code_mode)
|
|
|
|
void Formats__source_code(OUTPUT_STREAM, weave_target *wv, int tab_stops_of_indentation,
|
|
text_stream *prefatory, text_stream *matter, text_stream *colouring,
|
|
text_stream *concluding_comment, int starts, int finishes, int code_mode) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, SOURCE_CODE_FOR_MTID, OUT, wv, tab_stops_of_indentation,
|
|
prefatory, matter, colouring, concluding_comment, starts, finishes, code_mode);
|
|
}
|
|
|
|
#line 203 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 205 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(INLINE_CODE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int pre)
|
|
void Formats__source_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, INLINE_CODE_FOR_MTID, OUT, wv, TRUE);
|
|
TEMPORARY_TEXT(colouring);
|
|
for (int i=0; i< Str__len(fragment); i++) PUT_TO(colouring, EXTRACT_COLOUR);
|
|
Formats__source_code(OUT, wv, 0, TL_IS_285, fragment, colouring, TL_IS_286, FALSE, FALSE, TRUE);
|
|
DISCARD_TEXT(colouring);
|
|
VMETHOD_CALL(wf, INLINE_CODE_FOR_MTID, OUT, wv, FALSE);
|
|
}
|
|
|
|
#line 220 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 222 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(DISPLAY_LINE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, text_stream *from)
|
|
void Formats__display_line(OUTPUT_STREAM, weave_target *wv, text_stream *from) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, DISPLAY_LINE_FOR_MTID, OUT, wv, from);
|
|
}
|
|
|
|
#line 241 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 243 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(ITEM_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
int depth, text_stream *label)
|
|
void Formats__item(OUTPUT_STREAM, weave_target *wv, int depth, text_stream *label) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, ITEM_FOR_MTID, OUT, wv, depth, label);
|
|
}
|
|
|
|
#line 254 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 256 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(BAR_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv)
|
|
void Formats__bar(OUTPUT_STREAM, weave_target *wv) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, BAR_FOR_MTID, OUT, wv);
|
|
}
|
|
|
|
#line 267 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 269 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(FIGURE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
text_stream *figname, int w, int h, programming_language *pl)
|
|
void Formats__figure(OUTPUT_STREAM, weave_target *wv, text_stream *figname,
|
|
int w, int h, programming_language *pl) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, FIGURE_FOR_MTID, OUT, wv, figname, w, h, pl);
|
|
}
|
|
|
|
#line 282 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 284 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(PARA_MACRO_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
para_macro *pmac, int defn)
|
|
void Formats__para_macro(OUTPUT_STREAM, weave_target *wv, para_macro *pmac, int defn) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, PARA_MACRO_FOR_MTID, OUT, wv, pmac, defn);
|
|
}
|
|
|
|
#line 296 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 298 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(PAGEBREAK_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv)
|
|
void Formats__pagebreak(OUTPUT_STREAM, weave_target *wv) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, PAGEBREAK_FOR_MTID, OUT, wv);
|
|
}
|
|
|
|
#line 310 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 312 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(BLANK_LINE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
int in_comment)
|
|
void Formats__blank_line(OUTPUT_STREAM, weave_target *wv, int in_comment) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, BLANK_LINE_FOR_MTID, OUT, wv, in_comment);
|
|
}
|
|
|
|
#line 325 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 327 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(AFTER_DEFINITIONS_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv)
|
|
void Formats__after_definitions(OUTPUT_STREAM, weave_target *wv) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, AFTER_DEFINITIONS_FOR_MTID, OUT, wv);
|
|
}
|
|
|
|
#line 340 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 342 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(CHANGE_MATERIAL_FOR_MTID, weave_format *wf, text_stream *OUT,
|
|
weave_target *wv, int old_material, int new_material, int content)
|
|
void Formats__change_material(OUTPUT_STREAM, weave_target *wv,
|
|
int old_material, int new_material, int content) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, CHANGE_MATERIAL_FOR_MTID, OUT, wv, old_material, new_material, content);
|
|
}
|
|
|
|
#line 356 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 358 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(CHANGE_COLOUR_FOR_MTID, weave_format *wf, text_stream *OUT,
|
|
weave_target *wv, int col, int in_code)
|
|
void Formats__change_colour(OUTPUT_STREAM, weave_target *wv, int col, int in_code) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, CHANGE_COLOUR_FOR_MTID, OUT, wv, col, in_code);
|
|
}
|
|
|
|
#line 371 "inweb/Chapter 5/Weave Formats.w"
|
|
void Formats__text(OUTPUT_STREAM, weave_target *wv, text_stream *id) {
|
|
Formats__text_r(OUT, wv, id, FALSE);
|
|
}
|
|
|
|
void Formats__text_r(OUTPUT_STREAM, weave_target *wv, text_stream *id, int within) {
|
|
for (int i=0; i < Str__len(id); i++) {
|
|
if (Str__get_at(id, i) == '\\') i++;
|
|
else if (Str__get_at(id, i) == '|') {
|
|
TEMPORARY_TEXT(before);
|
|
Str__copy(before, id); Str__truncate(before, i);
|
|
TEMPORARY_TEXT(after);
|
|
Str__substr(after, Str__at(id, i+1), Str__end(id));
|
|
Formats__text_r(OUT, wv, before, within);
|
|
Formats__text_r(OUT, wv, after, (within)?FALSE:TRUE);
|
|
DISCARD_TEXT(before);
|
|
DISCARD_TEXT(after);
|
|
return;
|
|
}
|
|
}
|
|
if (within) {
|
|
Formats__source_fragment(OUT, wv, id);
|
|
} else {
|
|
Formats__text_fragment(OUT, wv, id);
|
|
}
|
|
}
|
|
|
|
#line 405 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 407 "inweb/Chapter 5/Weave Formats.w"
|
|
IMETHOD_TYPE(PRESERVE_MATH_MODE_FOR_MTID, weave_format *wf,
|
|
text_stream *matter, text_stream *id)
|
|
VMETHOD_TYPE(COMMENTARY_TEXT_FOR_MTID, weave_format *wf, text_stream *OUT,
|
|
weave_target *wv, text_stream *matter)
|
|
|
|
void Formats__text_fragment(OUTPUT_STREAM, weave_target *wv, text_stream *fragment) {
|
|
weave_format *wf = wv->format;
|
|
TEMPORARY_TEXT(matter);
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, wf, PRESERVE_MATH_MODE_FOR_MTID, matter, fragment);
|
|
if (rv == FALSE) TeX__remove_math_mode(matter, fragment);
|
|
else Str__copy(matter, fragment);
|
|
VMETHOD_CALL(wf, COMMENTARY_TEXT_FOR_MTID, OUT, wv, matter);
|
|
DISCARD_TEXT(matter);
|
|
}
|
|
|
|
#line 428 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 430 "inweb/Chapter 5/Weave Formats.w"
|
|
IMETHOD_TYPE(PREFORM_DOCUMENT_FOR_MTID, weave_format *wf, text_stream *OUT,
|
|
weave_target *wv, web *W, chapter *C, section *S, source_line *L,
|
|
text_stream *matter, text_stream *concluding_comment)
|
|
int Formats__preform_document(OUTPUT_STREAM, weave_target *wv, web *W,
|
|
chapter *C, section *S, source_line *L, text_stream *matter,
|
|
text_stream *concluding_comment) {
|
|
weave_format *wf = wv->format;
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, wf, PREFORM_DOCUMENT_FOR_MTID, OUT, wv, W, C, S, L, matter,
|
|
concluding_comment);
|
|
return rv;
|
|
}
|
|
|
|
#line 448 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 450 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(ENDNOTE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv, int end)
|
|
void Formats__endnote(OUTPUT_STREAM, weave_target *wv, int end) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, ENDNOTE_FOR_MTID, OUT, wv, end);
|
|
}
|
|
|
|
#line 462 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 464 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(LOCALE_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
paragraph *par1, paragraph *par2)
|
|
void Formats__locale(OUTPUT_STREAM, weave_target *wv, paragraph *par1, paragraph *par2) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, LOCALE_FOR_MTID, OUT, wv, par1, par2);
|
|
}
|
|
|
|
#line 475 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 477 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(TAIL_FOR_MTID, weave_format *wf, text_stream *OUT, weave_target *wv,
|
|
text_stream *comment, section *S)
|
|
void Formats__tail(OUTPUT_STREAM, weave_target *wv, text_stream *comment, section *S) {
|
|
weave_format *wf = wv->format;
|
|
VMETHOD_CALL(wf, TAIL_FOR_MTID, OUT, wv, comment, S);
|
|
}
|
|
|
|
#line 492 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 494 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(POST_PROCESS_POS_MTID, weave_format *wf, weave_target *wv, int open_afterwards)
|
|
void Formats__post_process_weave(weave_target *wv, int open_afterwards) {
|
|
VMETHOD_CALL(wv->format, POST_PROCESS_POS_MTID, wv, open_afterwards);
|
|
}
|
|
|
|
#line 503 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 505 "inweb/Chapter 5/Weave Formats.w"
|
|
VMETHOD_TYPE(POST_PROCESS_REPORT_POS_MTID, weave_format *wf, weave_target *wv)
|
|
void Formats__report_on_post_processing(weave_target *wv) {
|
|
VMETHOD_CALL(wv->format, POST_PROCESS_REPORT_POS_MTID, wv);
|
|
}
|
|
|
|
#line 515 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 517 "inweb/Chapter 5/Weave Formats.w"
|
|
IMETHOD_TYPE(INDEX_PDFS_POS_MTID, weave_format *wf)
|
|
int Formats__index_pdfs(text_stream *format) {
|
|
weave_format *wf = Formats__find_by_name(format);
|
|
if (wf == NULL) return FALSE;
|
|
int rv = FALSE;
|
|
IMETHOD_CALLV(rv, wf, INDEX_PDFS_POS_MTID);
|
|
return rv;
|
|
}
|
|
|
|
#line 530 "inweb/Chapter 5/Weave Formats.w"
|
|
|
|
#line 532 "inweb/Chapter 5/Weave Formats.w"
|
|
IMETHOD_TYPE(POST_PROCESS_SUBSTITUTE_POS_MTID, weave_format *wf, text_stream *OUT,
|
|
weave_target *wv, text_stream *detail, weave_pattern *pattern)
|
|
int Formats__substitute_post_processing_data(OUTPUT_STREAM, weave_target *wv,
|
|
text_stream *detail, weave_pattern *pattern) {
|
|
int rv = FALSE;
|
|
IMETHOD_CALL(rv, wv->format, POST_PROCESS_SUBSTITUTE_POS_MTID, OUT, wv, detail, pattern);
|
|
return rv;
|
|
}
|
|
|
|
#line 9 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__create(void) {
|
|
weave_format *wf = Formats__create_weave_format(TL_IS_287, TL_IS_288);
|
|
METHOD_ADD(wf, TOP_FOR_MTID, PlainText__top);
|
|
METHOD_ADD(wf, SUBHEADING_FOR_MTID, PlainText__subheading);
|
|
METHOD_ADD(wf, TOC_FOR_MTID, PlainText__toc);
|
|
METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, PlainText__chapter_title_page);
|
|
METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, PlainText__paragraph_heading);
|
|
METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, PlainText__source_code);
|
|
METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, PlainText__display_line);
|
|
METHOD_ADD(wf, ITEM_FOR_MTID, PlainText__item);
|
|
METHOD_ADD(wf, BAR_FOR_MTID, PlainText__bar);
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, PlainText__para_macro);
|
|
METHOD_ADD(wf, BLANK_LINE_FOR_MTID, PlainText__blank_line);
|
|
METHOD_ADD(wf, ENDNOTE_FOR_MTID, PlainText__endnote);
|
|
METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, PlainText__commentary_text);
|
|
METHOD_ADD(wf, LOCALE_FOR_MTID, PlainText__locale);
|
|
METHOD_ADD(wf, TAIL_FOR_MTID, PlainText__tail);
|
|
}
|
|
|
|
#line 32 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__top(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *comment) {
|
|
WRITE("[%S]\n", comment);
|
|
}
|
|
|
|
#line 38 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__subheading(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int level, text_stream *comment, text_stream *head) {
|
|
WRITE("%S:\n", comment);
|
|
if ((level == 2) && (head)) { Formats__text(OUT, wv, head); WRITE("\n\n"); }
|
|
}
|
|
|
|
#line 45 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage,
|
|
text_stream *text1, text_stream *text2, paragraph *P) {
|
|
switch (stage) {
|
|
case 1: WRITE("%S.", text1); break;
|
|
case 2: WRITE("; "); break;
|
|
case 3: WRITE("%S %S", text1, text2); break;
|
|
case 4: WRITE("\n\n"); break;
|
|
}
|
|
}
|
|
|
|
#line 56 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__chapter_title_page(weave_format *self, text_stream *OUT,
|
|
weave_target *wv, chapter *C) {
|
|
WRITE("%S\n\n", C->md->rubric);
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections)
|
|
WRITE(" %S: %S\n %S\n",
|
|
S->sect_range, S->md->sect_title, S->sect_purpose);
|
|
}
|
|
|
|
#line 66 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text,
|
|
text_stream *chaptermark, text_stream *sectionmark, int weight) {
|
|
if (P) {
|
|
WRITE("\n");
|
|
Formats__locale(OUT, wv, P, NULL);
|
|
WRITE(". %S ", heading_text);
|
|
} else {
|
|
WRITE("%S\n\n", heading_text);
|
|
}
|
|
}
|
|
|
|
#line 79 "inweb/Chapter 5/Plain Text Format.w"
|
|
void PlainText__source_code(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter,
|
|
text_stream *colouring, text_stream *concluding_comment, int starts,
|
|
int finishes, int code_mode) {
|
|
if (starts) {
|
|
for (int i=0; i<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_289, TL_IS_290);
|
|
|
|
{
|
|
#line 40 "inweb/Chapter 5/TeX Format.w"
|
|
METHOD_ADD(wf, TOP_FOR_MTID, TeX__top);
|
|
METHOD_ADD(wf, SUBHEADING_FOR_MTID, TeX__subheading);
|
|
METHOD_ADD(wf, TOC_FOR_MTID, TeX__toc);
|
|
METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, TeX__chapter_title_page);
|
|
METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, TeX__paragraph_heading);
|
|
METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, TeX__source_code);
|
|
METHOD_ADD(wf, INLINE_CODE_FOR_MTID, TeX__inline_code);
|
|
METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, TeX__display_line);
|
|
METHOD_ADD(wf, ITEM_FOR_MTID, TeX__item);
|
|
METHOD_ADD(wf, BAR_FOR_MTID, TeX__bar);
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro);
|
|
METHOD_ADD(wf, PAGEBREAK_FOR_MTID, TeX__pagebreak);
|
|
METHOD_ADD(wf, BLANK_LINE_FOR_MTID, TeX__blank_line);
|
|
METHOD_ADD(wf, AFTER_DEFINITIONS_FOR_MTID, TeX__after_definitions);
|
|
METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, TeX__change_material);
|
|
METHOD_ADD(wf, ENDNOTE_FOR_MTID, TeX__endnote);
|
|
METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, TeX__commentary_text);
|
|
METHOD_ADD(wf, LOCALE_FOR_MTID, TeX__locale);
|
|
METHOD_ADD(wf, TAIL_FOR_MTID, TeX__tail);
|
|
METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX__preform_document);
|
|
METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute);
|
|
METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes);
|
|
|
|
}
|
|
#line 17 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
|
|
}
|
|
#line 10 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
|
|
{
|
|
#line 20 "inweb/Chapter 5/TeX Format.w"
|
|
weave_format *wf = Formats__create_weave_format(TL_IS_291, TL_IS_292);
|
|
|
|
{
|
|
#line 40 "inweb/Chapter 5/TeX Format.w"
|
|
METHOD_ADD(wf, TOP_FOR_MTID, TeX__top);
|
|
METHOD_ADD(wf, SUBHEADING_FOR_MTID, TeX__subheading);
|
|
METHOD_ADD(wf, TOC_FOR_MTID, TeX__toc);
|
|
METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, TeX__chapter_title_page);
|
|
METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, TeX__paragraph_heading);
|
|
METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, TeX__source_code);
|
|
METHOD_ADD(wf, INLINE_CODE_FOR_MTID, TeX__inline_code);
|
|
METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, TeX__display_line);
|
|
METHOD_ADD(wf, ITEM_FOR_MTID, TeX__item);
|
|
METHOD_ADD(wf, BAR_FOR_MTID, TeX__bar);
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro);
|
|
METHOD_ADD(wf, PAGEBREAK_FOR_MTID, TeX__pagebreak);
|
|
METHOD_ADD(wf, BLANK_LINE_FOR_MTID, TeX__blank_line);
|
|
METHOD_ADD(wf, AFTER_DEFINITIONS_FOR_MTID, TeX__after_definitions);
|
|
METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, TeX__change_material);
|
|
METHOD_ADD(wf, ENDNOTE_FOR_MTID, TeX__endnote);
|
|
METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, TeX__commentary_text);
|
|
METHOD_ADD(wf, LOCALE_FOR_MTID, TeX__locale);
|
|
METHOD_ADD(wf, TAIL_FOR_MTID, TeX__tail);
|
|
METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX__preform_document);
|
|
METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute);
|
|
METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes);
|
|
|
|
}
|
|
#line 21 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
METHOD_ADD(wf, POST_PROCESS_POS_MTID, TeX__post_process_DVI);
|
|
METHOD_ADD(wf, POST_PROCESS_POS_MTID, TeX__post_process_report);
|
|
METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute);
|
|
METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes);
|
|
|
|
}
|
|
#line 11 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
|
|
{
|
|
#line 28 "inweb/Chapter 5/TeX Format.w"
|
|
weave_format *wf = Formats__create_weave_format(TL_IS_293, TL_IS_294);
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro_PDF_1);
|
|
|
|
{
|
|
#line 40 "inweb/Chapter 5/TeX Format.w"
|
|
METHOD_ADD(wf, TOP_FOR_MTID, TeX__top);
|
|
METHOD_ADD(wf, SUBHEADING_FOR_MTID, TeX__subheading);
|
|
METHOD_ADD(wf, TOC_FOR_MTID, TeX__toc);
|
|
METHOD_ADD(wf, CHAPTER_TP_FOR_MTID, TeX__chapter_title_page);
|
|
METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, TeX__paragraph_heading);
|
|
METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, TeX__source_code);
|
|
METHOD_ADD(wf, INLINE_CODE_FOR_MTID, TeX__inline_code);
|
|
METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, TeX__display_line);
|
|
METHOD_ADD(wf, ITEM_FOR_MTID, TeX__item);
|
|
METHOD_ADD(wf, BAR_FOR_MTID, TeX__bar);
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro);
|
|
METHOD_ADD(wf, PAGEBREAK_FOR_MTID, TeX__pagebreak);
|
|
METHOD_ADD(wf, BLANK_LINE_FOR_MTID, TeX__blank_line);
|
|
METHOD_ADD(wf, AFTER_DEFINITIONS_FOR_MTID, TeX__after_definitions);
|
|
METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, TeX__change_material);
|
|
METHOD_ADD(wf, ENDNOTE_FOR_MTID, TeX__endnote);
|
|
METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, TeX__commentary_text);
|
|
METHOD_ADD(wf, LOCALE_FOR_MTID, TeX__locale);
|
|
METHOD_ADD(wf, TAIL_FOR_MTID, TeX__tail);
|
|
METHOD_ADD(wf, PREFORM_DOCUMENT_FOR_MTID, TeX__preform_document);
|
|
METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute);
|
|
METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes);
|
|
|
|
}
|
|
#line 30 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, TeX__para_macro_PDF_2);
|
|
METHOD_ADD(wf, CHANGE_COLOUR_FOR_MTID, TeX__change_colour_PDF);
|
|
METHOD_ADD(wf, FIGURE_FOR_MTID, TeX__figure_PDF);
|
|
METHOD_ADD(wf, POST_PROCESS_POS_MTID, TeX__post_process_PDF);
|
|
METHOD_ADD(wf, POST_PROCESS_SUBSTITUTE_POS_MTID, TeX__post_process_substitute);
|
|
METHOD_ADD(wf, INDEX_PDFS_POS_MTID, TeX__yes);
|
|
METHOD_ADD(wf, PRESERVE_MATH_MODE_FOR_MTID, TeX__yes);
|
|
|
|
}
|
|
#line 12 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
}
|
|
|
|
#line 67 "inweb/Chapter 5/TeX Format.w"
|
|
int TeX__yes(weave_format *self) {
|
|
return TRUE;
|
|
}
|
|
|
|
#line 72 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) {
|
|
WRITE("%% %S\n", comment);
|
|
|
|
{
|
|
#line 85 "inweb/Chapter 5/TeX Format.w"
|
|
filename *Macros = Patterns__obtain_filename(wv->pattern, TL_IS_295);
|
|
FILE *MACROS = Filenames__fopen(Macros, "r");
|
|
if (MACROS == NULL) Errors__fatal_with_file("can't open file of TeX macros", Macros);
|
|
while (TRUE) {
|
|
int c = fgetc(MACROS);
|
|
if (c == EOF) break;
|
|
PUT(c);
|
|
}
|
|
fclose(MACROS);
|
|
|
|
}
|
|
#line 74 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
}
|
|
|
|
#line 96 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__subheading(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int level, text_stream *comment, text_stream *head) {
|
|
switch (level) {
|
|
case 1:
|
|
WRITE("\\par\\noindent{\\bf %S}\\mark{%S}\\medskip\n",
|
|
comment, head);
|
|
break;
|
|
case 2:
|
|
WRITE("\\smallskip\\par\\noindent{\\it %S}\\smallskip\\noindent\n",
|
|
comment);
|
|
if (head) Formats__text(OUT, wv, head);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#line 112 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__toc(weave_format *self, text_stream *OUT, weave_target *wv, int stage,
|
|
text_stream *text1, text_stream *text2, paragraph *P) {
|
|
switch (stage) {
|
|
case 1:
|
|
if (wv->pattern->show_abbrevs)
|
|
WRITE("\\medskip\\hrule\\smallskip\\par\\noindent{\\usagefont %S.", text1);
|
|
else
|
|
WRITE("\\medskip\\hrule\\smallskip\\par\\noindent{\\usagefont ");
|
|
break;
|
|
case 2:
|
|
WRITE("; ");
|
|
break;
|
|
case 3:
|
|
WRITE("%S~%S", text1, text2);
|
|
break;
|
|
case 4:
|
|
WRITE("}\\par\\medskip\\hrule\\bigskip\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#line 134 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__chapter_title_page(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
chapter *C) {
|
|
WRITE("%S\\medskip\n", C->md->rubric);
|
|
section *S;
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
|
|
WRITE("\\smallskip\\noindent ");
|
|
if (wv->pattern->number_sections) WRITE("%d. ", S->printed_number);
|
|
if (wv->pattern->show_abbrevs) WRITE("|%S|: ", S->sect_range);
|
|
WRITE("{\\it %S}\\qquad\n%S", S->md->sect_title, S->sect_purpose);
|
|
}
|
|
}
|
|
|
|
#line 147 "inweb/Chapter 5/TeX Format.w"
|
|
text_stream *P_literal = NULL;
|
|
void TeX__paragraph_heading(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *TeX_macro, section *S, paragraph *P, text_stream *heading_text,
|
|
text_stream *chaptermark, text_stream *sectionmark, int weight) {
|
|
if (P_literal == NULL) P_literal = Str__new_from_wide_string(L"P");
|
|
text_stream *orn = (P)?(P->ornament):P_literal;
|
|
text_stream *N = (P)?(P->paragraph_number):NULL;
|
|
TEMPORARY_TEXT(mark);
|
|
WRITE_TO(mark, "%S%S\\quad$\\%S$%S", chaptermark, sectionmark, orn, N);
|
|
TEMPORARY_TEXT(modified);
|
|
Str__copy(modified, heading_text);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, modified, L"(%c*?): (%c*)")) {
|
|
Str__clear(modified);
|
|
WRITE_TO(modified, "{\\sinchhigh %S}\\quad %S", mr.exp[0], mr.exp[1]);
|
|
}
|
|
if ((weight == 2) && ((S->md->is_a_singleton) || (wv->pattern->show_abbrevs == FALSE)))
|
|
WRITE("\\%S{%S}{%S}{%S}{\\%S}{%S}%%\n",
|
|
TeX_macro, N, modified, mark, orn, NULL);
|
|
else
|
|
WRITE("\\%S{%S}{%S}{%S}{\\%S}{%S}%%\n",
|
|
TeX_macro, N, modified, mark, orn, S->sect_range);
|
|
DISCARD_TEXT(mark);
|
|
DISCARD_TEXT(modified);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 180 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__source_code(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter,
|
|
text_stream *colouring, text_stream *concluding_comment,
|
|
int starts, int finishes, int code_mode) {
|
|
if (code_mode == FALSE) WRITE("\\smallskip\\par\\noindent");
|
|
if (starts) {
|
|
|
|
{
|
|
#line 212 "inweb/Chapter 5/TeX Format.w"
|
|
for (int i=0; i<tab_stops_of_indentation; i++)
|
|
WRITE("\\qquad");
|
|
|
|
}
|
|
#line 186 "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 216 "inweb/Chapter 5/TeX Format.w"
|
|
if (colour_wanted != current_colour) {
|
|
Formats__change_colour(OUT, wv, colour_wanted, TRUE);
|
|
current_colour = colour_wanted;
|
|
}
|
|
|
|
}
|
|
#line 192 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
if (Str__get_at(matter, i) == '|') WRITE("|\\||");
|
|
else WRITE("%c", Str__get_at(matter, i));
|
|
}
|
|
colour_wanted = PLAIN_COLOUR;
|
|
{
|
|
#line 216 "inweb/Chapter 5/TeX Format.w"
|
|
if (colour_wanted != current_colour) {
|
|
Formats__change_colour(OUT, wv, colour_wanted, TRUE);
|
|
current_colour = colour_wanted;
|
|
}
|
|
|
|
}
|
|
#line 196 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
if (finishes) {
|
|
WRITE("|");
|
|
if (Str__len(concluding_comment) > 0) {
|
|
if ((Str__len(matter) > 0) || (!starts))
|
|
WRITE("\\hfill\\quad ");
|
|
WRITE("{\\ttninepoint\\it %S}", concluding_comment);
|
|
}
|
|
WRITE("\n");
|
|
}
|
|
}
|
|
|
|
#line 222 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__inline_code(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int enter) {
|
|
WRITE("|");
|
|
}
|
|
|
|
#line 228 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__change_colour_PDF(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int col, int in_code) {
|
|
char *inout = "";
|
|
if (in_code) inout = "|";
|
|
switch (col) {
|
|
case DEFINITION_COLOUR:
|
|
WRITE("%s\\pdfliteral direct{1 1 0 0 k}%s", inout, inout); break;
|
|
case FUNCTION_COLOUR:
|
|
WRITE("%s\\pdfliteral direct{0 1 1 0 k}%s", inout, inout); break;
|
|
case PLAIN_COLOUR:
|
|
WRITE("%s\\special{PDF:0 g}%s", inout, inout); break;
|
|
case EXTRACT_COLOUR:
|
|
WRITE("%s\\special{PDF:0 g}%s", inout, inout); break;
|
|
}
|
|
}
|
|
|
|
#line 245 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__display_line(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *text) {
|
|
WRITE("\\quotesource{%S}\n", text);
|
|
}
|
|
|
|
#line 251 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth,
|
|
text_stream *label) {
|
|
if (Str__len(label) > 0) {
|
|
if (depth == 1) WRITE("\\item{(%S)}", label);
|
|
else WRITE("\\itemitem{(%S)}", label);
|
|
} else {
|
|
if (depth == 1) WRITE("\\item{}");
|
|
else WRITE("\\itemitem{}");
|
|
}
|
|
}
|
|
|
|
#line 263 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__bar(weave_format *self, text_stream *OUT, weave_target *wv) {
|
|
WRITE("\\par\\medskip\\noindent\\hrule\\medskip\\noindent\n");
|
|
}
|
|
|
|
#line 275 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__figure_PDF(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *figname, int w, int h, programming_language *pl) {
|
|
WRITE("\\pdfximage");
|
|
if (w >= 0)
|
|
WRITE(" width %d cm{../Figures/%S}\n", w, figname);
|
|
else if (h >= 0)
|
|
WRITE(" height %d cm{../Figures/%S}\n", h, figname);
|
|
else
|
|
WRITE("{../Figures/%S}\n", figname);
|
|
WRITE("\\smallskip\\noindent"
|
|
"\\hbox to\\hsize{\\hfill\\pdfrefximage \\pdflastximage\\hfill}"
|
|
"\\smallskip\n");
|
|
}
|
|
|
|
#line 297 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__para_macro_PDF_1(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
para_macro *pmac, int defn) {
|
|
if (defn)
|
|
WRITE("|\\pdfdest num %d fit ",
|
|
pmac->allocation_id + 100);
|
|
else
|
|
WRITE("|\\pdfstartlink attr{/C [0.9 0 0] /Border [0 0 0]} goto num %d ",
|
|
pmac->allocation_id + 100);
|
|
}
|
|
void TeX__para_macro(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
para_macro *pmac, int defn) {
|
|
WRITE("$\\langle${\\xreffont");
|
|
Formats__change_colour(OUT, wv, DEFINITION_COLOUR, FALSE);
|
|
WRITE("%S ", pmac->macro_name);
|
|
WRITE("{\\sevenss %S}}", pmac->defining_paragraph->paragraph_number);
|
|
Formats__change_colour(OUT, wv, PLAIN_COLOUR, FALSE);
|
|
WRITE("$\\rangle$ ");
|
|
}
|
|
void TeX__para_macro_PDF_2(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
para_macro *pmac, int defn) {
|
|
if (defn)
|
|
WRITE("$\\equiv$|");
|
|
else
|
|
WRITE("\\pdfendlink|");
|
|
}
|
|
|
|
#line 324 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) {
|
|
WRITE("\\vfill\\eject\n");
|
|
}
|
|
|
|
#line 329 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__blank_line(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int in_comment) {
|
|
if (in_comment) WRITE("\\smallskip\\par\\noindent%%\n");
|
|
else WRITE("\\smallskip\n");
|
|
}
|
|
|
|
#line 336 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__after_definitions(weave_format *self, text_stream *OUT, weave_target *wv) {
|
|
WRITE("\\smallskip\n");
|
|
}
|
|
|
|
#line 341 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) {
|
|
if (end == 1) {
|
|
WRITE("\\par\\noindent\\penalty10000\n");
|
|
WRITE("{\\usagefont ");
|
|
} else {
|
|
WRITE("}\\smallskip\n");
|
|
}
|
|
}
|
|
|
|
#line 351 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *id) {
|
|
int math_mode = FALSE;
|
|
for (int i=0; i < Str__len(id); i++) {
|
|
switch (Str__get_at(id, i)) {
|
|
case '$': math_mode = (math_mode)?FALSE:TRUE;
|
|
WRITE("%c", Str__get_at(id, i)); break;
|
|
case '_': if (math_mode) WRITE("_"); else WRITE("\\_"); break;
|
|
case '"':
|
|
if ((Str__get_at(id, i) == '"') &&
|
|
((i==0) || (Str__get_at(id, i-1) == ' ') ||
|
|
(Str__get_at(id, i-1) == '(')))
|
|
WRITE("``");
|
|
else
|
|
WRITE("''");
|
|
break;
|
|
default: WRITE("%c", Str__get_at(id, i));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 374 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__locale(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
paragraph *par1, paragraph *par2) {
|
|
WRITE("$\\%S$%S", par1->ornament, par1->paragraph_number);
|
|
if (par2) WRITE("-%S", par2->paragraph_number);
|
|
}
|
|
|
|
#line 381 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__change_material(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int old_material, int new_material, int content) {
|
|
if (old_material != new_material) {
|
|
switch (old_material) {
|
|
case REGULAR_MATERIAL:
|
|
switch (new_material) {
|
|
case CODE_MATERIAL:
|
|
WRITE("\\beginlines\n");
|
|
break;
|
|
case DEFINITION_MATERIAL:
|
|
WRITE("\\beginlines\n");
|
|
break;
|
|
case MACRO_MATERIAL:
|
|
WRITE("\\beginlines\n");
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
if (new_material == REGULAR_MATERIAL)
|
|
WRITE("\\endlines\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 407 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__tail(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *comment, section *S) {
|
|
WRITE("%% %S\n", comment);
|
|
WRITE("\\end\n");
|
|
}
|
|
|
|
#line 417 "inweb/Chapter 5/TeX Format.w"
|
|
int TeX__preform_document(weave_format *self, text_stream *OUT, web *W, weave_target *wv,
|
|
chapter *C, section *S, source_line *L, text_stream *matter,
|
|
text_stream *concluding_comment) {
|
|
if (L->preform_nonterminal_defined) {
|
|
preform_production_count = 0;
|
|
|
|
{
|
|
#line 434 "inweb/Chapter 5/TeX Format.w"
|
|
WRITE("\\nonterminal{%S} |::=|",
|
|
L->preform_nonterminal_defined->unangled_name);
|
|
if (L->preform_nonterminal_defined->as_function) {
|
|
WRITE("\\quad{\\it internal definition");
|
|
if (L->preform_nonterminal_defined->voracious)
|
|
WRITE(" (voracious)");
|
|
else if (L->preform_nonterminal_defined->min_word_count ==
|
|
L->preform_nonterminal_defined->min_word_count)
|
|
WRITE(" (%d word%s)",
|
|
L->preform_nonterminal_defined->min_word_count,
|
|
(L->preform_nonterminal_defined->min_word_count != 1)?"s":"");
|
|
WRITE("}");
|
|
}
|
|
WRITE("\n");
|
|
|
|
}
|
|
#line 422 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
return TRUE;
|
|
} else {
|
|
if (L->category == PREFORM_GRAMMAR_LCAT) {
|
|
|
|
{
|
|
#line 450 "inweb/Chapter 5/TeX Format.w"
|
|
TEMPORARY_TEXT(problem);
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, matter, L"Issue (%c*?) problem")) Str__copy(problem, mr.exp[0]);
|
|
else if (Regexp__match(&mr, matter, L"FAIL_NONTERMINAL %+")) WRITE_TO(problem, "fail and skip");
|
|
else if (Regexp__match(&mr, matter, L"FAIL_NONTERMINAL")) WRITE_TO(problem, "fail");
|
|
preform_production_count++;
|
|
WRITE_TO(matter, "|%S|", L->text_operand);
|
|
while (Regexp__match(&mr, matter, L"(%c+?)|(%c+)")) {
|
|
Str__clear(matter);
|
|
WRITE_TO(matter, "%S___stroke___%S", mr.exp[0], mr.exp[1]);
|
|
}
|
|
while (Regexp__match(&mr, matter, L"(%c*?)___stroke___(%c*)")) {
|
|
Str__clear(matter);
|
|
WRITE_TO(matter, "%S|\\||%S", mr.exp[0], mr.exp[1]);
|
|
}
|
|
while (Regexp__match(&mr, matter, L"(%c*)<(%c*?)>(%c*)")) {
|
|
Str__clear(matter);
|
|
WRITE_TO(matter, "%S|\\nonterminal{%S}|%S",
|
|
mr.exp[0], mr.exp[1], mr.exp[2]);
|
|
}
|
|
TEMPORARY_TEXT(label);
|
|
int N = preform_production_count;
|
|
int L = ((N-1)%26) + 1;
|
|
if (N <= 26) WRITE_TO(label, "%c", 'a'+L-1);
|
|
else if (N <= 52) WRITE_TO(label, "%c%c", 'a'+L-1, 'a'+L-1);
|
|
else if (N <= 78) WRITE_TO(label, "%c%c%c", 'a'+L-1, 'a'+L-1, 'a'+L-1);
|
|
else {
|
|
int n = (N-1)/26;
|
|
WRITE_TO(label, "%c${}^{%d}$", 'a'+L-1, n);
|
|
}
|
|
WRITE("\\qquad {\\hbox to 0.4in{\\it %S\\hfil}}%S", label, matter);
|
|
if (Str__len(problem) > 0)
|
|
WRITE("\\hfill$\\longrightarrow$ {\\ttninepoint\\it %S}", problem);
|
|
else if (Str__len(concluding_comment) > 0) {
|
|
WRITE(" \\hfill{\\ttninepoint\\it ");
|
|
if (concluding_comment) Formats__text(OUT, wv, concluding_comment);
|
|
WRITE("}");
|
|
}
|
|
WRITE("\n");
|
|
DISCARD_TEXT(label);
|
|
DISCARD_TEXT(problem);
|
|
Regexp__dispose_of(&mr);
|
|
|
|
}
|
|
#line 426 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#line 496 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__post_process_PDF(weave_format *self, weave_target *wv, int open) {
|
|
RunningTeX__post_process_weave(wv, open, FALSE);
|
|
}
|
|
void TeX__post_process_DVI(weave_format *self, weave_target *wv, int open) {
|
|
RunningTeX__post_process_weave(wv, open, TRUE);
|
|
}
|
|
|
|
#line 504 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__post_process_report(weave_format *self, weave_target *wv) {
|
|
RunningTeX__report_on_post_processing(wv);
|
|
}
|
|
|
|
#line 509 "inweb/Chapter 5/TeX Format.w"
|
|
int TeX__post_process_substitute(weave_format *self, text_stream *OUT,
|
|
weave_target *wv, text_stream *detail, weave_pattern *pattern) {
|
|
return RunningTeX__substitute_post_processing_data(OUT, wv, detail);
|
|
}
|
|
|
|
#line 522 "inweb/Chapter 5/TeX Format.w"
|
|
void TeX__remove_math_mode(OUTPUT_STREAM, text_stream *text) {
|
|
TEMPORARY_TEXT(math_matter);
|
|
TeX__remove_math_mode_range(math_matter, text, 0, Str__len(text)-1);
|
|
WRITE("%S", math_matter);
|
|
DISCARD_TEXT(math_matter);
|
|
}
|
|
|
|
void TeX__remove_math_mode_range(OUTPUT_STREAM, text_stream *text, int from, int to) {
|
|
for (int i=from; i <= to; i++) {
|
|
|
|
{
|
|
#line 553 "inweb/Chapter 5/TeX Format.w"
|
|
if ((Str__get_at(text, i) == '\\') &&
|
|
(Str__get_at(text, i+1) == 'o') && (Str__get_at(text, i+2) == 'v') &&
|
|
(Str__get_at(text, i+3) == 'e') && (Str__get_at(text, i+4) == 'r') &&
|
|
(Str__get_at(text, i+5) == '{')) {
|
|
int bl = 1;
|
|
int j = i-1;
|
|
for (; j >= from; j--) {
|
|
wchar_t c = Str__get_at(text, j);
|
|
if (c == '{') {
|
|
bl--;
|
|
if (bl == 0) break;
|
|
}
|
|
if (c == '}') bl++;
|
|
}
|
|
TeX__remove_math_mode_range(OUT, text, from, j-1);
|
|
WRITE("((");
|
|
TeX__remove_math_mode_range(OUT, text, j+2, i-2);
|
|
WRITE(") / (");
|
|
j=i+6; bl = 1;
|
|
for (; j <= to; j++) {
|
|
wchar_t c = Str__get_at(text, j);
|
|
if (c == '}') {
|
|
bl--;
|
|
if (bl == 0) break;
|
|
}
|
|
if (c == '{') bl++;
|
|
}
|
|
TeX__remove_math_mode_range(OUT, text, i+6, j-1);
|
|
WRITE("))");
|
|
TeX__remove_math_mode_range(OUT, text, j+2, to);
|
|
return;
|
|
}
|
|
|
|
}
|
|
#line 531 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
}
|
|
for (int i=from; i <= to; i++) {
|
|
|
|
{
|
|
#line 589 "inweb/Chapter 5/TeX Format.w"
|
|
if ((Str__get_at(text, i) == '{') && (Str__get_at(text, i+1) == '\\') &&
|
|
(((Str__get_at(text, i+2) == 'r') && (Str__get_at(text, i+3) == 'm')) ||
|
|
((Str__get_at(text, i+2) == 'i') && (Str__get_at(text, i+3) == 't'))) &&
|
|
(Str__get_at(text, i+4) == ' ')) {
|
|
TeX__remove_math_mode_range(OUT, text, from, i-1);
|
|
int j=i+5;
|
|
for (; j <= to; j++)
|
|
if (Str__get_at(text, j) == '}')
|
|
break;
|
|
TeX__remove_math_mode_range(OUT, text, i+5, j-1);
|
|
TeX__remove_math_mode_range(OUT, text, j+1, to);
|
|
return;
|
|
}
|
|
|
|
}
|
|
#line 534 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
|
|
{
|
|
#line 607 "inweb/Chapter 5/TeX Format.w"
|
|
if ((Str__get_at(text, i) == '\\') &&
|
|
(Str__get_at(text, i+1) == 's') && (Str__get_at(text, i+2) == 'q') &&
|
|
(Str__get_at(text, i+3) == 'r') && (Str__get_at(text, i+4) == 't') &&
|
|
(Str__get_at(text, i+5) == '{')) {
|
|
if ((Str__get_at(text, i-4) == '{') &&
|
|
(Str__get_at(text, i-3) == '}') &&
|
|
(Str__get_at(text, i-2) == '^') &&
|
|
(Str__get_at(text, i-1) == '3')) {
|
|
TeX__remove_math_mode_range(OUT, text, from, i-5);
|
|
WRITE(" curt(");
|
|
} else {
|
|
TeX__remove_math_mode_range(OUT, text, from, i-1);
|
|
WRITE(" sqrt(");
|
|
}
|
|
int j=i+6, bl = 1;
|
|
for (; j <= to; j++) {
|
|
wchar_t c = Str__get_at(text, j);
|
|
if (c == '}') {
|
|
bl--;
|
|
if (bl == 0) break;
|
|
}
|
|
if (c == '{') bl++;
|
|
}
|
|
TeX__remove_math_mode_range(OUT, text, i+6, j-1);
|
|
WRITE(")");
|
|
TeX__remove_math_mode_range(OUT, text, j+1, to);
|
|
return;
|
|
}
|
|
|
|
}
|
|
#line 535 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
}
|
|
int math_mode = FALSE;
|
|
for (int i=from; i <= to; i++) {
|
|
switch (Str__get_at(text, i)) {
|
|
case '$':
|
|
if (Str__get_at(text, i+1) == '$') i++;
|
|
math_mode = (math_mode)?FALSE:TRUE; break;
|
|
case '~': if (math_mode) WRITE(" "); else WRITE("~"); break;
|
|
case '\\':
|
|
{
|
|
#line 637 "inweb/Chapter 5/TeX Format.w"
|
|
TEMPORARY_TEXT(macro);
|
|
i++;
|
|
while ((i < Str__len(text)) && (Characters__isalpha(Str__get_at(text, i))))
|
|
PUT_TO(macro, Str__get_at(text, i++));
|
|
if (Str__eq(macro, TL_IS_296))
|
|
{
|
|
#line 749 "inweb/Chapter 5/TeX Format.w"
|
|
if (Str__get_at(text, i) == '\\') {
|
|
Str__clear(macro);
|
|
i++;
|
|
while ((i < Str__len(text)) && (Characters__isalpha(Str__get_at(text, i))))
|
|
PUT_TO(macro, Str__get_at(text, i++));
|
|
if (Str__eq(macro, TL_IS_390)) PUT((wchar_t) 0x2204);
|
|
else if (Str__eq(macro, TL_IS_391)) { PUT((wchar_t) 0x00AC); PUT((wchar_t) 0x2200); }
|
|
else {
|
|
PRINT("Don't know how to apply '\\not' to '\\%S'\n", macro);
|
|
}
|
|
} else {
|
|
PRINT("Don't know how to apply '\\not' here\n");
|
|
}
|
|
|
|
}
|
|
#line 641 "inweb/Chapter 5/TeX Format.w"
|
|
|
|
else
|
|
{
|
|
#line 647 "inweb/Chapter 5/TeX Format.w"
|
|
if (Str__eq(macro, TL_IS_297)) WRITE("<=");
|
|
else if (Str__eq(macro, TL_IS_298)) WRITE(">=");
|
|
else if (Str__eq(macro, TL_IS_299)) WRITE("~");
|
|
else if (Str__eq(macro, TL_IS_300)) WRITE("");
|
|
else if (Str__eq(macro, TL_IS_301)) WRITE("");
|
|
else if (Str__eq(macro, TL_IS_302)) WRITE("");
|
|
else if (Str__eq(macro, TL_IS_303)) WRITE("=>");
|
|
else if (Str__eq(macro, TL_IS_304)) WRITE("<=>");
|
|
else if (Str__eq(macro, TL_IS_305)) WRITE("-->");
|
|
else if (Str__eq(macro, TL_IS_306)) WRITE("-->");
|
|
else if (Str__eq(macro, TL_IS_307)) WRITE("-->");
|
|
else if (Str__eq(macro, TL_IS_308)) WRITE("<--");
|
|
else if (Str__eq(macro, TL_IS_309)) WRITE("<--");
|
|
else if (Str__eq(macro, TL_IS_310)) WRITE("{");
|
|
else if (Str__eq(macro, TL_IS_311)) WRITE("|");
|
|
else if (Str__eq(macro, TL_IS_312)) WRITE("}");
|
|
else if (Str__eq(macro, TL_IS_313)) WRITE(".");
|
|
else if (Str__eq(macro, TL_IS_314)) WRITE("...");
|
|
else if (Str__eq(macro, TL_IS_315)) WRITE("...");
|
|
else if (Str__eq(macro, TL_IS_316)) WRITE("*");
|
|
else if (Str__eq(macro, TL_IS_317)) WRITE(" ");
|
|
else if (Str__eq(macro, TL_IS_318)) WRITE(" ");
|
|
else if (Str__eq(macro, TL_IS_319)) WRITE("TeX");
|
|
else if (Str__eq(macro, TL_IS_320)) WRITE("!=");
|
|
else if (Str__eq(macro, TL_IS_321)) WRITE("!=");
|
|
else if (Str__eq(macro, TL_IS_322)) WRITE("l");
|
|
else if (Str__eq(macro, TL_IS_323)) WRITE("log");
|
|
else if (Str__eq(macro, TL_IS_324)) WRITE("exp");
|
|
else if (Str__eq(macro, TL_IS_325)) WRITE("sin");
|
|
else if (Str__eq(macro, TL_IS_326)) WRITE("cos");
|
|
else if (Str__eq(macro, TL_IS_327)) WRITE("tan");
|
|
else if (Str__eq(macro, TL_IS_328)) WRITE("T");
|
|
else if (Str__eq(macro, TL_IS_329)) PUT((wchar_t) 0x0391);
|
|
else if (Str__eq(macro, TL_IS_330)) PUT((wchar_t) 0x0392);
|
|
else if (Str__eq(macro, TL_IS_331)) PUT((wchar_t) 0x0393);
|
|
else if (Str__eq(macro, TL_IS_332)) PUT((wchar_t) 0x0394);
|
|
else if (Str__eq(macro, TL_IS_333)) PUT((wchar_t) 0x0395);
|
|
else if (Str__eq(macro, TL_IS_334)) PUT((wchar_t) 0x0396);
|
|
else if (Str__eq(macro, TL_IS_335)) PUT((wchar_t) 0x0397);
|
|
else if (Str__eq(macro, TL_IS_336)) PUT((wchar_t) 0x0398);
|
|
else if (Str__eq(macro, TL_IS_337)) PUT((wchar_t) 0x0399);
|
|
else if (Str__eq(macro, TL_IS_338)) PUT((wchar_t) 0x039A);
|
|
else if (Str__eq(macro, TL_IS_339)) PUT((wchar_t) 0x039B);
|
|
else if (Str__eq(macro, TL_IS_340)) PUT((wchar_t) 0x039C);
|
|
else if (Str__eq(macro, TL_IS_341)) PUT((wchar_t) 0x039D);
|
|
else if (Str__eq(macro, TL_IS_342)) PUT((wchar_t) 0x039E);
|
|
else if (Str__eq(macro, TL_IS_343)) PUT((wchar_t) 0x039F);
|
|
else if (Str__eq(macro, TL_IS_344)) PUT((wchar_t) 0x03A0);
|
|
else if (Str__eq(macro, TL_IS_345)) PUT((wchar_t) 0x03A1);
|
|
else if (Str__eq(macro, TL_IS_346)) PUT((wchar_t) 0x03A2);
|
|
else if (Str__eq(macro, TL_IS_347)) PUT((wchar_t) 0x03A3);
|
|
else if (Str__eq(macro, TL_IS_348)) PUT((wchar_t) 0x03A4);
|
|
else if (Str__eq(macro, TL_IS_349)) PUT((wchar_t) 0x03A5);
|
|
else if (Str__eq(macro, TL_IS_350)) PUT((wchar_t) 0x03A6);
|
|
else if (Str__eq(macro, TL_IS_351)) PUT((wchar_t) 0x03A7);
|
|
else if (Str__eq(macro, TL_IS_352)) PUT((wchar_t) 0x03A8);
|
|
else if (Str__eq(macro, TL_IS_353)) PUT((wchar_t) 0x03A9);
|
|
else if (Str__eq(macro, TL_IS_354)) PUT((wchar_t) 0x03B1);
|
|
else if (Str__eq(macro, TL_IS_355)) PUT((wchar_t) 0x03B2);
|
|
else if (Str__eq(macro, TL_IS_356)) PUT((wchar_t) 0x03B3);
|
|
else if (Str__eq(macro, TL_IS_357)) PUT((wchar_t) 0x03B4);
|
|
else if (Str__eq(macro, TL_IS_358)) PUT((wchar_t) 0x03B5);
|
|
else if (Str__eq(macro, TL_IS_359)) PUT((wchar_t) 0x03B6);
|
|
else if (Str__eq(macro, TL_IS_360)) PUT((wchar_t) 0x03B7);
|
|
else if (Str__eq(macro, TL_IS_361)) PUT((wchar_t) 0x03B8);
|
|
else if (Str__eq(macro, TL_IS_362)) PUT((wchar_t) 0x03B9);
|
|
else if (Str__eq(macro, TL_IS_363)) PUT((wchar_t) 0x03BA);
|
|
else if (Str__eq(macro, TL_IS_364)) PUT((wchar_t) 0x03BB);
|
|
else if (Str__eq(macro, TL_IS_365)) PUT((wchar_t) 0x03BC);
|
|
else if (Str__eq(macro, TL_IS_366)) PUT((wchar_t) 0x03BD);
|
|
else if (Str__eq(macro, TL_IS_367)) PUT((wchar_t) 0x03BE);
|
|
else if (Str__eq(macro, TL_IS_368)) PUT((wchar_t) 0x03BF);
|
|
else if (Str__eq(macro, TL_IS_369)) PUT((wchar_t) 0x03C0);
|
|
else if (Str__eq(macro, TL_IS_370)) PUT((wchar_t) 0x03C1);
|
|
else if (Str__eq(macro, TL_IS_371)) PUT((wchar_t) 0x03C2);
|
|
else if (Str__eq(macro, TL_IS_372)) PUT((wchar_t) 0x03C3);
|
|
else if (Str__eq(macro, TL_IS_373)) PUT((wchar_t) 0x03C4);
|
|
else if (Str__eq(macro, TL_IS_374)) PUT((wchar_t) 0x03C5);
|
|
else if (Str__eq(macro, TL_IS_375)) PUT((wchar_t) 0x03C6);
|
|
else if (Str__eq(macro, TL_IS_376)) PUT((wchar_t) 0x03C7);
|
|
else if (Str__eq(macro, TL_IS_377)) PUT((wchar_t) 0x03C8);
|
|
else if (Str__eq(macro, TL_IS_378)) PUT((wchar_t) 0x03C9);
|
|
else if (Str__eq(macro, TL_IS_379)) PUT((wchar_t) 0x2203);
|
|
else if (Str__eq(macro, TL_IS_380)) PUT((wchar_t) 0x2208);
|
|
else if (Str__eq(macro, TL_IS_381)) PUT((wchar_t) 0x2200);
|
|
else if (Str__eq(macro, TL_IS_382)) PUT((wchar_t) 0x2229);
|
|
else if (Str__eq(macro, TL_IS_383)) PUT((wchar_t) 0x2205);
|
|
else if (Str__eq(macro, TL_IS_384)) PUT((wchar_t) 0x2286);
|
|
else if (Str__eq(macro, TL_IS_385)) PUT((wchar_t) 0x2227);
|
|
else if (Str__eq(macro, TL_IS_386)) PUT((wchar_t) 0x2228);
|
|
else if (Str__eq(macro, TL_IS_387)) PUT((wchar_t) 0x00AC);
|
|
else if (Str__eq(macro, TL_IS_388)) PUT((wchar_t) 0x03A3);
|
|
else if (Str__eq(macro, TL_IS_389)) PUT((wchar_t) 0x03A0);
|
|
else {
|
|
if (Str__len(macro) > 0)
|
|
PRINT("Passing through unknown TeX macro \\%S: %S", macro, text);
|
|
WRITE("\\%S", macro);
|
|
}
|
|
|
|
}
|
|
#line 642 "inweb/Chapter 5/TeX Format.w"
|
|
;
|
|
DISCARD_TEXT(macro);
|
|
i--;
|
|
|
|
}
|
|
#line 544 "inweb/Chapter 5/TeX Format.w"
|
|
; break;
|
|
default: PUT(Str__get_at(text, i)); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 6 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__create(void) {
|
|
|
|
{
|
|
#line 12 "inweb/Chapter 5/HTML Formats.w"
|
|
weave_format *wf = Formats__create_weave_format(TL_IS_392, TL_IS_393);
|
|
METHOD_ADD(wf, TOP_FOR_MTID, HTMLFormat__top);
|
|
|
|
{
|
|
#line 24 "inweb/Chapter 5/HTML Formats.w"
|
|
METHOD_ADD(wf, SUBHEADING_FOR_MTID, HTMLFormat__subheading);
|
|
METHOD_ADD(wf, TOC_FOR_MTID, HTMLFormat__toc);
|
|
METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, HTMLFormat__paragraph_heading);
|
|
METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, HTMLFormat__source_code);
|
|
METHOD_ADD(wf, INLINE_CODE_FOR_MTID, HTMLFormat__inline_code);
|
|
METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, HTMLFormat__display_line);
|
|
METHOD_ADD(wf, ITEM_FOR_MTID, HTMLFormat__item);
|
|
METHOD_ADD(wf, BAR_FOR_MTID, HTMLFormat__bar);
|
|
METHOD_ADD(wf, FIGURE_FOR_MTID, HTMLFormat__figure);
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, HTMLFormat__para_macro);
|
|
METHOD_ADD(wf, PAGEBREAK_FOR_MTID, HTMLFormat__pagebreak);
|
|
METHOD_ADD(wf, BLANK_LINE_FOR_MTID, HTMLFormat__blank_line);
|
|
METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, HTMLFormat__change_material);
|
|
METHOD_ADD(wf, CHANGE_COLOUR_FOR_MTID, HTMLFormat__change_colour);
|
|
METHOD_ADD(wf, ENDNOTE_FOR_MTID, HTMLFormat__endnote);
|
|
METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, HTMLFormat__commentary_text);
|
|
METHOD_ADD(wf, LOCALE_FOR_MTID, HTMLFormat__locale);
|
|
METHOD_ADD(wf, TAIL_FOR_MTID, HTMLFormat__tail);
|
|
|
|
}
|
|
#line 14 "inweb/Chapter 5/HTML Formats.w"
|
|
;
|
|
|
|
}
|
|
#line 7 "inweb/Chapter 5/HTML Formats.w"
|
|
;
|
|
|
|
{
|
|
#line 17 "inweb/Chapter 5/HTML Formats.w"
|
|
weave_format *wf = Formats__create_weave_format(TL_IS_394, TL_IS_395);
|
|
METHOD_ADD(wf, TOP_FOR_MTID, HTMLFormat__top_EPUB);
|
|
|
|
{
|
|
#line 24 "inweb/Chapter 5/HTML Formats.w"
|
|
METHOD_ADD(wf, SUBHEADING_FOR_MTID, HTMLFormat__subheading);
|
|
METHOD_ADD(wf, TOC_FOR_MTID, HTMLFormat__toc);
|
|
METHOD_ADD(wf, PARAGRAPH_HEADING_FOR_MTID, HTMLFormat__paragraph_heading);
|
|
METHOD_ADD(wf, SOURCE_CODE_FOR_MTID, HTMLFormat__source_code);
|
|
METHOD_ADD(wf, INLINE_CODE_FOR_MTID, HTMLFormat__inline_code);
|
|
METHOD_ADD(wf, DISPLAY_LINE_FOR_MTID, HTMLFormat__display_line);
|
|
METHOD_ADD(wf, ITEM_FOR_MTID, HTMLFormat__item);
|
|
METHOD_ADD(wf, BAR_FOR_MTID, HTMLFormat__bar);
|
|
METHOD_ADD(wf, FIGURE_FOR_MTID, HTMLFormat__figure);
|
|
METHOD_ADD(wf, PARA_MACRO_FOR_MTID, HTMLFormat__para_macro);
|
|
METHOD_ADD(wf, PAGEBREAK_FOR_MTID, HTMLFormat__pagebreak);
|
|
METHOD_ADD(wf, BLANK_LINE_FOR_MTID, HTMLFormat__blank_line);
|
|
METHOD_ADD(wf, CHANGE_MATERIAL_FOR_MTID, HTMLFormat__change_material);
|
|
METHOD_ADD(wf, CHANGE_COLOUR_FOR_MTID, HTMLFormat__change_colour);
|
|
METHOD_ADD(wf, ENDNOTE_FOR_MTID, HTMLFormat__endnote);
|
|
METHOD_ADD(wf, COMMENTARY_TEXT_FOR_MTID, HTMLFormat__commentary_text);
|
|
METHOD_ADD(wf, LOCALE_FOR_MTID, HTMLFormat__locale);
|
|
METHOD_ADD(wf, TAIL_FOR_MTID, HTMLFormat__tail);
|
|
|
|
}
|
|
#line 19 "inweb/Chapter 5/HTML Formats.w"
|
|
;
|
|
METHOD_ADD(wf, BEGIN_WEAVING_FOR_MTID, HTMLFormat__begin_weaving_EPUB);
|
|
METHOD_ADD(wf, END_WEAVING_FOR_MTID, HTMLFormat__end_weaving_EPUB);
|
|
|
|
}
|
|
#line 8 "inweb/Chapter 5/HTML Formats.w"
|
|
;
|
|
}
|
|
|
|
#line 55 "inweb/Chapter 5/HTML Formats.w"
|
|
int html_in_para = HTML_OUT; /* one of the above */
|
|
int item_depth = 0; /* for |HTML_IN_LI| only: how many lists we're nested inside */
|
|
|
|
void HTMLFormat__p(OUTPUT_STREAM, char *class) {
|
|
if (class) HTML_OPEN_WITH("p", "class=\"%s\"", class)
|
|
else HTML_OPEN("p");
|
|
html_in_para = HTML_IN_P;
|
|
}
|
|
|
|
void HTMLFormat__cp(OUTPUT_STREAM) {
|
|
HTML_CLOSE("p"); WRITE("\n");
|
|
html_in_para = HTML_OUT;
|
|
}
|
|
|
|
void HTMLFormat__pre(OUTPUT_STREAM, char *class) {
|
|
if (class) HTML_OPEN_WITH("pre", "class=\"%s\"", class)
|
|
else HTML_OPEN("pre");
|
|
WRITE("\n"); INDENT;
|
|
html_in_para = HTML_IN_PRE;
|
|
}
|
|
|
|
void HTMLFormat__cpre(OUTPUT_STREAM) {
|
|
OUTDENT; HTML_CLOSE("pre"); WRITE("\n");
|
|
html_in_para = HTML_OUT;
|
|
}
|
|
|
|
#line 85 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__go_to_depth(OUTPUT_STREAM, int depth) {
|
|
if (html_in_para != HTML_IN_LI) HTMLFormat__exit_current_paragraph(OUT);
|
|
if (item_depth == depth) {
|
|
HTML_CLOSE("li");
|
|
} else {
|
|
while (item_depth < depth) {
|
|
HTML_OPEN_WITH("ul", "class=\"items\""); item_depth++;
|
|
}
|
|
while (item_depth > depth) {
|
|
HTML_CLOSE("li");
|
|
HTML_CLOSE("ul");
|
|
WRITE("\n"); item_depth--;
|
|
}
|
|
}
|
|
if (depth > 0) {
|
|
HTML_OPEN("li");
|
|
html_in_para = HTML_IN_LI;
|
|
} else {
|
|
html_in_para = HTML_OUT;
|
|
}
|
|
}
|
|
|
|
#line 110 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__exit_current_paragraph(OUTPUT_STREAM) {
|
|
switch (html_in_para) {
|
|
case HTML_IN_P: HTMLFormat__cp(OUT); break;
|
|
case HTML_IN_PRE: HTMLFormat__cpre(OUT); break;
|
|
case HTML_IN_LI: HTMLFormat__go_to_depth(OUT, 0); break;
|
|
}
|
|
}
|
|
|
|
#line 122 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__breadcrumb(OUTPUT_STREAM, text_stream *text, text_stream *link) {
|
|
if (link) {
|
|
HTML_OPEN("li");
|
|
HTML__begin_link(OUT, link);
|
|
WRITE("%S", text);
|
|
HTML__end_link(OUT);
|
|
HTML_CLOSE("li");
|
|
} else {
|
|
HTML_OPEN("li");
|
|
HTML_OPEN("b");
|
|
WRITE("%S", text);
|
|
HTML_CLOSE("b");
|
|
HTML_CLOSE("li");
|
|
}
|
|
}
|
|
|
|
#line 142 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__top(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) {
|
|
HTML__declare_as_HTML(OUT, FALSE);
|
|
Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_396, wv, WEAVE_FIRST_HALF);
|
|
if (wv->self_contained == FALSE) {
|
|
filename *CSS = Patterns__obtain_filename(wv->pattern, TL_IS_397);
|
|
if (wv->pattern->hierarchical)
|
|
Patterns__copy_up_file_into_weave(wv->weave_web, CSS);
|
|
else
|
|
Patterns__copy_file_into_weave(wv->weave_web, CSS);
|
|
}
|
|
HTML__comment(OUT, comment);
|
|
html_in_para = HTML_OUT;
|
|
}
|
|
|
|
void HTMLFormat__top_EPUB(weave_format *self, text_stream *OUT, weave_target *wv, text_stream *comment) {
|
|
HTML__declare_as_HTML(OUT, TRUE);
|
|
Epub__note_page(wv->weave_web->as_ebook, wv->weave_to, wv->booklet_title, TL_IS_398);
|
|
Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_399, wv, WEAVE_FIRST_HALF);
|
|
HTML__comment(OUT, comment);
|
|
html_in_para = HTML_OUT;
|
|
}
|
|
|
|
#line 165 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__subheading(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int level, text_stream *comment, text_stream *head) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
switch (level) {
|
|
case 1: HTML__heading(OUT, "h3", comment); break;
|
|
case 2: HTMLFormat__p(OUT, "purpose");
|
|
WRITE("%S", comment);
|
|
if (head) {
|
|
WRITE(": ");
|
|
Formats__text(OUT, wv, head);
|
|
}
|
|
HTMLFormat__cp(OUT);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#line 182 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__toc(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int stage, text_stream *text1, text_stream *text2, paragraph *P) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
switch (stage) {
|
|
case 1:
|
|
HTML_OPEN_WITH("ul", "class=\"toc\"");
|
|
HTML_OPEN("li");
|
|
break;
|
|
case 2:
|
|
HTML_CLOSE("li");
|
|
HTML_OPEN("li");
|
|
break;
|
|
case 3: {
|
|
TEMPORARY_TEXT(TEMP)
|
|
HTMLFormat__xref(TEMP, wv, P, NULL, TRUE);
|
|
HTML__begin_link(OUT, TEMP);
|
|
DISCARD_TEXT(TEMP)
|
|
WRITE("%s%S", (Str__get_first_char(P->ornament) == 'S')?"§":"¶",
|
|
P->paragraph_number);
|
|
WRITE(". %S", text2);
|
|
HTML__end_link(OUT);
|
|
break;
|
|
}
|
|
case 4:
|
|
HTML_CLOSE("li");
|
|
HTML_CLOSE("ul");
|
|
HTML__hr(OUT, "tocbar");
|
|
WRITE("\n"); break;
|
|
}
|
|
}
|
|
|
|
#line 214 "inweb/Chapter 5/HTML Formats.w"
|
|
section *page_section = NULL;
|
|
int crumbs_dropped = FALSE;
|
|
|
|
void HTMLFormat__paragraph_heading(weave_format *self, text_stream *OUT,
|
|
weave_target *wv, text_stream *TeX_macro, section *S, paragraph *P,
|
|
text_stream *heading_text, text_stream *chaptermark, text_stream *sectionmark,
|
|
int weight) {
|
|
page_section = S;
|
|
if (weight == 3) return; /* Skip chapter headings */
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
if (P) {
|
|
HTMLFormat__p(OUT, "inwebparagraph");
|
|
TEMPORARY_TEXT(TEMP)
|
|
HTMLFormat__xref(TEMP, wv, P, NULL, FALSE);
|
|
HTML__anchor(OUT, TEMP);
|
|
DISCARD_TEXT(TEMP)
|
|
HTML_OPEN("b");
|
|
WRITE("%s%S", (Str__get_first_char(P->ornament) == 'S')?"§":"¶",
|
|
P->paragraph_number);
|
|
WRITE(". %S%s ", heading_text, (Str__len(heading_text) > 0)?".":"");
|
|
HTML_CLOSE("b");
|
|
} else {
|
|
if (wv->self_contained == FALSE) {
|
|
if (crumbs_dropped == FALSE) {
|
|
filename *C = Patterns__obtain_filename(wv->pattern, TL_IS_400);
|
|
if (wv->pattern->hierarchical)
|
|
Patterns__copy_up_file_into_weave(wv->weave_web, C);
|
|
else
|
|
Patterns__copy_file_into_weave(wv->weave_web, C);
|
|
crumbs_dropped = TRUE;
|
|
}
|
|
HTML_OPEN_WITH("ul", "class=\"crumbs\"");
|
|
HTMLFormat__drop_initial_breadcrumbs(OUT, wv->breadcrumbs, wv->docs_mode);
|
|
text_stream *bct = Bibliographic__get_datum(wv->weave_web->md, TL_IS_401);
|
|
if (Str__len(Bibliographic__get_datum(wv->weave_web->md, TL_IS_402)) > 0) {
|
|
bct = Bibliographic__get_datum(wv->weave_web->md, TL_IS_403);
|
|
}
|
|
HTMLFormat__breadcrumb(OUT, bct, TL_IS_404);
|
|
|
|
if (wv->weave_web->md->chaptered) {
|
|
TEMPORARY_TEXT(chapter_link);
|
|
WRITE_TO(chapter_link, "index.html#%s%S", (wv->weave_web->as_ebook)?"C":"",
|
|
S->owning_chapter->md->ch_range);
|
|
HTMLFormat__breadcrumb(OUT, S->owning_chapter->md->ch_title, chapter_link);
|
|
DISCARD_TEXT(chapter_link);
|
|
}
|
|
|
|
HTMLFormat__breadcrumb(OUT, heading_text, NULL);
|
|
HTML_CLOSE("ul");
|
|
} else {
|
|
HTML_OPEN_WITH("ul", "class=\"crumbs\"");
|
|
HTMLFormat__breadcrumb(OUT, heading_text, NULL);
|
|
HTML_CLOSE("ul");
|
|
}
|
|
}
|
|
}
|
|
|
|
void HTMLFormat__drop_initial_breadcrumbs(OUTPUT_STREAM, linked_list *crumbs, int docs_mode) {
|
|
if (LinkedLists__len(crumbs) > 0) {
|
|
breadcrumb_request *BR;
|
|
LOOP_OVER_LINKED_LIST(BR, breadcrumb_request, crumbs) {
|
|
HTMLFormat__breadcrumb(OUT, BR->breadcrumb_text, BR->breadcrumb_link);
|
|
}
|
|
} else if (docs_mode)
|
|
HTMLFormat__breadcrumb(OUT, TL_IS_405, TL_IS_406);
|
|
}
|
|
|
|
#line 282 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__source_code(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int tab_stops_of_indentation, text_stream *prefatory, text_stream *matter,
|
|
text_stream *colouring, text_stream *concluding_comment,
|
|
int starts, int finishes, int code_mode) {
|
|
if (starts) {
|
|
if (Str__len(prefatory) > 0) {
|
|
HTML_OPEN_WITH("span", "class=\"definitionkeyword\"");
|
|
WRITE("%S", prefatory);
|
|
HTML_CLOSE("span");
|
|
WRITE(" ");
|
|
if (Str__eq(prefatory, TL_IS_407)) {
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, matter, L"(%c*) from (%C+) *")) {
|
|
HTMLFormat__source_code(self, OUT, wv, 0, NULL, mr.exp[0], colouring,
|
|
concluding_comment, starts, FALSE, code_mode);
|
|
HTML_OPEN_WITH("span", "class=\"definitionkeyword\"");
|
|
WRITE(" from ");
|
|
HTML_CLOSE("span");
|
|
HTMLFormat__source_code(self, OUT, wv, 0, NULL, mr.exp[1], colouring,
|
|
concluding_comment, FALSE, finishes, code_mode);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
} else
|
|
for (int i=0; i<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 333 "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;
|
|
}
|
|
|
|
}
|
|
#line 313 "inweb/Chapter 5/HTML Formats.w"
|
|
;
|
|
if (Str__get_at(matter, i) == '<') WRITE("<");
|
|
else if (Str__get_at(matter, i) == '>') WRITE(">");
|
|
else if (Str__get_at(matter, i) == '&') WRITE("&");
|
|
else WRITE("%c", Str__get_at(matter, i));
|
|
}
|
|
if (current_colour >= 0) HTML_CLOSE("span");
|
|
current_colour = -1;
|
|
if (finishes) {
|
|
if (Str__len(concluding_comment) > 0) {
|
|
if (!starts) WRITE(" ");
|
|
HTML_OPEN_WITH("span", "class=\"comment\"");
|
|
Formats__text(OUT, wv, concluding_comment);
|
|
HTML_CLOSE("span");
|
|
}
|
|
WRITE("\n");
|
|
}
|
|
}
|
|
|
|
#line 340 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__inline_code(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int enter) {
|
|
if (enter) {
|
|
if (html_in_para == HTML_OUT) HTMLFormat__p(OUT, "inwebparagraph");
|
|
HTML_OPEN_WITH("code", "class=\"display\"");
|
|
} else {
|
|
HTML_CLOSE("code");
|
|
}
|
|
}
|
|
|
|
#line 351 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__display_line(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *from) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
HTML_OPEN("blockquote"); WRITE("\n"); INDENT;
|
|
HTMLFormat__p(OUT, NULL);
|
|
WRITE("%S", from);
|
|
HTMLFormat__cp(OUT);
|
|
OUTDENT; HTML_CLOSE("blockquote"); WRITE("\n");
|
|
}
|
|
|
|
#line 362 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__item(weave_format *self, text_stream *OUT, weave_target *wv, int depth,
|
|
text_stream *label) {
|
|
HTMLFormat__go_to_depth(OUT, depth);
|
|
if (Str__len(label) > 0) WRITE("(%S) ", label);
|
|
else WRITE(" ");
|
|
|
|
}
|
|
|
|
#line 371 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__bar(weave_format *self, text_stream *OUT, weave_target *wv) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
HTML__hr(OUT, NULL);
|
|
}
|
|
|
|
#line 383 "inweb/Chapter 5/HTML Formats.w"
|
|
|
|
void HTMLFormat__figure(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *figname, int w, int h, programming_language *pl) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
filename *F = Filenames__in_folder(
|
|
Pathnames__subfolder(wv->weave_web->md->path_to_web, TL_IS_408),
|
|
figname);
|
|
filename *RF = Filenames__from_text(figname);
|
|
TEMPORARY_TEXT(ext);
|
|
Filenames__write_extension(ext, RF);
|
|
if (Str__eq_insensitive(ext, TL_IS_409)) {
|
|
if (pl == NULL) HTMLFormat__pre(OUT, NULL);
|
|
else HTMLFormat__pre(OUT, NULL);
|
|
if (pl) Painter__reset_syntax_colouring(pl);
|
|
HTML_figure_state hfs;
|
|
hfs.OUT = OUT;
|
|
hfs.colour_as = pl;
|
|
hfs.wv = wv;
|
|
hfs.keywords = (pl)?(&(pl->built_in_keywords)):NULL;
|
|
TextFiles__read(F, FALSE, "unable to read file of textual figure", TRUE,
|
|
&HTMLFormat__text_file_helper, NULL, &hfs);
|
|
if (pl == NULL) HTMLFormat__cpre(OUT);
|
|
else HTMLFormat__cpre(OUT);
|
|
} else {
|
|
HTML_OPEN("center");
|
|
HTML__image(OUT, RF);
|
|
Patterns__copy_file_into_weave(wv->weave_web, F);
|
|
HTML_CLOSE("center");
|
|
}
|
|
DISCARD_TEXT(ext);
|
|
WRITE("\n");
|
|
}
|
|
|
|
void HTMLFormat__text_file_helper(text_stream *text, text_file_position *tfp, void *state) {
|
|
HTML_figure_state *hfs = (HTML_figure_state *) state;
|
|
TEMPORARY_TEXT(colouring);
|
|
LOOP_THROUGH_TEXT(pos, text) PUT_TO(colouring, PLAIN_COLOUR);
|
|
if (hfs->colour_as) {
|
|
Painter__syntax_colour(hfs->colour_as, hfs->OUT, hfs->keywords, text, colouring, TRUE);
|
|
Formats__source_code(hfs->OUT, hfs->wv, 1, TL_IS_410, text, colouring, TL_IS_411, TRUE, TRUE, TRUE);
|
|
} else {
|
|
WRITE_TO(hfs->OUT, "%S\n", text);
|
|
}
|
|
DISCARD_TEXT(colouring);
|
|
}
|
|
|
|
#line 430 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__para_macro(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
para_macro *pmac, int defn) {
|
|
paragraph *P = pmac->defining_paragraph;
|
|
WRITE("<");
|
|
HTML_OPEN_WITH("span", "class=\"%s\"", (defn)?"cwebmacrodefn":"cwebmacro");
|
|
WRITE("%S", pmac->macro_name);
|
|
HTML_CLOSE("span");
|
|
WRITE(" ");
|
|
HTML_OPEN_WITH("span", "class=\"cwebmacronumber\"");
|
|
WRITE("%S", P->paragraph_number);
|
|
HTML_CLOSE("span");
|
|
WRITE(">%s", (defn)?" =":"");
|
|
}
|
|
|
|
#line 445 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__pagebreak(weave_format *self, text_stream *OUT, weave_target *wv) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
}
|
|
|
|
#line 450 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__blank_line(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int in_comment) {
|
|
if (html_in_para == HTML_IN_PRE) {
|
|
WRITE("\n");
|
|
} else {
|
|
int old_state = html_in_para, old_depth = item_depth;
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
if ((old_state == HTML_IN_P) || ((old_state == HTML_IN_LI) && (old_depth > 1)))
|
|
HTMLFormat__p(OUT,"inwebparagraph");
|
|
}
|
|
}
|
|
|
|
#line 463 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__change_material(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int old_material, int new_material, int content) {
|
|
if (old_material != new_material) {
|
|
if (old_material == MACRO_MATERIAL) HTML_CLOSE("code");
|
|
if ((content) || (new_material != MACRO_MATERIAL))
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
switch (old_material) {
|
|
case CODE_MATERIAL:
|
|
case REGULAR_MATERIAL:
|
|
switch (new_material) {
|
|
case CODE_MATERIAL:
|
|
WRITE("\n");
|
|
HTMLFormat__pre(OUT, "display");
|
|
break;
|
|
case DEFINITION_MATERIAL:
|
|
WRITE("\n");
|
|
HTMLFormat__pre(OUT, "definitions");
|
|
break;
|
|
case MACRO_MATERIAL:
|
|
if (content) {
|
|
WRITE("\n");
|
|
HTMLFormat__p(OUT,"macrodefinition");
|
|
}
|
|
HTML_OPEN_WITH("code", "class=\"display\"");
|
|
WRITE("\n");
|
|
break;
|
|
case REGULAR_MATERIAL:
|
|
if (content) {
|
|
WRITE("\n");
|
|
HTMLFormat__p(OUT,"inwebparagraph");
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case MACRO_MATERIAL:
|
|
switch (new_material) {
|
|
case CODE_MATERIAL:
|
|
WRITE("\n");
|
|
HTMLFormat__pre(OUT, "displaydefn");
|
|
break;
|
|
case DEFINITION_MATERIAL:
|
|
WRITE("\n");
|
|
HTMLFormat__pre(OUT, "definitions");
|
|
break;
|
|
}
|
|
break;
|
|
case DEFINITION_MATERIAL:
|
|
switch (new_material) {
|
|
case CODE_MATERIAL:
|
|
WRITE("\n");
|
|
HTMLFormat__pre(OUT, "display");
|
|
break;
|
|
case MACRO_MATERIAL:
|
|
WRITE("\n");
|
|
HTMLFormat__p(OUT, "macrodefinition");
|
|
HTML_OPEN_WITH("code", "class=\"display\"");
|
|
WRITE("\n");
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
HTMLFormat__cpre(OUT);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 531 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__change_colour(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
int col, int in_code) {
|
|
char *cl = "plain";
|
|
switch (col) {
|
|
case DEFINITION_COLOUR: cl = "cwebmacrotext"; break;
|
|
case FUNCTION_COLOUR: cl = "functiontext"; break;
|
|
case IDENTIFIER_COLOUR: cl = "identifier"; break;
|
|
case ELEMENT_COLOUR: cl = "element"; break;
|
|
case RESERVED_COLOUR: cl = "reserved"; break;
|
|
case STRING_COLOUR: cl = "string"; break;
|
|
case CHAR_LITERAL_COLOUR: cl = "character"; break;
|
|
case CONSTANT_COLOUR: cl = "constant"; break;
|
|
case PLAIN_COLOUR: cl = "plain"; break;
|
|
case EXTRACT_COLOUR: cl = "extract"; break;
|
|
case COMMENT_COLOUR: cl = "comment"; break;
|
|
default: PRINT("col: %d\n", col); internal_error("bad colour"); break;
|
|
}
|
|
HTML_OPEN_WITH("span", "class=\"%s\"", cl);
|
|
}
|
|
|
|
#line 552 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__endnote(weave_format *self, text_stream *OUT, weave_target *wv, int end) {
|
|
if (end == 1) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
HTMLFormat__p(OUT, "endnote");
|
|
} else {
|
|
HTMLFormat__cp(OUT);
|
|
}
|
|
}
|
|
|
|
#line 562 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__commentary_text(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *id) {
|
|
for (int i=0; i < Str__len(id); i++) {
|
|
if (html_in_para == HTML_OUT) HTMLFormat__p(OUT, "inwebparagraph");
|
|
if (Str__get_at(id, i) == '&') WRITE("&");
|
|
else if (Str__get_at(id, i) == '<') WRITE("<");
|
|
else if (Str__get_at(id, i) == '>') WRITE(">");
|
|
else if ((i == 0) && (Str__get_at(id, i) == '-') &&
|
|
(Str__get_at(id, i+1) == '-') &&
|
|
((Str__get_at(id, i+2) == ' ') || (Str__get_at(id, i+2) == 0))) {
|
|
WRITE("—"); i++;
|
|
} else if ((Str__get_at(id, i) == ' ') && (Str__get_at(id, i+1) == '-') &&
|
|
(Str__get_at(id, i+2) == '-') &&
|
|
((Str__get_at(id, i+3) == ' ') || (Str__get_at(id, i+3) == '\n') ||
|
|
(Str__get_at(id, i+3) == 0))) {
|
|
WRITE(" —"); i+=2;
|
|
} else PUT(Str__get_at(id, i));
|
|
}
|
|
}
|
|
|
|
#line 583 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__locale(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
paragraph *par1, paragraph *par2) {
|
|
TEMPORARY_TEXT(TEMP)
|
|
HTMLFormat__xref(TEMP, wv, par1, page_section, TRUE);
|
|
HTML__begin_link(OUT, TEMP);
|
|
DISCARD_TEXT(TEMP)
|
|
WRITE("%s%S",
|
|
(Str__get_first_char(par1->ornament) == 'S')?"§":"¶",
|
|
par1->paragraph_number);
|
|
if (par2) WRITE("-%S", par2->paragraph_number);
|
|
HTML__end_link(OUT);
|
|
}
|
|
|
|
#line 597 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__xref(OUTPUT_STREAM, weave_target *wv, paragraph *P, section *from,
|
|
int a_link) {
|
|
TEMPORARY_TEXT(linkto);
|
|
if ((from) && (P->under_section != from)) {
|
|
Str__copy(linkto, P->under_section->sect_range);
|
|
LOOP_THROUGH_TEXT(pos, linkto)
|
|
if ((Str__get(pos) == '/') || (Str__get(pos) == ' '))
|
|
Str__put(pos, '-');
|
|
WRITE_TO(linkto, ".html");
|
|
}
|
|
WRITE("%S%s%S", linkto, (a_link)?"#":"", P->ornament);
|
|
DISCARD_TEXT(linkto);
|
|
|
|
WRITE("P");
|
|
text_stream *N = P->paragraph_number;
|
|
LOOP_THROUGH_TEXT(pos, N)
|
|
if (Str__get(pos) == '.') WRITE("_");
|
|
else PUT(Str__get(pos));
|
|
}
|
|
|
|
#line 618 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__tail(weave_format *self, text_stream *OUT, weave_target *wv,
|
|
text_stream *comment, section *this_S) {
|
|
HTMLFormat__exit_current_paragraph(OUT);
|
|
if (wv->docs_mode) {
|
|
chapter *C = this_S->owning_chapter;
|
|
section *S, *last_S = NULL, *prev_S = NULL, *next_S = NULL;
|
|
LOOP_OVER_LINKED_LIST(S, section, C->sections) {
|
|
if (S == this_S) prev_S = last_S;
|
|
if (last_S == this_S) next_S = S;
|
|
last_S = S;
|
|
}
|
|
if ((prev_S) || (next_S)) {
|
|
HTML__hr(OUT, "tocbar");
|
|
HTML_OPEN_WITH("ul", "class=\"toc\"");
|
|
HTML_OPEN("li");
|
|
if (prev_S == NULL) WRITE("<i>(This section begins %S.)</i>", C->md->ch_title);
|
|
else {
|
|
TEMPORARY_TEXT(TEMP);
|
|
HTMLFormat__sref(TEMP, wv, prev_S);
|
|
HTML__begin_link(OUT, TEMP);
|
|
WRITE("Back to '%S'", prev_S->md->sect_title);
|
|
HTML__end_link(OUT);
|
|
DISCARD_TEXT(TEMP);
|
|
}
|
|
HTML_CLOSE("li");
|
|
HTML_OPEN("li");
|
|
if (next_S == NULL) WRITE("<i>(This section ends %S.)</i>", C->md->ch_title);
|
|
else {
|
|
TEMPORARY_TEXT(TEMP);
|
|
HTMLFormat__sref(TEMP, wv, next_S);
|
|
HTML__begin_link(OUT, TEMP);
|
|
WRITE("Continue with '%S'", next_S->md->sect_title);
|
|
HTML__end_link(OUT);
|
|
DISCARD_TEXT(TEMP);
|
|
}
|
|
HTML_CLOSE("li");
|
|
HTML_CLOSE("ul");
|
|
}
|
|
HTML__hr(OUT, "tocbar");
|
|
}
|
|
HTML__comment(OUT, comment);
|
|
HTML__completed(OUT);
|
|
Bibliographic__set_datum(wv->weave_web->md, TL_IS_412, wv->booklet_title);
|
|
Indexer__cover_sheet_maker(OUT, wv->weave_web, TL_IS_413, wv, WEAVE_SECOND_HALF);
|
|
}
|
|
|
|
#line 665 "inweb/Chapter 5/HTML Formats.w"
|
|
void HTMLFormat__sref(OUTPUT_STREAM, weave_target *wv, section *S) {
|
|
if (S == NULL) internal_error("unwoven section");
|
|
LOOP_THROUGH_TEXT(pos, S->sect_range)
|
|
if (Str__get(pos) == '/')
|
|
PUT('-');
|
|
else
|
|
PUT(Str__get(pos));
|
|
WRITE(".html");
|
|
}
|
|
|
|
#line 678 "inweb/Chapter 5/HTML Formats.w"
|
|
int HTMLFormat__begin_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) {
|
|
TEMPORARY_TEXT(T)
|
|
WRITE_TO(T, "%S", Bibliographic__get_datum(W->md, TL_IS_414));
|
|
W->as_ebook = Epub__new(T, "P");
|
|
filename *CSS = Patterns__obtain_filename(pattern, TL_IS_415);
|
|
Epub__use_CSS_throughout(W->as_ebook, CSS);
|
|
Epub__attach_metadata(W->as_ebook, L"identifier", T);
|
|
DISCARD_TEXT(T)
|
|
|
|
pathname *P = Reader__woven_folder(W);
|
|
W->redirect_weaves_to = Epub__begin_construction(W->as_ebook, P, NULL);
|
|
Shell__copy(CSS, W->redirect_weaves_to, "");
|
|
return SWARM_SECTIONS_SWM;
|
|
}
|
|
|
|
void HTMLFormat__end_weaving_EPUB(weave_format *wf, web *W, weave_pattern *pattern) {
|
|
Epub__end_construction(W->as_ebook);
|
|
}
|
|
|
|
#line 22 "inweb/Chapter 5/Running Through TeX.w"
|
|
void RunningTeX__post_process_weave(weave_target *wv, int open_afterwards, int to_DVI) {
|
|
filename *console_filename = Filenames__set_extension(wv->weave_to, "console");
|
|
filename *log_filename = Filenames__set_extension(wv->weave_to, "log");
|
|
filename *pdf_filename = Filenames__set_extension(wv->weave_to, "pdf");
|
|
|
|
tex_results *res = CREATE(tex_results);
|
|
|
|
{
|
|
#line 52 "inweb/Chapter 5/Running Through TeX.w"
|
|
res->overfull_hbox_count = 0;
|
|
res->tex_error_count = 0;
|
|
res->page_count = 0;
|
|
res->pdf_size = 0;
|
|
res->PDF_filename = pdf_filename;
|
|
|
|
}
|
|
#line 28 "inweb/Chapter 5/Running Through TeX.w"
|
|
;
|
|
wv->post_processing_results = (void *) res;
|
|
|
|
|
|
{
|
|
#line 59 "inweb/Chapter 5/Running Through TeX.w"
|
|
TEMPORARY_TEXT(TEMP)
|
|
filename *tex_rel = Filenames__without_path(wv->weave_to);
|
|
filename *console_rel = Filenames__without_path(console_filename);
|
|
|
|
Shell__plain(TEMP, "cd ");
|
|
Shell__quote_path(TEMP, Filenames__get_path_to(wv->weave_to));
|
|
Shell__plain(TEMP, "; ");
|
|
|
|
text_stream *tool = wv->pattern->pdftex_command;
|
|
if (to_DVI) tool = wv->pattern->tex_command;
|
|
WRITE_TO(TEMP, "%S", tool);
|
|
Shell__plain(TEMP, " -interaction=scrollmode ");
|
|
Shell__quote_file(TEMP, tex_rel);
|
|
Shell__plain(TEMP, ">");
|
|
Shell__quote_file(TEMP, console_rel);
|
|
Shell__run(TEMP);
|
|
DISCARD_TEXT(TEMP)
|
|
|
|
}
|
|
#line 31 "inweb/Chapter 5/Running Through TeX.w"
|
|
;
|
|
|
|
{
|
|
#line 82 "inweb/Chapter 5/Running Through TeX.w"
|
|
TextFiles__read(console_filename, FALSE,
|
|
"can't open console file", TRUE, RunningTeX__scan_console_line, NULL,
|
|
(void *) res);
|
|
|
|
}
|
|
#line 32 "inweb/Chapter 5/Running Through TeX.w"
|
|
;
|
|
|
|
{
|
|
#line 94 "inweb/Chapter 5/Running Through TeX.w"
|
|
if (res->tex_error_count == 0) {
|
|
Shell__rm(console_filename);
|
|
Shell__rm(log_filename);
|
|
Shell__rm(wv->weave_to);
|
|
}
|
|
|
|
}
|
|
#line 33 "inweb/Chapter 5/Running Through TeX.w"
|
|
;
|
|
|
|
if (open_afterwards)
|
|
{
|
|
#line 103 "inweb/Chapter 5/Running Through TeX.w"
|
|
if (Str__len(wv->pattern->open_command) == 0)
|
|
Errors__fatal("no way to open PDF (see pattern.txt file)");
|
|
else
|
|
Shell__apply_S(wv->pattern->open_command, pdf_filename);
|
|
|
|
}
|
|
#line 35 "inweb/Chapter 5/Running Through TeX.w"
|
|
;
|
|
}
|
|
|
|
#line 50 "inweb/Chapter 5/Running Through TeX.w"
|
|
|
|
#line 109 "inweb/Chapter 5/Running Through TeX.w"
|
|
void RunningTeX__scan_console_line(text_stream *line, text_file_position *tfp,
|
|
void *res_V) {
|
|
tex_results *res = (tex_results *) res_V;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line,
|
|
L"Output written %c*? %((%d+) page%c*?(%d+) bytes%).")) {
|
|
res->page_count = Str__atoi(mr.exp[0], 0);
|
|
res->pdf_size = Str__atoi(mr.exp[1], 0);
|
|
}
|
|
if (Regexp__match(&mr, line, L"%c+verfull \\hbox%c+"))
|
|
res->overfull_hbox_count++;
|
|
else if (Str__get_first_char(line) == '!') {
|
|
res->tex_error_count++;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 129 "inweb/Chapter 5/Running Through TeX.w"
|
|
void RunningTeX__report_on_post_processing(weave_target *wv) {
|
|
tex_results *res = wv->post_processing_results;
|
|
if (res) {
|
|
PRINT(": %dpp %dK", res->page_count, res->pdf_size/1024);
|
|
if (res->overfull_hbox_count > 0)
|
|
PRINT(", %d overfull hbox(es)", res->overfull_hbox_count);
|
|
if (res->tex_error_count > 0)
|
|
PRINT(", %d error(s)", res->tex_error_count);
|
|
}
|
|
}
|
|
|
|
#line 143 "inweb/Chapter 5/Running Through TeX.w"
|
|
int RunningTeX__substitute_post_processing_data(text_stream *to, weave_target *wv,
|
|
text_stream *detail) {
|
|
if (wv) {
|
|
tex_results *res = wv->post_processing_results;
|
|
if (res) {
|
|
if (Str__eq_wide_string(detail, L"PDF Size")) {
|
|
WRITE_TO(to, "%dKB", res->pdf_size/1024);
|
|
} else if (Str__eq_wide_string(detail, L"Extent")) {
|
|
WRITE_TO(to, "%dpp", res->page_count);
|
|
} else if (Str__eq_wide_string(detail, L"Leafname")) {
|
|
Str__copy(to, Filenames__get_leafname(res->PDF_filename));
|
|
} else if (Str__eq_wide_string(detail, L"Errors")) {
|
|
Str__clear(to);
|
|
if ((res->overfull_hbox_count > 0) || (res->tex_error_count > 0))
|
|
WRITE_TO(to, ": ");
|
|
if (res->overfull_hbox_count > 0)
|
|
WRITE_TO(to, "%d overfull line%s",
|
|
res->overfull_hbox_count,
|
|
(res->overfull_hbox_count>1)?"s":"");
|
|
if ((res->overfull_hbox_count > 0) && (res->tex_error_count > 0))
|
|
WRITE_TO(to, ", ");
|
|
if (res->tex_error_count > 0)
|
|
WRITE_TO(to, "%d TeX error%s",
|
|
res->tex_error_count,
|
|
(res->tex_error_count>1)?"s":"");
|
|
} else return FALSE;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#line 23 "inweb/Chapter 6/Makefiles.w"
|
|
|
|
void Makefiles__write(web *W, filename *prototype, filename *F, module_search *I) {
|
|
makefile_state MS;
|
|
MS.for_web = W;
|
|
MS.last_line_was_blank = TRUE;
|
|
MS.repeat_block = Str__new();
|
|
MS.inside_block = FALSE;
|
|
MS.allow_commands = TRUE;
|
|
MS.tools_dictionary = Dictionaries__new(16, FALSE);
|
|
MS.webs_dictionary = Dictionaries__new(16, FALSE);
|
|
MS.modules_dictionary = Dictionaries__new(16, FALSE);
|
|
MS.search_path = I;
|
|
MS.repeat_scope = -1;
|
|
MS.repeat_tag = NULL;
|
|
text_stream *OUT = &(MS.to_makefile);
|
|
if (STREAM_OPEN_TO_FILE(OUT, F, ISO_ENC) == FALSE)
|
|
Errors__fatal_with_file("unable to write tangled file", F);
|
|
WRITE("# This makefile was automatically written by inweb -makefile\n");
|
|
WRITE("# and is not intended for human editing\n\n");
|
|
TextFiles__read(prototype, FALSE, "can't open prototype file",
|
|
TRUE, Makefiles__scan_makefile_line, NULL, &MS);
|
|
STREAM_CLOSE(OUT);
|
|
WRITE_TO(STDOUT, "Wrote makefile '%f' from script '%f'\n", F, prototype);
|
|
}
|
|
|
|
#line 49 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__scan_makefile_line(text_stream *line, text_file_position *tfp, void *X) {
|
|
makefile_state *MS = (makefile_state *) X;
|
|
text_stream *OUT = &(MS->to_makefile);
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L" *#%c*")) { Regexp__dispose_of(&mr); return; } // Skip comment lines
|
|
if (MS->allow_commands) {
|
|
if (Regexp__match(&mr, line, L" *{repeat-tools-block:(%C*)} *"))
|
|
|
|
{
|
|
#line 93 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_TOOL_MOM;
|
|
|
|
{
|
|
#line 105 "inweb/Chapter 6/Makefiles.w"
|
|
if (MS->inside_block) Errors__in_text_file("nested repeat blocks are not allowed", tfp);
|
|
MS->inside_block = TRUE;
|
|
MS->repeat_scope = marker;
|
|
MS->repeat_tag = Str__duplicate(mr.exp[0]);
|
|
Str__clear(MS->repeat_block);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 94 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 57 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *{repeat-webs-block:(%C*)} *"))
|
|
|
|
{
|
|
#line 97 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_WEB_MOM;
|
|
|
|
{
|
|
#line 105 "inweb/Chapter 6/Makefiles.w"
|
|
if (MS->inside_block) Errors__in_text_file("nested repeat blocks are not allowed", tfp);
|
|
MS->inside_block = TRUE;
|
|
MS->repeat_scope = marker;
|
|
MS->repeat_tag = Str__duplicate(mr.exp[0]);
|
|
Str__clear(MS->repeat_block);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 98 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 59 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *{repeat-modules-block:(%C*)} *"))
|
|
|
|
{
|
|
#line 101 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_MODULE_MOM;
|
|
|
|
{
|
|
#line 105 "inweb/Chapter 6/Makefiles.w"
|
|
if (MS->inside_block) Errors__in_text_file("nested repeat blocks are not allowed", tfp);
|
|
MS->inside_block = TRUE;
|
|
MS->repeat_scope = marker;
|
|
MS->repeat_tag = Str__duplicate(mr.exp[0]);
|
|
Str__clear(MS->repeat_block);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 102 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 61 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *{end-block} *"))
|
|
{
|
|
#line 118 "inweb/Chapter 6/Makefiles.w"
|
|
if (MS->inside_block == FALSE)
|
|
Errors__in_text_file("{endblock} without {repeatblock}", tfp);
|
|
MS->inside_block = FALSE;
|
|
Makefiles__repeat(OUT, NULL, TRUE, MS->repeat_block, TRUE, NULL, tfp, MS, MS->repeat_scope, MS->repeat_tag);
|
|
Str__clear(MS->repeat_block);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 62 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (MS->inside_block)
|
|
{
|
|
#line 114 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE_TO(MS->repeat_block, "%S\n", line);
|
|
return;
|
|
|
|
}
|
|
#line 63 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
if (Regexp__match(&mr, line, L"(%c*){repeat-tools-span}(%c*?){end-span}(%c*)"))
|
|
|
|
{
|
|
#line 127 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_TOOL_MOM;
|
|
|
|
{
|
|
#line 139 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%S", mr.exp[0]);
|
|
Makefiles__repeat(OUT, TL_IS_416, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_417);
|
|
WRITE("%S\n", mr.exp[2]);
|
|
MS->last_line_was_blank = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 128 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 66 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L"(%c*){repeat-webs-span}(%c*?){end-span}(%c*)"))
|
|
|
|
{
|
|
#line 131 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_WEB_MOM;
|
|
|
|
{
|
|
#line 139 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%S", mr.exp[0]);
|
|
Makefiles__repeat(OUT, TL_IS_416, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_417);
|
|
WRITE("%S\n", mr.exp[2]);
|
|
MS->last_line_was_blank = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 132 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 68 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L"(%c*){repeat-modules-span}(%c*?){end-span}(%c*)"))
|
|
|
|
{
|
|
#line 135 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_MODULE_MOM;
|
|
|
|
{
|
|
#line 139 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%S", mr.exp[0]);
|
|
Makefiles__repeat(OUT, TL_IS_416, FALSE, mr.exp[1], FALSE, NULL, tfp, MS, marker, TL_IS_417);
|
|
WRITE("%S\n", mr.exp[2]);
|
|
MS->last_line_was_blank = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 136 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 70 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
if (Regexp__match(&mr, line, L" *{identity-settings} *"))
|
|
{
|
|
#line 156 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("INWEB = "); Makefiles__pathname_slashed(OUT, path_to_inweb); WRITE("/Tangled/inweb\n");
|
|
pathname *path_to_intest = Pathnames__subfolder(Pathnames__up(path_to_inweb), TL_IS_419);
|
|
WRITE("INTEST = "); Makefiles__pathname_slashed(OUT, path_to_intest); WRITE("/Tangled/intest\n");
|
|
if (MS->for_web) {
|
|
WRITE("MYNAME = %S\n", Pathnames__directory_name(MS->for_web->md->path_to_web));
|
|
WRITE("ME = "); Makefiles__pathname_slashed(OUT, MS->for_web->md->path_to_web);
|
|
WRITE("\n");
|
|
MS->last_line_was_blank = FALSE;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 72 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *{platform-settings} *"))
|
|
{
|
|
#line 147 "inweb/Chapter 6/Makefiles.w"
|
|
filename *prototype = Filenames__in_folder(path_to_inweb, TL_IS_418);
|
|
MS->allow_commands = FALSE;
|
|
TextFiles__read(prototype, FALSE, "can't open make settings file",
|
|
TRUE, Makefiles__scan_makefile_line, NULL, MS);
|
|
Regexp__dispose_of(&mr);
|
|
MS->allow_commands = TRUE;
|
|
return;
|
|
|
|
}
|
|
#line 73 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
if (Regexp__match(&mr, line, L" *{tool} *(%C+) (%C+) (%c+) (%C+) *"))
|
|
{
|
|
#line 169 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_TOOL_MOM;
|
|
|
|
{
|
|
#line 181 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%SLEAF = %S\n", mr.exp[0], mr.exp[1]);
|
|
WRITE("%SWEB = %S\n", mr.exp[0], mr.exp[2]);
|
|
WRITE("%SMAKER = $(%SWEB)/%S.mk\n", mr.exp[0], mr.exp[0], mr.exp[1]);
|
|
WRITE("%SX = $(%SWEB)/Tangled/%S\n", mr.exp[0], mr.exp[0], mr.exp[1]);
|
|
MS->last_line_was_blank = FALSE;
|
|
web_md *Wm = Reader__load_web_md(Pathnames__from_text(mr.exp[2]), NULL, MS->search_path, FALSE, TRUE);
|
|
Wm->as_module->module_name = Str__duplicate(mr.exp[0]);
|
|
Wm->as_module->module_tag = Str__duplicate(mr.exp[3]);
|
|
Wm->as_module->origin_marker = marker;
|
|
Dictionaries__create(MS->tools_dictionary, mr.exp[0]);
|
|
Dictionaries__write_value(MS->tools_dictionary, mr.exp[0], Wm);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 170 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 75 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *{web} *(%C+) (%C+) (%c+) (%C+) *"))
|
|
{
|
|
#line 173 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_WEB_MOM;
|
|
|
|
{
|
|
#line 181 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%SLEAF = %S\n", mr.exp[0], mr.exp[1]);
|
|
WRITE("%SWEB = %S\n", mr.exp[0], mr.exp[2]);
|
|
WRITE("%SMAKER = $(%SWEB)/%S.mk\n", mr.exp[0], mr.exp[0], mr.exp[1]);
|
|
WRITE("%SX = $(%SWEB)/Tangled/%S\n", mr.exp[0], mr.exp[0], mr.exp[1]);
|
|
MS->last_line_was_blank = FALSE;
|
|
web_md *Wm = Reader__load_web_md(Pathnames__from_text(mr.exp[2]), NULL, MS->search_path, FALSE, TRUE);
|
|
Wm->as_module->module_name = Str__duplicate(mr.exp[0]);
|
|
Wm->as_module->module_tag = Str__duplicate(mr.exp[3]);
|
|
Wm->as_module->origin_marker = marker;
|
|
Dictionaries__create(MS->tools_dictionary, mr.exp[0]);
|
|
Dictionaries__write_value(MS->tools_dictionary, mr.exp[0], Wm);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 174 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 76 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L" *{module} *(%C+) (%C+) (%c+) (%C+) *"))
|
|
{
|
|
#line 177 "inweb/Chapter 6/Makefiles.w"
|
|
int marker = MAKEFILE_MODULE_MOM;
|
|
|
|
{
|
|
#line 181 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%SLEAF = %S\n", mr.exp[0], mr.exp[1]);
|
|
WRITE("%SWEB = %S\n", mr.exp[0], mr.exp[2]);
|
|
WRITE("%SMAKER = $(%SWEB)/%S.mk\n", mr.exp[0], mr.exp[0], mr.exp[1]);
|
|
WRITE("%SX = $(%SWEB)/Tangled/%S\n", mr.exp[0], mr.exp[0], mr.exp[1]);
|
|
MS->last_line_was_blank = FALSE;
|
|
web_md *Wm = Reader__load_web_md(Pathnames__from_text(mr.exp[2]), NULL, MS->search_path, FALSE, TRUE);
|
|
Wm->as_module->module_name = Str__duplicate(mr.exp[0]);
|
|
Wm->as_module->module_tag = Str__duplicate(mr.exp[3]);
|
|
Wm->as_module->origin_marker = marker;
|
|
Dictionaries__create(MS->tools_dictionary, mr.exp[0]);
|
|
Dictionaries__write_value(MS->tools_dictionary, mr.exp[0], Wm);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 178 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
}
|
|
#line 77 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
|
|
if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files} *"))
|
|
{
|
|
#line 196 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%S", mr.exp[0]);
|
|
Makefiles__pattern(OUT, MS->for_web->md->sections_md, MS->for_web->md->contents_filename);
|
|
WRITE("\n");
|
|
MS->last_line_was_blank = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 79 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files-for-tool-alone} *(%C+)"))
|
|
|
|
{
|
|
#line 221 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%S", mr.exp[0]);
|
|
if (Dictionaries__find(MS->tools_dictionary, mr.exp[1])) {
|
|
web_md *Wm = Dictionaries__read_value(MS->tools_dictionary, mr.exp[1]);
|
|
Makefiles__pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename);
|
|
} else if (Dictionaries__find(MS->webs_dictionary, mr.exp[1])) {
|
|
web_md *Wm = Dictionaries__read_value(MS->webs_dictionary, mr.exp[1]);
|
|
Makefiles__pattern(OUT, Wm->as_module->sections_md, Wm->contents_filename);
|
|
} else {
|
|
PRINT("Tool %S\n", mr.exp[0]);
|
|
Errors__in_text_file("unknown tool to find dependencies for", tfp);
|
|
}
|
|
WRITE("\n");
|
|
MS->last_line_was_blank = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 81 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files-for-tool-and-modules} *(%C+)"))
|
|
|
|
{
|
|
#line 204 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%S", mr.exp[0]);
|
|
if (Dictionaries__find(MS->tools_dictionary, mr.exp[1])) {
|
|
web_md *Wm = Dictionaries__read_value(MS->tools_dictionary, mr.exp[1]);
|
|
Makefiles__pattern(OUT, Wm->sections_md, Wm->contents_filename);
|
|
} else if (Dictionaries__find(MS->webs_dictionary, mr.exp[1])) {
|
|
web_md *Wm = Dictionaries__read_value(MS->webs_dictionary, mr.exp[1]);
|
|
Makefiles__pattern(OUT, Wm->sections_md, Wm->contents_filename);
|
|
} else {
|
|
PRINT("Tool %S\n", mr.exp[0]);
|
|
Errors__in_text_file("unknown tool to find dependencies for", tfp);
|
|
}
|
|
WRITE("\n");
|
|
MS->last_line_was_blank = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 83 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
if (Regexp__match(&mr, line, L"(%c*?) *{dependent-files-for-module} *(%C+)"))
|
|
|
|
{
|
|
#line 238 "inweb/Chapter 6/Makefiles.w"
|
|
WRITE("%S", mr.exp[0]);
|
|
if (Dictionaries__find(MS->modules_dictionary, mr.exp[1])) {
|
|
web_md *Wm = Dictionaries__read_value(MS->modules_dictionary, mr.exp[1]);
|
|
Makefiles__pattern(OUT, Wm->sections_md, Wm->contents_filename);
|
|
} else {
|
|
Errors__in_text_file("unknown module to find dependencies for", tfp);
|
|
}
|
|
WRITE("\n");
|
|
MS->last_line_was_blank = FALSE;
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 85 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
|
|
|
|
{
|
|
#line 251 "inweb/Chapter 6/Makefiles.w"
|
|
if (Str__len(line) == 0) {
|
|
if (MS->last_line_was_blank == FALSE) WRITE("\n");
|
|
MS->last_line_was_blank = TRUE;
|
|
} else {
|
|
MS->last_line_was_blank = FALSE;
|
|
WRITE("%S\n", line);
|
|
}
|
|
|
|
}
|
|
#line 89 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
}
|
|
|
|
#line 260 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__pathname_slashed(OUTPUT_STREAM, pathname *P) {
|
|
TEMPORARY_TEXT(PT)
|
|
WRITE_TO(PT, "%p", P);
|
|
LOOP_THROUGH_TEXT(pos, PT) {
|
|
wchar_t c = Str__get(pos);
|
|
if (c == ' ') WRITE("\\ ");
|
|
else PUT(c);
|
|
}
|
|
DISCARD_TEXT(PT)
|
|
}
|
|
|
|
void Makefiles__pattern(OUTPUT_STREAM, linked_list *L, filename *F) {
|
|
dictionary *patterns_done = Dictionaries__new(16, TRUE);
|
|
if (F)
|
|
{
|
|
#line 282 "inweb/Chapter 6/Makefiles.w"
|
|
pathname *P = Filenames__get_path_to(F);
|
|
TEMPORARY_TEXT(leaf_pattern);
|
|
WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P));
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, leaf_pattern, L"Chapter %d*")) {
|
|
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Chapter*");
|
|
} else if (Regexp__match(&mr, leaf_pattern, L"Appendix %C")) {
|
|
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Appendix*");
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
TEMPORARY_TEXT(tester);
|
|
WRITE_TO(tester, "%p/%S/*", Pathnames__up(P), leaf_pattern);
|
|
DISCARD_TEXT(leaf_pattern);
|
|
Filenames__write_extension(tester, F);
|
|
if (Dictionaries__find(patterns_done, tester) == NULL) {
|
|
WRITE_TO(Dictionaries__create_text(patterns_done, tester), "got this");
|
|
WRITE(" ");
|
|
LOOP_THROUGH_TEXT(pos, tester) {
|
|
wchar_t c = Str__get(pos);
|
|
if (c == ' ') PUT('\\');
|
|
PUT(c);
|
|
}
|
|
}
|
|
DISCARD_TEXT(tester);
|
|
|
|
}
|
|
#line 273 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
section_md *Sm;
|
|
LOOP_OVER_LINKED_LIST(Sm, section_md, L) {
|
|
filename *F = Sm->source_file_for_section;
|
|
|
|
{
|
|
#line 282 "inweb/Chapter 6/Makefiles.w"
|
|
pathname *P = Filenames__get_path_to(F);
|
|
TEMPORARY_TEXT(leaf_pattern);
|
|
WRITE_TO(leaf_pattern, "%S", Pathnames__directory_name(P));
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, leaf_pattern, L"Chapter %d*")) {
|
|
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Chapter*");
|
|
} else if (Regexp__match(&mr, leaf_pattern, L"Appendix %C")) {
|
|
Str__clear(leaf_pattern); WRITE_TO(leaf_pattern, "Appendix*");
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
TEMPORARY_TEXT(tester);
|
|
WRITE_TO(tester, "%p/%S/*", Pathnames__up(P), leaf_pattern);
|
|
DISCARD_TEXT(leaf_pattern);
|
|
Filenames__write_extension(tester, F);
|
|
if (Dictionaries__find(patterns_done, tester) == NULL) {
|
|
WRITE_TO(Dictionaries__create_text(patterns_done, tester), "got this");
|
|
WRITE(" ");
|
|
LOOP_THROUGH_TEXT(pos, tester) {
|
|
wchar_t c = Str__get(pos);
|
|
if (c == ' ') PUT('\\');
|
|
PUT(c);
|
|
}
|
|
}
|
|
DISCARD_TEXT(tester);
|
|
|
|
}
|
|
#line 277 "inweb/Chapter 6/Makefiles.w"
|
|
;
|
|
}
|
|
}
|
|
|
|
#line 310 "inweb/Chapter 6/Makefiles.w"
|
|
void Makefiles__repeat(OUTPUT_STREAM, text_stream *prefix, int every_time, text_stream *matter,
|
|
int as_lines, text_stream *suffix, text_file_position *tfp, makefile_state *MS, int over, text_stream *tag) {
|
|
module *M;
|
|
int c = 0;
|
|
LOOP_OVER(M, module) {
|
|
if ((M->origin_marker == over) &&
|
|
((Str__eq(tag, TL_IS_420)) || (Str__eq(tag, M->module_tag)))) {
|
|
if ((prefix) && ((c++ > 0) || (every_time))) WRITE("%S", prefix);
|
|
if (matter) {
|
|
TEMPORARY_TEXT(line);
|
|
LOOP_THROUGH_TEXT(pos, matter) {
|
|
if (Str__get(pos) == '\n') {
|
|
if (as_lines) {
|
|
Makefiles__scan_makefile_line(line, tfp, (void *) MS);
|
|
Str__clear(line);
|
|
}
|
|
} else {
|
|
if (Str__get(pos) == '@') {
|
|
WRITE_TO(line, "%S", M->module_name);
|
|
} else {
|
|
PUT_TO(line, Str__get(pos));
|
|
}
|
|
}
|
|
}
|
|
if (!as_lines) WRITE("%S", line);
|
|
DISCARD_TEXT(line);
|
|
}
|
|
if (suffix) WRITE("%S", suffix);
|
|
}
|
|
}
|
|
}
|
|
|
|
#line 14 "inweb/Chapter 6/Git Support.w"
|
|
|
|
void Git__write_gitignore(web *W, filename *prototype, filename *F) {
|
|
gitignore_state MS;
|
|
MS.for_web = W;
|
|
MS.last_line_was_blank = TRUE;
|
|
text_stream *OUT = &(MS.to_gitignore);
|
|
if (STREAM_OPEN_TO_FILE(OUT, F, ISO_ENC) == FALSE)
|
|
Errors__fatal_with_file("unable to write tangled file", F);
|
|
WRITE("# This gitignore was automatically written by inweb -gitignore\n");
|
|
WRITE("# and is not intended for human editing\n\n");
|
|
TextFiles__read(prototype, FALSE, "can't open prototype file",
|
|
TRUE, Git__copy_gitignore_line, NULL, &MS);
|
|
STREAM_CLOSE(OUT);
|
|
WRITE_TO(STDOUT, "Wrote gitignore file '%f' from script '%f'\n", F, prototype);
|
|
}
|
|
|
|
#line 31 "inweb/Chapter 6/Git Support.w"
|
|
void Git__copy_gitignore_line(text_stream *line, text_file_position *tfp, void *X) {
|
|
gitignore_state *MS = (gitignore_state *) X;
|
|
text_stream *OUT = &(MS->to_gitignore);
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, line, L" *#%c*")) { Regexp__dispose_of(&mr); return; }
|
|
if (Regexp__match(&mr, line, L" *{basics} *"))
|
|
{
|
|
#line 44 "inweb/Chapter 6/Git Support.w"
|
|
filename *prototype =
|
|
Filenames__in_folder(path_to_inweb_materials, TL_IS_421);
|
|
TextFiles__read(prototype, FALSE, "can't open make settings file",
|
|
TRUE, Git__copy_gitignore_line, NULL, MS);
|
|
Regexp__dispose_of(&mr);
|
|
return;
|
|
|
|
}
|
|
#line 37 "inweb/Chapter 6/Git Support.w"
|
|
;
|
|
Regexp__dispose_of(&mr);
|
|
|
|
|
|
{
|
|
#line 52 "inweb/Chapter 6/Git Support.w"
|
|
if (Str__len(line) == 0) {
|
|
if (MS->last_line_was_blank == FALSE) WRITE("\n");
|
|
MS->last_line_was_blank = TRUE;
|
|
} else {
|
|
MS->last_line_was_blank = FALSE;
|
|
WRITE("%S\n", line);
|
|
}
|
|
|
|
}
|
|
#line 40 "inweb/Chapter 6/Git Support.w"
|
|
;
|
|
}
|
|
|
|
#line 18 "inweb/Chapter 6/Readme Writeme.w"
|
|
|
|
void Readme__write(filename *from, filename *to) {
|
|
WRITE_TO(STDOUT, "write-me: %f --> %f\n", from, to);
|
|
write_state ws;
|
|
ws.current_definition = NULL;
|
|
ws.known_macros = NEW_LINKED_LIST(macro);
|
|
macro *V = Readme__new_macro(TL_IS_422, NULL, NULL);
|
|
ADD_TO_LINKED_LIST(V, macro, ws.known_macros);
|
|
macro *P = Readme__new_macro(TL_IS_423, NULL, NULL);
|
|
ADD_TO_LINKED_LIST(P, macro, ws.known_macros);
|
|
macro *A = Readme__new_macro(TL_IS_424, NULL, NULL);
|
|
ADD_TO_LINKED_LIST(A, macro, ws.known_macros);
|
|
ws.stack_frame = NULL;
|
|
text_stream file_to;
|
|
if (Streams__open_to_file(&file_to, to, UTF8_ENC) == FALSE)
|
|
Errors__fatal_with_file("can't write readme file", to);
|
|
ws.OUT = &file_to;
|
|
TextFiles__read(from, FALSE, "unable to read template file", TRUE,
|
|
&Readme__write_helper, NULL, (void *) &ws);
|
|
Streams__close(&file_to);
|
|
}
|
|
|
|
#line 44 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__write_helper(text_stream *text, text_file_position *tfp, void *state) {
|
|
write_state *ws = (write_state *) state;
|
|
text_stream *OUT = ws->OUT;
|
|
|
|
match_results mr = Regexp__create_mr();
|
|
if (Regexp__match(&mr, text, L" *@end *")) {
|
|
if (ws->current_definition == NULL)
|
|
Errors__in_text_file("@end without @define", tfp);
|
|
else ws->current_definition = NULL;
|
|
} else if (ws->current_definition) {
|
|
if (Str__len(ws->current_definition->content) > 0)
|
|
WRITE_TO(ws->current_definition->content, "\n");
|
|
WRITE_TO(ws->current_definition->content, "%S", text);
|
|
} else if (Regexp__match(&mr, text, L" *@define (%i+)(%c*)")) {
|
|
if (ws->current_definition)
|
|
Errors__in_text_file("@define without @end", tfp);
|
|
else {
|
|
macro *M = Readme__new_macro(mr.exp[0], mr.exp[1], tfp);
|
|
ws->current_definition = M;
|
|
ADD_TO_LINKED_LIST(M, macro, ws->known_macros);
|
|
}
|
|
} else {
|
|
Readme__expand_material(ws, OUT, text, tfp);
|
|
Readme__expand_material(ws, OUT, TL_IS_425, tfp);
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 82 "inweb/Chapter 6/Readme Writeme.w"
|
|
|
|
macro *Readme__new_macro(text_stream *name, text_stream *tokens, text_file_position *tfp) {
|
|
macro *M = CREATE(macro);
|
|
M->name = Str__duplicate(name);
|
|
M->tokens = Readme__parse_token_list(tokens, tfp);
|
|
M->content = Str__new();
|
|
return M;
|
|
}
|
|
|
|
#line 98 "inweb/Chapter 6/Readme Writeme.w"
|
|
|
|
#line 100 "inweb/Chapter 6/Readme Writeme.w"
|
|
macro_tokens Readme__parse_token_list(text_stream *chunk, text_file_position *tfp) {
|
|
macro_tokens mt;
|
|
mt.no_pars = 0;
|
|
mt.down = NULL;
|
|
mt.bound_to = NULL;
|
|
if (Str__get_first_char(chunk) == '(') {
|
|
int x = 1, bl = 1, from = 1, quoted = FALSE;
|
|
while ((bl > 0) && (Str__get_at(chunk, x) != 0)) {
|
|
wchar_t c = Str__get_at(chunk, x);
|
|
if (c == '\'') {
|
|
quoted = quoted?FALSE:TRUE;
|
|
} else if (quoted == FALSE) {
|
|
if (c == '(') bl++;
|
|
else if (c == ')') {
|
|
bl--;
|
|
if (bl == 0)
|
|
{
|
|
#line 129 "inweb/Chapter 6/Readme Writeme.w"
|
|
int n = mt.no_pars;
|
|
if (n >= 8) Errors__in_text_file("too many parameters", tfp);
|
|
else {
|
|
mt.pars[n] = Str__new();
|
|
for (int j=from; j<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_426))
|
|
{
|
|
#line 215 "inweb/Chapter 6/Readme Writeme.w"
|
|
if (ws->stack_frame->no_pars != 1)
|
|
Errors__in_text_file("@version takes 1 parameter", tfp);
|
|
else {
|
|
TEMPORARY_TEXT(program);
|
|
Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp);
|
|
Readme__write_var(OUT, program, TL_IS_429);
|
|
DISCARD_TEXT(program);
|
|
}
|
|
|
|
}
|
|
#line 205 "inweb/Chapter 6/Readme Writeme.w"
|
|
|
|
else if (Str__eq(M->name, TL_IS_427))
|
|
{
|
|
#line 225 "inweb/Chapter 6/Readme Writeme.w"
|
|
if (ws->stack_frame->no_pars != 1)
|
|
Errors__in_text_file("@purpose takes 1 parameter", tfp);
|
|
else {
|
|
TEMPORARY_TEXT(program);
|
|
Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp);
|
|
Readme__write_var(OUT, program, TL_IS_430);
|
|
DISCARD_TEXT(program);
|
|
}
|
|
|
|
}
|
|
#line 206 "inweb/Chapter 6/Readme Writeme.w"
|
|
|
|
else if (Str__eq(M->name, TL_IS_428))
|
|
{
|
|
#line 235 "inweb/Chapter 6/Readme Writeme.w"
|
|
if (ws->stack_frame->no_pars != 2)
|
|
Errors__in_text_file("@var takes 2 parameters", tfp);
|
|
else {
|
|
TEMPORARY_TEXT(program);
|
|
TEMPORARY_TEXT(bibv);
|
|
Readme__expand_material(ws, program, ws->stack_frame->pars[0], tfp);
|
|
Readme__expand_material(ws, bibv, ws->stack_frame->pars[1], tfp);
|
|
Readme__write_var(OUT, program, bibv);
|
|
DISCARD_TEXT(program);
|
|
DISCARD_TEXT(bibv);
|
|
}
|
|
|
|
}
|
|
#line 207 "inweb/Chapter 6/Readme Writeme.w"
|
|
|
|
else {
|
|
ws->stack_frame->bound_to = M;
|
|
Readme__expand_material(ws, OUT, M->content, tfp);
|
|
}
|
|
}
|
|
|
|
#line 262 "inweb/Chapter 6/Readme Writeme.w"
|
|
|
|
void Readme__write_var(text_stream *OUT, text_stream *program, text_stream *datum) {
|
|
writeme_asset *A = Readme__find_asset(program);
|
|
if (A->if_web) WRITE("%S", Bibliographic__get_datum(A->if_web, datum));
|
|
else if (Str__eq(datum, TL_IS_431)) WRITE("%S", A->date);
|
|
else if (Str__eq(datum, TL_IS_432)) WRITE("%S", A->version);
|
|
}
|
|
|
|
#line 273 "inweb/Chapter 6/Readme Writeme.w"
|
|
writeme_asset *Readme__find_asset(text_stream *program) {
|
|
writeme_asset *A;
|
|
LOOP_OVER(A, writeme_asset) if (Str__eq(program, A->name)) return A;
|
|
A = CREATE(writeme_asset);
|
|
A->name = Str__duplicate(program);
|
|
A->if_web = NULL;
|
|
A->date = Str__new();
|
|
A->version = Str__new();
|
|
A->next_is_version = FALSE;
|
|
|
|
{
|
|
#line 287 "inweb/Chapter 6/Readme Writeme.w"
|
|
if (Str__ends_with_wide_string(program, L".i7x")) {
|
|
|
|
{
|
|
#line 306 "inweb/Chapter 6/Readme Writeme.w"
|
|
TextFiles__read(Filenames__from_text(program), FALSE, "unable to read extension", TRUE,
|
|
&Readme__extension_harvester, NULL, A);
|
|
|
|
}
|
|
#line 288 "inweb/Chapter 6/Readme Writeme.w"
|
|
;
|
|
} else {
|
|
if (WebMetadata__directory_looks_like_a_web(Pathnames__from_text(program))) {
|
|
A->if_web = WebMetadata__get_without_modules(Pathnames__from_text(program), NULL);
|
|
} else {
|
|
filename *I6_vn = Filenames__in_folder(
|
|
Pathnames__subfolder(Pathnames__from_text(program), TL_IS_433), TL_IS_434);
|
|
if (TextFiles__exists(I6_vn))
|
|
{
|
|
#line 310 "inweb/Chapter 6/Readme Writeme.w"
|
|
TextFiles__read(I6_vn, FALSE, "unable to read header file from I6 source", TRUE,
|
|
&Readme__header_harvester, NULL, A);
|
|
|
|
}
|
|
#line 295 "inweb/Chapter 6/Readme Writeme.w"
|
|
;
|
|
filename *template_vn = Filenames__in_folder(Pathnames__from_text(program), TL_IS_435);
|
|
if (TextFiles__exists(template_vn))
|
|
{
|
|
#line 314 "inweb/Chapter 6/Readme Writeme.w"
|
|
TextFiles__read(template_vn, FALSE, "unable to read manifest file from website template", TRUE,
|
|
&Readme__template_harvester, NULL, A);
|
|
|
|
}
|
|
#line 297 "inweb/Chapter 6/Readme Writeme.w"
|
|
;
|
|
filename *rmt_vn = Filenames__in_folder(Pathnames__from_text(program), TL_IS_436);
|
|
if (TextFiles__exists(rmt_vn))
|
|
{
|
|
#line 318 "inweb/Chapter 6/Readme Writeme.w"
|
|
TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE,
|
|
&Readme__readme_harvester, NULL, A);
|
|
|
|
}
|
|
#line 299 "inweb/Chapter 6/Readme Writeme.w"
|
|
;
|
|
rmt_vn = Filenames__in_folder(Pathnames__from_text(program), TL_IS_437);
|
|
if (TextFiles__exists(rmt_vn))
|
|
{
|
|
#line 318 "inweb/Chapter 6/Readme Writeme.w"
|
|
TextFiles__read(rmt_vn, FALSE, "unable to read README file from website template", TRUE,
|
|
&Readme__readme_harvester, NULL, A);
|
|
|
|
}
|
|
#line 301 "inweb/Chapter 6/Readme Writeme.w"
|
|
;
|
|
}
|
|
}
|
|
|
|
}
|
|
#line 282 "inweb/Chapter 6/Readme Writeme.w"
|
|
;
|
|
return A;
|
|
}
|
|
|
|
#line 324 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__extension_harvester(text_stream *text, text_file_position *tfp, void *state) {
|
|
writeme_asset *A = (writeme_asset *) state;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Str__len(text) == 0) return;
|
|
if (Regexp__match(&mr, text, L" *Version (%c*?) of %c*begins here. *"))
|
|
A->version = Str__duplicate(mr.exp[0]);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 336 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__header_harvester(text_stream *text, text_file_position *tfp, void *state) {
|
|
writeme_asset *A = (writeme_asset *) state;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Str__len(text) == 0) return;
|
|
if (Regexp__match(&mr, text, L"#define RELEASE_NUMBER (%c*?) *"))
|
|
A->version = Str__duplicate(mr.exp[0]);
|
|
if (Regexp__match(&mr, text, L"#define RELEASE_DATE \"(%c*?)\" *"))
|
|
A->date = Str__duplicate(mr.exp[0]);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 350 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__template_harvester(text_stream *text, text_file_position *tfp, void *state) {
|
|
writeme_asset *A = (writeme_asset *) state;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Str__len(text) == 0) return;
|
|
if (Regexp__match(&mr, text, L"%[INTERPRETERVERSION%]")) {
|
|
A->next_is_version = TRUE;
|
|
} else if (A->next_is_version) {
|
|
A->version = Str__duplicate(text);
|
|
A->next_is_version = FALSE;
|
|
}
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
#line 366 "inweb/Chapter 6/Readme Writeme.w"
|
|
void Readme__readme_harvester(text_stream *text, text_file_position *tfp, void *state) {
|
|
writeme_asset *A = (writeme_asset *) state;
|
|
match_results mr = Regexp__create_mr();
|
|
if (Str__len(text) == 0) return;
|
|
if ((Regexp__match(&mr, text, L"CheapGlk Library: version (%c*?) *")) ||
|
|
(Regexp__match(&mr, text, L"- Version (%c*?) *")))
|
|
A->version = Str__duplicate(mr.exp[0]);
|
|
Regexp__dispose_of(&mr);
|
|
}
|
|
|
|
void register_tangled_nonterminals(void) {
|
|
}
|
|
void register_tangled_text_literals(void) {
|
|
TL_IS_0 = Str__literal(L"strings");
|
|
TL_IS_1 = Str__literal(L"Hello");
|
|
TL_IS_2 = Str__literal(L"debug-log.txt");
|
|
TL_IS_3 = Str__literal(L"Tangled");
|
|
TL_IS_4 = Str__literal(L"wayzgoose");
|
|
TL_IS_5 = Str__literal(L"snow goose");
|
|
TL_IS_6 = Str__literal(L"fish");
|
|
TL_IS_7 = Str__literal(L"ePub");
|
|
TL_IS_8 = Str__literal(L"OEBPS");
|
|
TL_IS_9 = Str__literal(L"mimetype");
|
|
TL_IS_10 = Str__literal(L"META-INF");
|
|
TL_IS_11 = Str__literal(L"container.xml");
|
|
TL_IS_12 = Str__literal(L"cover.html");
|
|
TL_IS_13 = Str__literal(L"Cover");
|
|
TL_IS_14 = Str__literal(L"cover");
|
|
TL_IS_15 = Str__literal(L"content.opf");
|
|
TL_IS_16 = Str__literal(L"toc.ncx");
|
|
TL_IS_17 = Str__literal(L"..");
|
|
TL_IS_18 = Str__literal(L"A");
|
|
TL_IS_19 = Str__literal(L"Web Syntax Version: 1");
|
|
TL_IS_20 = Str__literal(L"Web Syntax Version: 2");
|
|
TL_IS_21 = Str__literal(L"S");
|
|
TL_IS_22 = Str__literal(L"Sections");
|
|
TL_IS_23 = Str__literal(L"All");
|
|
TL_IS_24 = Str__literal(L"Headers");
|
|
TL_IS_25 = Str__literal(L"Language");
|
|
TL_IS_26 = Str__literal(L"Language");
|
|
TL_IS_27 = Str__literal(L"Contents.w");
|
|
TL_IS_28 = Str__literal(L"Author");
|
|
TL_IS_29 = Str__literal(L"Language");
|
|
TL_IS_30 = Str__literal(L"Purpose");
|
|
TL_IS_31 = Str__literal(L"Title");
|
|
TL_IS_32 = Str__literal(L"License");
|
|
TL_IS_33 = Str__literal(L"Licence");
|
|
TL_IS_34 = Str__literal(L"Short Title");
|
|
TL_IS_35 = Str__literal(L"Capitalized Title");
|
|
TL_IS_36 = Str__literal(L"Build Date");
|
|
TL_IS_37 = Str__literal(L"Build Number");
|
|
TL_IS_38 = Str__literal(L"Prerelease");
|
|
TL_IS_39 = Str__literal(L"Semantic Version Number");
|
|
TL_IS_40 = Str__literal(L"Version Number");
|
|
TL_IS_41 = Str__literal(L"1");
|
|
TL_IS_42 = Str__literal(L"Version Name");
|
|
TL_IS_43 = Str__literal(L"Index Template");
|
|
TL_IS_44 = Str__literal(L"Preform Language");
|
|
TL_IS_45 = Str__literal(L"Declare Section Usage");
|
|
TL_IS_46 = Str__literal(L"Off");
|
|
TL_IS_47 = Str__literal(L"Namespaces");
|
|
TL_IS_48 = Str__literal(L"Off");
|
|
TL_IS_49 = Str__literal(L"Strict Usage Rules");
|
|
TL_IS_50 = Str__literal(L"Off");
|
|
TL_IS_51 = Str__literal(L"Web Syntax Version");
|
|
TL_IS_52 = Str__literal(L"Capitalized Title");
|
|
TL_IS_53 = Str__literal(L"miscellaneous");
|
|
TL_IS_54 = Str__literal(L"(main)");
|
|
TL_IS_55 = Str__literal(L"build.txt");
|
|
TL_IS_56 = Str__literal(L"build.txt");
|
|
TL_IS_57 = Str__literal(L"Prerelease");
|
|
TL_IS_58 = Str__literal(L"Build Number");
|
|
TL_IS_59 = Str__literal(L"Build Date");
|
|
TL_IS_60 = Str__literal(L"Semantic Version Number");
|
|
TL_IS_61 = Str__literal(L"Version Number");
|
|
TL_IS_62 = Str__literal(L"Prerelease");
|
|
TL_IS_63 = Str__literal(L"Build Number");
|
|
TL_IS_64 = Str__literal(L"Semantic Version Number");
|
|
TL_IS_65 = Str__literal(L"The compiler is not feeling well today.");
|
|
TL_IS_66 = Str__literal(L"inweb");
|
|
TL_IS_67 = Str__literal(L"Patterns");
|
|
TL_IS_68 = Str__literal(L"Materials");
|
|
TL_IS_69 = Str__literal(L"makescript.txt");
|
|
TL_IS_70 = Str__literal(L"gitignorescript.txt");
|
|
TL_IS_71 = Str__literal(L"READMEscript.txt");
|
|
TL_IS_72 = Str__literal(L"Short Title");
|
|
TL_IS_73 = Str__literal(L"Short Title");
|
|
TL_IS_74 = Str__literal(L"Title");
|
|
TL_IS_75 = Str__literal(L"docs");
|
|
TL_IS_76 = Str__literal(L"Short Title");
|
|
TL_IS_77 = Str__literal(L"Short Title");
|
|
TL_IS_78 = Str__literal(L"Title");
|
|
TL_IS_79 = Str__literal(L"GitHubPages");
|
|
TL_IS_80 = Str__literal(L"0");
|
|
TL_IS_81 = Str__literal(L"for locating programming language definitions");
|
|
TL_IS_82 = Str__literal(L"for analysing a web");
|
|
TL_IS_83 = Str__literal(L"for weaving a web");
|
|
TL_IS_84 = Str__literal(L"for tangling a web");
|
|
TL_IS_85 = Str__literal(L".inweb");
|
|
TL_IS_86 = Str__literal(L"0");
|
|
TL_IS_87 = Str__literal(L"0");
|
|
TL_IS_88 = Str__literal(L"tex");
|
|
TL_IS_89 = Str__literal(L"pdftex");
|
|
TL_IS_90 = Str__literal(L"open");
|
|
TL_IS_91 = Str__literal(L"Patterns");
|
|
TL_IS_92 = Str__literal(L"pattern.txt");
|
|
TL_IS_93 = Str__literal(L"pattern.txt");
|
|
TL_IS_94 = Str__literal(L"format");
|
|
TL_IS_95 = Str__literal(L"abbrevs");
|
|
TL_IS_96 = Str__literal(L"numbered");
|
|
TL_IS_97 = Str__literal(L"default-range");
|
|
TL_IS_98 = Str__literal(L"tex-command");
|
|
TL_IS_99 = Str__literal(L"pdftex-command");
|
|
TL_IS_100 = Str__literal(L"open-command");
|
|
TL_IS_101 = Str__literal(L"Booklet Title");
|
|
TL_IS_102 = Str__literal(L"yes");
|
|
TL_IS_103 = Str__literal(L"no");
|
|
TL_IS_104 = Str__literal(L"../");
|
|
TL_IS_105 = Str__literal(L"Inweb Version");
|
|
TL_IS_106 = Str__literal(L"Language");
|
|
TL_IS_107 = Str__literal(L"Woven");
|
|
TL_IS_108 = Str__literal(L"Tangled");
|
|
TL_IS_109 = Str__literal(L"Title");
|
|
TL_IS_110 = Str__literal(L"");
|
|
TL_IS_111 = Str__literal(L"=");
|
|
TL_IS_112 = Str__literal(L"@");
|
|
TL_IS_113 = Str__literal(L"Figures");
|
|
TL_IS_114 = Str__literal(L"Figures");
|
|
TL_IS_115 = Str__literal(L"unknown [[command]]");
|
|
TL_IS_116 = Str__literal(L"<...> definition begins outside of a paragraph");
|
|
TL_IS_117 = Str__literal(L"(very early code)");
|
|
TL_IS_118 = Str__literal(L"(early code)");
|
|
TL_IS_119 = Str__literal(L"(not code)");
|
|
TL_IS_120 = Str__literal(L"unknown bracketed annotation");
|
|
TL_IS_121 = Str__literal(L"unknown material after '='");
|
|
TL_IS_122 = Str__literal(L"don't understand @command");
|
|
TL_IS_123 = Str__literal(L"Purpose used after bar");
|
|
TL_IS_124 = Str__literal(L"Interface used after bar");
|
|
TL_IS_125 = Str__literal(L"Definitions used after bar");
|
|
TL_IS_126 = Str__literal(L"second bar in the same section");
|
|
TL_IS_127 = Str__literal(L"enumeration constants can't supply a value");
|
|
TL_IS_128 = Str__literal(L"P");
|
|
TL_IS_129 = Str__literal(L"S");
|
|
TL_IS_130 = Str__literal(L"ifdef-");
|
|
TL_IS_131 = Str__literal(L"ifndef-");
|
|
TL_IS_132 = Str__literal(L".");
|
|
TL_IS_133 = Str__literal(L"This paragraph is used only if ");
|
|
TL_IS_134 = Str__literal(L" and if ");
|
|
TL_IS_135 = Str__literal(L" and ");
|
|
TL_IS_136 = Str__literal(L" is");
|
|
TL_IS_137 = Str__literal(L" are");
|
|
TL_IS_138 = Str__literal(L" defined");
|
|
TL_IS_139 = Str__literal(L" undefined");
|
|
TL_IS_140 = Str__literal(L"enumeration constants must belong to a _FAMILY");
|
|
TL_IS_141 = Str__literal(L"this enumeration _FAMILY is unknown");
|
|
TL_IS_142 = Str__literal(L"this enumeration _FAMILY already exists");
|
|
TL_IS_143 = Str__literal(L"unrecognised interface line");
|
|
TL_IS_144 = Str__literal(L"makescript.txt");
|
|
TL_IS_145 = Str__literal(L"makescript.txt");
|
|
TL_IS_146 = Str__literal(L"gitignorescript.txt");
|
|
TL_IS_147 = Str__literal(L"gitignorescript.txt");
|
|
TL_IS_148 = Str__literal(L"cover-sheet");
|
|
TL_IS_149 = Str__literal(L"Version Number");
|
|
TL_IS_150 = Str__literal(L"Version Number");
|
|
TL_IS_151 = Str__literal(L" ");
|
|
TL_IS_152 = Str__literal(L"chaptered-index.html");
|
|
TL_IS_153 = Str__literal(L"unchaptered-index.html");
|
|
TL_IS_154 = Str__literal(L"index.html");
|
|
TL_IS_155 = Str__literal(L"index.html");
|
|
TL_IS_156 = Str__literal(L"cover-sheet");
|
|
TL_IS_157 = Str__literal(L"nav.html");
|
|
TL_IS_158 = Str__literal(L"nav.html");
|
|
TL_IS_159 = Str__literal(L"Index");
|
|
TL_IS_160 = Str__literal(L"index");
|
|
TL_IS_161 = Str__literal(L"Purpose");
|
|
TL_IS_162 = Str__literal(L"Booklet Title");
|
|
TL_IS_163 = Str__literal(L"Booklet Title");
|
|
TL_IS_164 = Str__literal(L"Booklet Title");
|
|
TL_IS_165 = Str__literal(L"Booklet Title");
|
|
TL_IS_166 = Str__literal(L"Definitions");
|
|
TL_IS_167 = Str__literal(L"");
|
|
TL_IS_168 = Str__literal(L"");
|
|
TL_IS_169 = Str__literal(L"");
|
|
TL_IS_170 = Str__literal(L"");
|
|
TL_IS_171 = Str__literal(L"define");
|
|
TL_IS_172 = Str__literal(L"enum");
|
|
TL_IS_173 = Str__literal(L"weavesection");
|
|
TL_IS_174 = Str__literal(L"weavesections");
|
|
TL_IS_175 = Str__literal(L"weavesectionss");
|
|
TL_IS_176 = Str__literal(L"weavesectionsss");
|
|
TL_IS_177 = Str__literal(L"nsweavesection");
|
|
TL_IS_178 = Str__literal(L"nsweavesections");
|
|
TL_IS_179 = Str__literal(L"tweavesection");
|
|
TL_IS_180 = Str__literal(L"tweavesections");
|
|
TL_IS_181 = Str__literal(L"tweavesectionss");
|
|
TL_IS_182 = Str__literal(L"tweavesectionsss");
|
|
TL_IS_183 = Str__literal(L"Title");
|
|
TL_IS_184 = Str__literal(L"This code is ");
|
|
TL_IS_185 = Str__literal(L"never used");
|
|
TL_IS_186 = Str__literal(L", ");
|
|
TL_IS_187 = Str__literal(L" and ");
|
|
TL_IS_188 = Str__literal(L"used in ");
|
|
TL_IS_189 = Str__literal(L" (twice)");
|
|
TL_IS_190 = Str__literal(L" (three times)");
|
|
TL_IS_191 = Str__literal(L" (four times)");
|
|
TL_IS_192 = Str__literal(L" (five times)");
|
|
TL_IS_193 = Str__literal(L".");
|
|
TL_IS_194 = Str__literal(L"The function ");
|
|
TL_IS_195 = Str__literal(L" appears nowhere else");
|
|
TL_IS_196 = Str__literal(L")");
|
|
TL_IS_197 = Str__literal(L".");
|
|
TL_IS_198 = Str__literal(L" is used in ");
|
|
TL_IS_199 = Str__literal(L"), ");
|
|
TL_IS_200 = Str__literal(L", ");
|
|
TL_IS_201 = Str__literal(L" (");
|
|
TL_IS_202 = Str__literal(L", ");
|
|
TL_IS_203 = Str__literal(L"The structure ");
|
|
TL_IS_204 = Str__literal(L" is private to this section");
|
|
TL_IS_205 = Str__literal(L" is accessed in ");
|
|
TL_IS_206 = Str__literal(L", ");
|
|
TL_IS_207 = Str__literal(L" and here");
|
|
TL_IS_208 = Str__literal(L".");
|
|
TL_IS_209 = Str__literal(L"");
|
|
TL_IS_210 = Str__literal(L"");
|
|
TL_IS_211 = Str__literal(L"");
|
|
TL_IS_212 = Str__literal(L"");
|
|
TL_IS_213 = Str__literal(L"");
|
|
TL_IS_214 = Str__literal(L"misplaced definition");
|
|
TL_IS_215 = Str__literal(L"unknown macro");
|
|
TL_IS_216 = Str__literal(L"C");
|
|
TL_IS_217 = Str__literal(L"Languages");
|
|
TL_IS_218 = Str__literal(L"InC");
|
|
TL_IS_219 = Str__literal(L"Name");
|
|
TL_IS_220 = Str__literal(L"Details");
|
|
TL_IS_221 = Str__literal(L"Extension");
|
|
TL_IS_222 = Str__literal(L"Line Comment");
|
|
TL_IS_223 = Str__literal(L"Whole Line Comment");
|
|
TL_IS_224 = Str__literal(L"Multiline Comment Open");
|
|
TL_IS_225 = Str__literal(L"Multiline Comment Close");
|
|
TL_IS_226 = Str__literal(L"String Literal");
|
|
TL_IS_227 = Str__literal(L"String Literal Escape");
|
|
TL_IS_228 = Str__literal(L"Character Literal");
|
|
TL_IS_229 = Str__literal(L"Character Literal Escape");
|
|
TL_IS_230 = Str__literal(L"Binary Literal Prefix");
|
|
TL_IS_231 = Str__literal(L"Octal Literal Prefix");
|
|
TL_IS_232 = Str__literal(L"Hexadecimal Literal Prefix");
|
|
TL_IS_233 = Str__literal(L"Negative Literal Prefix");
|
|
TL_IS_234 = Str__literal(L"Shebang");
|
|
TL_IS_235 = Str__literal(L"Line Marker");
|
|
TL_IS_236 = Str__literal(L"Before Named Paragraph Expansion");
|
|
TL_IS_237 = Str__literal(L"After Named Paragraph Expansion");
|
|
TL_IS_238 = Str__literal(L"Start Definition");
|
|
TL_IS_239 = Str__literal(L"Prolong Definition");
|
|
TL_IS_240 = Str__literal(L"End Definition");
|
|
TL_IS_241 = Str__literal(L"Start Ifdef");
|
|
TL_IS_242 = Str__literal(L"Start Ifndef");
|
|
TL_IS_243 = Str__literal(L"End Ifdef");
|
|
TL_IS_244 = Str__literal(L"End Ifndef");
|
|
TL_IS_245 = Str__literal(L"C-Like");
|
|
TL_IS_246 = Str__literal(L"Suppress Disclaimer");
|
|
TL_IS_247 = Str__literal(L"Supports Namespaces");
|
|
TL_IS_248 = Str__literal(L"}");
|
|
TL_IS_249 = Str__literal(L"unquoted");
|
|
TL_IS_250 = Str__literal(L"{");
|
|
TL_IS_251 = Str__literal(L"debug");
|
|
TL_IS_252 = Str__literal(L"!string");
|
|
TL_IS_253 = Str__literal(L"!function");
|
|
TL_IS_254 = Str__literal(L"!definition");
|
|
TL_IS_255 = Str__literal(L"!reserved");
|
|
TL_IS_256 = Str__literal(L"!element");
|
|
TL_IS_257 = Str__literal(L"!identifier");
|
|
TL_IS_258 = Str__literal(L"!character");
|
|
TL_IS_259 = Str__literal(L"!constant");
|
|
TL_IS_260 = Str__literal(L"!plain");
|
|
TL_IS_261 = Str__literal(L"!extract");
|
|
TL_IS_262 = Str__literal(L"!comment");
|
|
TL_IS_263 = Str__literal(L"true");
|
|
TL_IS_264 = Str__literal(L"false");
|
|
TL_IS_265 = Str__literal(L"Tangled output generated by inweb: do not edit");
|
|
TL_IS_266 = Str__literal(L"this programming language does not support @d");
|
|
TL_IS_267 = Str__literal(L"this programming language does not support multiline @d");
|
|
TL_IS_268 = Str__literal(L"program ended with conditional compilation open");
|
|
TL_IS_269 = Str__literal(L"conditional compilation too deeply nested");
|
|
TL_IS_270 = Str__literal(L"found #endif without #ifdef or #ifndef");
|
|
TL_IS_271 = Str__literal(L"Structures");
|
|
TL_IS_272 = Str__literal(L"Main::");
|
|
TL_IS_273 = Str__literal(L"Namespaces");
|
|
TL_IS_274 = Str__literal(L"Being internally called, this function mustn't belong to a :: namespace");
|
|
TL_IS_275 = Str__literal(L"Being externally called, this function must belong to a :: namespace");
|
|
TL_IS_276 = Str__literal(L"quartz");
|
|
TL_IS_277 = Str__literal(L"quartz");
|
|
TL_IS_278 = Str__literal(L"quartz");
|
|
TL_IS_279 = Str__literal(L"like this");
|
|
TL_IS_280 = Str__literal(L"most_recent_result");
|
|
TL_IS_281 = Str__literal(L"most_recent_result_p");
|
|
TL_IS_282 = Str__literal(L"Syntax.preform");
|
|
TL_IS_283 = Str__literal(L"Preform Language");
|
|
TL_IS_284 = Str__literal(L"Preform Language");
|
|
TL_IS_285 = Str__literal(L"");
|
|
TL_IS_286 = Str__literal(L"");
|
|
TL_IS_287 = Str__literal(L"plain");
|
|
TL_IS_288 = Str__literal(L".txt");
|
|
TL_IS_289 = Str__literal(L"TeX");
|
|
TL_IS_290 = Str__literal(L".tex");
|
|
TL_IS_291 = Str__literal(L"DVI");
|
|
TL_IS_292 = Str__literal(L".tex");
|
|
TL_IS_293 = Str__literal(L"PDF");
|
|
TL_IS_294 = Str__literal(L".tex");
|
|
TL_IS_295 = Str__literal(L"inweb-macros.tex");
|
|
TL_IS_296 = Str__literal(L"not");
|
|
TL_IS_297 = Str__literal(L"leq");
|
|
TL_IS_298 = Str__literal(L"geq");
|
|
TL_IS_299 = Str__literal(L"sim");
|
|
TL_IS_300 = Str__literal(L"hbox");
|
|
TL_IS_301 = Str__literal(L"left");
|
|
TL_IS_302 = Str__literal(L"right");
|
|
TL_IS_303 = Str__literal(L"Rightarrow");
|
|
TL_IS_304 = Str__literal(L"Leftrightarrow");
|
|
TL_IS_305 = Str__literal(L"to");
|
|
TL_IS_306 = Str__literal(L"rightarrow");
|
|
TL_IS_307 = Str__literal(L"longrightarrow");
|
|
TL_IS_308 = Str__literal(L"leftarrow");
|
|
TL_IS_309 = Str__literal(L"longleftarrow");
|
|
TL_IS_310 = Str__literal(L"lbrace");
|
|
TL_IS_311 = Str__literal(L"mid");
|
|
TL_IS_312 = Str__literal(L"rbrace");
|
|
TL_IS_313 = Str__literal(L"cdot");
|
|
TL_IS_314 = Str__literal(L"cdots");
|
|
TL_IS_315 = Str__literal(L"dots");
|
|
TL_IS_316 = Str__literal(L"times");
|
|
TL_IS_317 = Str__literal(L"quad");
|
|
TL_IS_318 = Str__literal(L"qquad");
|
|
TL_IS_319 = Str__literal(L"TeX");
|
|
TL_IS_320 = Str__literal(L"neq");
|
|
TL_IS_321 = Str__literal(L"noteq");
|
|
TL_IS_322 = Str__literal(L"ell");
|
|
TL_IS_323 = Str__literal(L"log");
|
|
TL_IS_324 = Str__literal(L"exp");
|
|
TL_IS_325 = Str__literal(L"sin");
|
|
TL_IS_326 = Str__literal(L"cos");
|
|
TL_IS_327 = Str__literal(L"tan");
|
|
TL_IS_328 = Str__literal(L"top");
|
|
TL_IS_329 = Str__literal(L"Alpha");
|
|
TL_IS_330 = Str__literal(L"Beta");
|
|
TL_IS_331 = Str__literal(L"Gamma");
|
|
TL_IS_332 = Str__literal(L"Delta");
|
|
TL_IS_333 = Str__literal(L"Epsilon");
|
|
TL_IS_334 = Str__literal(L"Zeta");
|
|
TL_IS_335 = Str__literal(L"Eta");
|
|
TL_IS_336 = Str__literal(L"Theta");
|
|
TL_IS_337 = Str__literal(L"Iota");
|
|
TL_IS_338 = Str__literal(L"Kappa");
|
|
TL_IS_339 = Str__literal(L"Lambda");
|
|
TL_IS_340 = Str__literal(L"Mu");
|
|
TL_IS_341 = Str__literal(L"Nu");
|
|
TL_IS_342 = Str__literal(L"Xi");
|
|
TL_IS_343 = Str__literal(L"Omicron");
|
|
TL_IS_344 = Str__literal(L"Pi");
|
|
TL_IS_345 = Str__literal(L"Rho");
|
|
TL_IS_346 = Str__literal(L"Varsigma");
|
|
TL_IS_347 = Str__literal(L"Sigma");
|
|
TL_IS_348 = Str__literal(L"Tau");
|
|
TL_IS_349 = Str__literal(L"Upsilon");
|
|
TL_IS_350 = Str__literal(L"Phi");
|
|
TL_IS_351 = Str__literal(L"Chi");
|
|
TL_IS_352 = Str__literal(L"Psi");
|
|
TL_IS_353 = Str__literal(L"Omega");
|
|
TL_IS_354 = Str__literal(L"alpha");
|
|
TL_IS_355 = Str__literal(L"beta");
|
|
TL_IS_356 = Str__literal(L"gamma");
|
|
TL_IS_357 = Str__literal(L"delta");
|
|
TL_IS_358 = Str__literal(L"epsilon");
|
|
TL_IS_359 = Str__literal(L"zeta");
|
|
TL_IS_360 = Str__literal(L"eta");
|
|
TL_IS_361 = Str__literal(L"theta");
|
|
TL_IS_362 = Str__literal(L"iota");
|
|
TL_IS_363 = Str__literal(L"kappa");
|
|
TL_IS_364 = Str__literal(L"lambda");
|
|
TL_IS_365 = Str__literal(L"mu");
|
|
TL_IS_366 = Str__literal(L"nu");
|
|
TL_IS_367 = Str__literal(L"xi");
|
|
TL_IS_368 = Str__literal(L"omicron");
|
|
TL_IS_369 = Str__literal(L"pi");
|
|
TL_IS_370 = Str__literal(L"rho");
|
|
TL_IS_371 = Str__literal(L"varsigma");
|
|
TL_IS_372 = Str__literal(L"sigma");
|
|
TL_IS_373 = Str__literal(L"tau");
|
|
TL_IS_374 = Str__literal(L"upsilon");
|
|
TL_IS_375 = Str__literal(L"phi");
|
|
TL_IS_376 = Str__literal(L"chi");
|
|
TL_IS_377 = Str__literal(L"psi");
|
|
TL_IS_378 = Str__literal(L"omega");
|
|
TL_IS_379 = Str__literal(L"exists");
|
|
TL_IS_380 = Str__literal(L"in");
|
|
TL_IS_381 = Str__literal(L"forall");
|
|
TL_IS_382 = Str__literal(L"cap");
|
|
TL_IS_383 = Str__literal(L"emptyset");
|
|
TL_IS_384 = Str__literal(L"subseteq");
|
|
TL_IS_385 = Str__literal(L"land");
|
|
TL_IS_386 = Str__literal(L"lor");
|
|
TL_IS_387 = Str__literal(L"lnot");
|
|
TL_IS_388 = Str__literal(L"sum");
|
|
TL_IS_389 = Str__literal(L"prod");
|
|
TL_IS_390 = Str__literal(L"exists");
|
|
TL_IS_391 = Str__literal(L"forall");
|
|
TL_IS_392 = Str__literal(L"HTML");
|
|
TL_IS_393 = Str__literal(L".html");
|
|
TL_IS_394 = Str__literal(L"ePub");
|
|
TL_IS_395 = Str__literal(L".html");
|
|
TL_IS_396 = Str__literal(L"template");
|
|
TL_IS_397 = Str__literal(L"inweb.css");
|
|
TL_IS_398 = Str__literal(L"");
|
|
TL_IS_399 = Str__literal(L"template");
|
|
TL_IS_400 = Str__literal(L"crumbs.gif");
|
|
TL_IS_401 = Str__literal(L"Title");
|
|
TL_IS_402 = Str__literal(L"Short Title");
|
|
TL_IS_403 = Str__literal(L"Short Title");
|
|
TL_IS_404 = Str__literal(L"index.html");
|
|
TL_IS_405 = Str__literal(L"★");
|
|
TL_IS_406 = Str__literal(L"../webs.html");
|
|
TL_IS_407 = Str__literal(L"enum");
|
|
TL_IS_408 = Str__literal(L"Figures");
|
|
TL_IS_409 = Str__literal(L".txt");
|
|
TL_IS_410 = Str__literal(L"");
|
|
TL_IS_411 = Str__literal(L"");
|
|
TL_IS_412 = Str__literal(L"Booklet Title");
|
|
TL_IS_413 = Str__literal(L"template");
|
|
TL_IS_414 = Str__literal(L"Title");
|
|
TL_IS_415 = Str__literal(L"inweb.css");
|
|
TL_IS_416 = Str__literal(L" ");
|
|
TL_IS_417 = Str__literal(L"all");
|
|
TL_IS_418 = Str__literal(L"platform-settings.mk");
|
|
TL_IS_419 = Str__literal(L"intest");
|
|
TL_IS_420 = Str__literal(L"all");
|
|
TL_IS_421 = Str__literal(L"gitignorescript.txt");
|
|
TL_IS_422 = Str__literal(L"version");
|
|
TL_IS_423 = Str__literal(L"purpose");
|
|
TL_IS_424 = Str__literal(L"var");
|
|
TL_IS_425 = Str__literal(L"\n");
|
|
TL_IS_426 = Str__literal(L"version");
|
|
TL_IS_427 = Str__literal(L"purpose");
|
|
TL_IS_428 = Str__literal(L"var");
|
|
TL_IS_429 = Str__literal(L"Version Number");
|
|
TL_IS_430 = Str__literal(L"Purpose");
|
|
TL_IS_431 = Str__literal(L"Build Date");
|
|
TL_IS_432 = Str__literal(L"Version Number");
|
|
TL_IS_433 = Str__literal(L"inform6");
|
|
TL_IS_434 = Str__literal(L"header.h");
|
|
TL_IS_435 = Str__literal(L"(manifest).txt");
|
|
TL_IS_436 = Str__literal(L"README.txt");
|
|
TL_IS_437 = Str__literal(L"README.md");
|
|
}
|