From cca0366c8fb08660478651c636e6942a4a76d7a3 Mon Sep 17 00:00:00 2001 From: Graham Nelson Date: Sun, 15 May 2022 15:35:53 +0100 Subject: [PATCH] More reliable text file existence checking --- README.md | 2 +- Tangled/inweb.c | 267 ++++++++++++---------- build.txt | 4 +- docs/docs-assets/Base.css | 11 +- docs/docs-assets/Breadcrumbs.css | 8 +- docs/docs-assets/Navigation.css | 22 +- docs/docs-assets/Popups.css | 6 + docs/docs-assets/Progress.css | 6 + docs/foundation-module/1-fm.html | 2 +- docs/foundation-module/1-pp.html | 123 +++++----- docs/foundation-module/1-wp.html | 91 ++++---- docs/foundation-module/2-lcl.html | 2 +- docs/foundation-module/2-mmr.html | 4 +- docs/foundation-module/2-wal.html | 4 +- docs/foundation-module/3-drc.html | 41 +++- docs/foundation-module/3-fln.html | 4 +- docs/foundation-module/3-pth.html | 4 +- docs/foundation-module/3-shl.html | 4 +- docs/foundation-module/4-sm.html | 4 +- docs/foundation-module/4-tf.html | 15 +- docs/goldbach/goldbach.pdf | Bin 251998 -> 251998 bytes foundation-module/Chapter 3/Directories.w | 26 ++- foundation-module/Chapter 4/Text Files.w | 15 +- 23 files changed, 373 insertions(+), 292 deletions(-) diff --git a/README.md b/README.md index de0bb4d..468945d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Inweb 7.1.0 -v7.1.0-beta+1B02 'Escape to Danger' (4 May 2022) +v7.1.0-beta+1B03 'Escape to Danger' (15 May 2022) ## About Inweb diff --git a/Tangled/inweb.c b/Tangled/inweb.c index ca9c154..9757d06 100644 --- a/Tangled/inweb.c +++ b/Tangled/inweb.c @@ -112,21 +112,21 @@ void Platform__where_am_i(wchar_t *p, size_t length) { #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 384 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 373 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" typedef pthread_t foundation_thread; typedef pthread_attr_t foundation_thread_attributes; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_LINUX #ifdef PLATFORM_POSIX -#line 419 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 408 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #endif /* PLATFORM_LINUX */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 433 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 422 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #endif /* PLATFORM_MACOS */ @@ -167,7 +167,7 @@ char *Platform__getenv(const char *name) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 112 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 101 "inweb/foundation-module/Chapter 1/Windows Platform.w" /* Check the first element of the command: if it has path separators in it, we assume we are running one of our commands, otherwise it is a Unix style command. */ @@ -240,7 +240,7 @@ int Platform__system(const char *cmd) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 374 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 363 "inweb/foundation-module/Chapter 1/Windows Platform.w" typedef HANDLE foundation_thread; typedef int foundation_thread_attributes; @@ -248,7 +248,7 @@ struct Win32_Thread_Start { void *(*fn)(void *); void* arg; }; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 475 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 464 "inweb/foundation-module/Chapter 1/Windows Platform.w" struct Win32_Mutex { INIT_ONCE init; CRITICAL_SECTION crit; }; #endif /* PLATFORM_WINDOWS */ @@ -322,9 +322,6 @@ struct Win32_Mutex { INIT_ONCE init; CRITICAL_SECTION crit; }; #endif /* PLATFORM_ANDROID */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#define PLATFORM_SNPRINTF snprintf -#endif /* PLATFORM_POSIX */ -#ifdef PLATFORM_POSIX #define CREATE_MUTEX(name) \ static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER; #endif /* PLATFORM_POSIX */ @@ -356,9 +353,6 @@ struct Win32_Mutex { INIT_ONCE init; CRITICAL_SECTION crit; }; #define isdigit(x) Platform__Windows_isdigit(x) #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#define PLATFORM_SNPRINTF snprintf -#endif /* PLATFORM_WINDOWS */ -#ifdef PLATFORM_WINDOWS #define CREATE_MUTEX(name) \ static struct Win32_Mutex name = { INIT_ONCE_STATIC_INIT, { 0 }}; #endif /* PLATFORM_WINDOWS */ @@ -1303,12 +1297,12 @@ typedef struct string_position { struct text_stream *S; int index; } string_position; -#line 215 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 228 "inweb/foundation-module/Chapter 4/Text Files.w" typedef struct unicode_file_buffer { char unicode_feed_buffer[32]; /* holds a single escape such as "[unicode 3106]" */ int ufb_counter; /* position in the unicode feed buffer */ } unicode_file_buffer; -#line 26 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 39 "inweb/foundation-module/Chapter 4/Text Files.w" typedef struct text_file_position { struct filename *text_file_filename; FILE *handle_when_open; @@ -2522,97 +2516,97 @@ int Platform__system(const char *cmd) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 227 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 216 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__system(const char *cmd) ; #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 244 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 233 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__mkdir(char *transcoded_pathname) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 252 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 241 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void * Platform__opendir(char *dir_name) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 257 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 246 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__readdir(void *D, char *dir_name, char *leafname) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 272 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 261 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__closedir(void *D) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 285 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 274 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" time_t Platform__never_time(void) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 289 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 278 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" time_t Platform__timestamp(char *transcoded_filename) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 295 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 284 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" off_t Platform__size(char *transcoded_filename) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 309 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 298 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__rsync(char *transcoded_source, char *transcoded_dest) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 318 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 307 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__quote_text(char *quoted, char *raw, int terminate) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 334 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 323 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__sleep(int seconds) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 350 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 339 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__notification(text_stream *text, int happy) ; #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifndef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 363 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 352 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__notification(text_stream *text, int happy) ; #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 376 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 365 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__configure_terminal(void) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 388 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 377 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__create_thread(foundation_thread *pt, const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 393 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 382 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__join_thread(foundation_thread pt, void** rv) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 397 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 386 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__init_thread(foundation_thread_attributes *pa, size_t size) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 402 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 391 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" size_t Platform__get_thread_stack_size(foundation_thread_attributes *pa) ; #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_LINUX #ifdef PLATFORM_POSIX -#line 423 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 412 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__get_core_count(void) ; #endif /* PLATFORM_LINUX */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 437 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 426 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__get_core_count(void) ; #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_ANDROID #ifdef PLATFORM_POSIX -#line 449 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 438 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__get_core_count(void) ; #endif /* PLATFORM_ANDROID */ #endif /* PLATFORM_POSIX */ @@ -2629,75 +2623,75 @@ int Platform__is_folder_separator(wchar_t c) ; void Platform__where_am_i(wchar_t *p, size_t length) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 185 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 174 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__mkdir(char *transcoded_pathname) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 193 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 182 "inweb/foundation-module/Chapter 1/Windows Platform.w" void * Platform__opendir(char *dir_name) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 198 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 187 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__readdir(void *D, char *dir_name, char *leafname) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 215 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 204 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__closedir(void *D) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 223 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 212 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__path_add(const char* base, const char* add, char* path) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 233 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 222 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__rsync(char *transcoded_source, char *transcoded_dest) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 312 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 301 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__sleep(int seconds) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 319 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 308 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__notification(text_stream *text, int happy) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 337 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 326 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__Win32_ResetConsole(void) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 346 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 335 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__configure_terminal(void) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 388 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 377 "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 403 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 392 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__join_thread(foundation_thread pt, void** rv) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 407 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 396 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__init_thread(foundation_thread_attributes* pa, size_t size) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 410 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 399 "inweb/foundation-module/Chapter 1/Windows Platform.w" size_t Platform__get_thread_stack_size(foundation_thread_attributes* pa) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 420 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 409 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__get_core_count(void) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 441 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 430 "inweb/foundation-module/Chapter 1/Windows Platform.w" time_t Platform__never_time(void) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 445 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 434 "inweb/foundation-module/Chapter 1/Windows Platform.w" time_t Platform__timestamp(char *transcoded_filename) ; #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 451 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 440 "inweb/foundation-module/Chapter 1/Windows Platform.w" off_t Platform__size(char *transcoded_filename) ; #endif /* PLATFORM_WINDOWS */ #line 64 "inweb/foundation-module/Chapter 2/Debugging Log.w" @@ -3183,14 +3177,18 @@ void Shell__verbose(void) ; #line 110 "inweb/foundation-module/Chapter 3/Shell.w" int Shell__run(OUTPUT_STREAM) ; #line 19 "inweb/foundation-module/Chapter 3/Directories.w" +scan_directory * Directories__open_from(text_stream *name) ; +#line 27 "inweb/foundation-module/Chapter 3/Directories.w" scan_directory * Directories__open(pathname *P) ; -#line 30 "inweb/foundation-module/Chapter 3/Directories.w" +#line 35 "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" +#line 47 "inweb/foundation-module/Chapter 3/Directories.w" void Directories__close(scan_directory *D) ; -#line 58 "inweb/foundation-module/Chapter 3/Directories.w" +#line 55 "inweb/foundation-module/Chapter 3/Directories.w" +int Directories__exists(pathname *P) ; +#line 74 "inweb/foundation-module/Chapter 3/Directories.w" linked_list * Directories__listing(pathname *P) ; -#line 86 "inweb/foundation-module/Chapter 3/Directories.w" +#line 102 "inweb/foundation-module/Chapter 3/Directories.w" int Directories__compare_names(const void *ent1, const void *ent2) ; #line 13 "inweb/foundation-module/Chapter 3/Time.w" void Time__begin(void) ; @@ -3412,23 +3410,23 @@ int Str__includes(text_stream *S, text_stream *T) ; int Str__includes_at(text_stream *line, int i, text_stream *pattern) ; #line 648 "inweb/foundation-module/Chapter 4/String Manipulation.w" text_stream * Str__literal(wchar_t *wide_C_string) ; -#line 15 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 20 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__exists(filename *F) ; -#line 39 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 52 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__get_line_count(text_file_position *tfp) ; -#line 47 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 60 "inweb/foundation-module/Chapter 4/Text Files.w" text_file_position TextFiles__nowhere(void) ; -#line 57 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 70 "inweb/foundation-module/Chapter 4/Text Files.w" text_file_position TextFiles__at(filename *F, int line) ; -#line 71 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 84 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__read(filename *F, int escape_oddities, char *message, int serious, void (iterator)(text_stream *, text_file_position *, void *), text_file_position *start_at, void *state) ; -#line 163 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 176 "inweb/foundation-module/Chapter 4/Text Files.w" void TextFiles__read_line(OUTPUT_STREAM, int escape_oddities, text_file_position *tfp) ; -#line 187 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 200 "inweb/foundation-module/Chapter 4/Text Files.w" void TextFiles__lose_interest(text_file_position *tfp) ; -#line 220 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 233 "inweb/foundation-module/Chapter 4/Text Files.w" unicode_file_buffer TextFiles__create_ufb(void) ; -#line 226 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 239 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, unicode_file_buffer *ufb) ; #line 23 "inweb/foundation-module/Chapter 4/Preprocessor.w" void Preprocessor__preprocess(filename *prototype, filename *F, text_stream *header, linked_list *special_macros, general_pointer specifics, wchar_t comment_char) ; @@ -5557,11 +5555,9 @@ int Platform__system(const char *cmd) { #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ -#ifdef PLATFORM_POSIX -#endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 222 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 211 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" #include #include @@ -5584,7 +5580,7 @@ int Platform__system(const char *cmd) { #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 244 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 233 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__mkdir(char *transcoded_pathname) { errno = 0; int rv = mkdir(transcoded_pathname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); @@ -5620,7 +5616,7 @@ void Platform__closedir(void *D) { #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 285 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 274 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" time_t Platform__never_time(void) { return (time_t) 0; } @@ -5639,7 +5635,7 @@ off_t Platform__size(char *transcoded_filename) { #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 309 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 298 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__rsync(char *transcoded_source, char *transcoded_dest) { char rsync_command[10*MAX_FILENAME_LENGTH]; sprintf(rsync_command, "rsync -a --delete "); @@ -5664,7 +5660,7 @@ void Platform__quote_text(char *quoted, char *raw, int terminate) { #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 334 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 323 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__sleep(int seconds) { sleep((unsigned int) seconds); } @@ -5672,7 +5668,7 @@ void Platform__sleep(int seconds) { #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 350 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 339 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__notification(text_stream *text, int happy) { char *sound_name = "Bell.aiff"; if (happy == FALSE) sound_name = "Submarine.aiff"; @@ -5687,20 +5683,20 @@ void Platform__notification(text_stream *text, int happy) { #endif /* PLATFORM_POSIX */ #ifndef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 363 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 352 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__notification(text_stream *text, int happy) { } #endif /* PLATFORM_MACOS */ #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 376 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 365 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" void Platform__configure_terminal(void) { } #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_POSIX -#line 388 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 377 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__create_thread(foundation_thread *pt, const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) { return pthread_create(pt, pa, fn, arg); @@ -5724,7 +5720,7 @@ size_t Platform__get_thread_stack_size(foundation_thread_attributes *pa) { #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_LINUX #ifdef PLATFORM_POSIX -#line 423 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 412 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__get_core_count(void) { int N = get_nprocs(); if (N < 1) return 1; @@ -5735,7 +5731,7 @@ int Platform__get_core_count(void) { #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_MACOS #ifdef PLATFORM_POSIX -#line 437 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 426 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__get_core_count(void) { int N; size_t N_size = sizeof(int); @@ -5748,7 +5744,7 @@ int Platform__get_core_count(void) { #endif /* PLATFORM_POSIX */ #ifdef PLATFORM_ANDROID #ifdef PLATFORM_POSIX -#line 449 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" +#line 438 "inweb/foundation-module/Chapter 1/POSIX Platforms.w" int Platform__get_core_count(void) { return 1; } @@ -5782,9 +5778,7 @@ void Platform__where_am_i(wchar_t *p, size_t length) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#endif /* PLATFORM_WINDOWS */ -#ifdef PLATFORM_WINDOWS -#line 185 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 174 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__mkdir(char *transcoded_pathname) { errno = 0; int rv = mkdir(transcoded_pathname); @@ -5822,7 +5816,7 @@ void Platform__closedir(void *D) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 223 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 212 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__path_add(const char* base, const char* add, char* path) { char last; @@ -5910,20 +5904,20 @@ void Platform__rsync(char *transcoded_source, char *transcoded_dest) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 312 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 301 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__sleep(int seconds) { Sleep((DWORD)(1000*seconds)); } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 319 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 308 "inweb/foundation-module/Chapter 1/Windows Platform.w" void Platform__notification(text_stream *text, int happy) { } #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 330 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 319 "inweb/foundation-module/Chapter 1/Windows Platform.w" #define WIN32CONS_RESET_MODE 1 #define WIN32CONS_RESET_OUTCP 2 @@ -5967,7 +5961,7 @@ void Platform__configure_terminal(void) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 381 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 370 "inweb/foundation-module/Chapter 1/Windows Platform.w" DWORD WINAPI Platform__Win32_Thread_Func(LPVOID param) { struct Win32_Thread_Start* start = (struct Win32_Thread_Start*)param; (start->fn)(start->arg); @@ -6003,7 +5997,7 @@ size_t Platform__get_thread_stack_size(foundation_thread_attributes* pa) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 420 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 409 "inweb/foundation-module/Chapter 1/Windows Platform.w" int Platform__get_core_count(void) { int count = 0; SYSTEM_INFO sysInfo; @@ -6019,7 +6013,7 @@ int Platform__get_core_count(void) { #endif /* PLATFORM_WINDOWS */ #ifdef PLATFORM_WINDOWS -#line 441 "inweb/foundation-module/Chapter 1/Windows Platform.w" +#line 430 "inweb/foundation-module/Chapter 1/Windows Platform.w" time_t Platform__never_time(void) { return (time_t) 0; } @@ -7568,14 +7562,14 @@ void Writers__printf(text_stream *stream, char *fmt, ...) { 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 (PLATFORM_SNPRINTF(temp, 255, format_string, ival) >= 255) strcpy(temp, "?"); + 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 (PLATFORM_SNPRINTF(temp, 255, format_string, dval) >= 255) strcpy(temp, "?"); + if (snprintf(temp, 255, format_string, dval) >= 255) strcpy(temp, "?"); for (int j = 0; temp[j]; j++) Streams__putc(temp[j], stream); break; } @@ -7673,14 +7667,14 @@ void Writers__printf(text_stream *stream, char *fmt, ...) { 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 (PLATFORM_SNPRINTF(temp, 255, format_string, ival) >= 255) strcpy(temp, "?"); + 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 (PLATFORM_SNPRINTF(temp, 255, format_string, dval) >= 255) strcpy(temp, "?"); + if (snprintf(temp, 255, format_string, dval) >= 255) strcpy(temp, "?"); for (int j = 0; temp[j]; j++) Streams__putc(temp[j], stream); break; } @@ -9962,17 +9956,22 @@ int Shell__run(OUTPUT_STREAM) { #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 *Directories__open_from(text_stream *name) { 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) + Str__copy_to_locale_string(D->directory_name_written_out, name, 4*MAX_FILENAME_LENGTH); D->directory_handle = Platform__opendir(D->directory_name_written_out); if (D->directory_handle == NULL) return NULL; return D; } +scan_directory *Directories__open(pathname *P) { + TEMPORARY_TEXT(pn) + WRITE_TO(pn, "%p", P); + scan_directory *D = Directories__open_from(pn); + DISCARD_TEXT(pn) + return D; +} + int Directories__next(scan_directory *D, text_stream *leafname) { char leafname_Cs[MAX_FILENAME_LENGTH]; int rv = TRUE; @@ -9989,7 +9988,15 @@ void Directories__close(scan_directory *D) { Platform__closedir(D->directory_handle); } -#line 58 "inweb/foundation-module/Chapter 3/Directories.w" +#line 55 "inweb/foundation-module/Chapter 3/Directories.w" +int Directories__exists(pathname *P) { + scan_directory *TRY = Directories__open(P); + if (TRY == NULL) return FALSE; + Directories__close(TRY); + return TRUE; +} + +#line 74 "inweb/foundation-module/Chapter 3/Directories.w" linked_list *Directories__listing(pathname *P) { int capacity = 4, used = 0; text_stream **listing_array = (text_stream **) @@ -10965,23 +10972,31 @@ text_stream *Str__literal(wchar_t *wide_C_string) { return answer; } -#line 15 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 20 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__exists(filename *F) { + TEMPORARY_TEXT(pn) + WRITE_TO(pn, "%f", F); + scan_directory *D = Directories__open_from(pn); + DISCARD_TEXT(pn) + if (D) { + Directories__close(D); + return FALSE; + } FILE *HANDLE = Filenames__fopen(F, "rb"); if (HANDLE == NULL) return FALSE; fclose(HANDLE); return TRUE; } -#line 35 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 48 "inweb/foundation-module/Chapter 4/Text Files.w" -#line 39 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 52 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__get_line_count(text_file_position *tfp) { if (tfp == NULL) return 0; return tfp->line_count; } -#line 47 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 60 "inweb/foundation-module/Chapter 4/Text Files.w" text_file_position TextFiles__nowhere(void) { text_file_position tfp; tfp.text_file_filename = NULL; @@ -10999,7 +11014,7 @@ text_file_position TextFiles__at(filename *F, int line) { return tfp; } -#line 71 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 84 "inweb/foundation-module/Chapter 4/Text Files.w" int TextFiles__read(filename *F, int escape_oddities, char *message, int serious, void (iterator)(text_stream *, text_file_position *, void *), text_file_position *start_at, void *state) { @@ -11007,7 +11022,7 @@ int TextFiles__read(filename *F, int escape_oddities, char *message, int serious tfp.ufb = TextFiles__create_ufb(); { -#line 84 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 97 "inweb/foundation-module/Chapter 4/Text Files.w" tfp.handle_when_open = Filenames__fopen(F, "rb"); if (tfp.handle_when_open == NULL) { if (message == NULL) return 0; @@ -11016,11 +11031,11 @@ int TextFiles__read(filename *F, int escape_oddities, char *message, int serious } } -#line 76 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 89 "inweb/foundation-module/Chapter 4/Text Files.w" ; { -#line 97 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 110 "inweb/foundation-module/Chapter 4/Text Files.w" if (start_at == NULL) { tfp.line_count = 1; tfp.line_position = 0; @@ -11037,11 +11052,11 @@ int TextFiles__read(filename *F, int escape_oddities, char *message, int serious tfp.text_file_filename = F; } -#line 77 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 90 "inweb/foundation-module/Chapter 4/Text Files.w" ; { -#line 116 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 129 "inweb/foundation-module/Chapter 4/Text Files.w" TEMPORARY_TEXT(line) int i = 0, c = ' '; while ((c != EOF) && (tfp.actively_scanning)) { @@ -11051,19 +11066,19 @@ int TextFiles__read(filename *F, int escape_oddities, char *message, int serious if ((i > 0) || (c != tfp.skip_terminator)) { { -#line 140 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 153 "inweb/foundation-module/Chapter 4/Text Files.w" iterator(line, &tfp, state); tfp.line_count++; } -#line 123 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 136 "inweb/foundation-module/Chapter 4/Text Files.w" ; if (c == '\x0a') tfp.skip_terminator = '\x0d'; if (c == '\x0d') tfp.skip_terminator = '\x0a'; } else tfp.skip_terminator = 'X'; { -#line 154 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 167 "inweb/foundation-module/Chapter 4/Text Files.w" tfp.line_position = (int) (ftell(tfp.handle_when_open)); if (tfp.line_position == -1) { if (serious) @@ -11073,7 +11088,7 @@ int TextFiles__read(filename *F, int escape_oddities, char *message, int serious } } -#line 127 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 140 "inweb/foundation-module/Chapter 4/Text Files.w" ; i = 0; } else { @@ -11083,23 +11098,23 @@ int TextFiles__read(filename *F, int escape_oddities, char *message, int serious if ((i > 0) && (tfp.actively_scanning)) { -#line 140 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 153 "inweb/foundation-module/Chapter 4/Text Files.w" iterator(line, &tfp, state); tfp.line_count++; } -#line 134 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 147 "inweb/foundation-module/Chapter 4/Text Files.w" ; DISCARD_TEXT(line) } -#line 78 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 91 "inweb/foundation-module/Chapter 4/Text Files.w" ; fclose(tfp.handle_when_open); return tfp.line_count; } -#line 163 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 176 "inweb/foundation-module/Chapter 4/Text Files.w" void TextFiles__read_line(OUTPUT_STREAM, int escape_oddities, text_file_position *tfp) { Str__clear(OUT); int i = 0, c = ' '; @@ -11120,12 +11135,12 @@ void TextFiles__read_line(OUTPUT_STREAM, int escape_oddities, text_file_position if ((i > 0) && (tfp->actively_scanning)) tfp->line_count++; } -#line 187 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 200 "inweb/foundation-module/Chapter 4/Text Files.w" void TextFiles__lose_interest(text_file_position *tfp) { tfp->actively_scanning = FALSE; } -#line 219 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 232 "inweb/foundation-module/Chapter 4/Text Files.w" unicode_file_buffer TextFiles__create_ufb(void) { unicode_file_buffer ufb; @@ -11146,7 +11161,7 @@ int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, { -#line 259 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 272 "inweb/foundation-module/Chapter 4/Text Files.w" if (c<0xC0) return '?'; /* malformed UTF-8 */ if (c<0xE0) { c = c & 0x1f; conts = 1; } else if (c<0xF0) { c = c & 0xf; conts = 2; } @@ -11163,11 +11178,11 @@ int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, } } -#line 237 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 250 "inweb/foundation-module/Chapter 4/Text Files.w" ; { -#line 288 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 301 "inweb/foundation-module/Chapter 4/Text Files.w" if ((c == 0xa1) || (c == 0xa3) || (c == 0xbf)) return c; /* pound sign, inverted ! and ? */ if (c == 0xd7) return 'x'; /* convert multiplication sign to lower case "x" */ if ((c >= 0xc0) && (c <= 0xff)) { /* accented West European letters, but... */ @@ -11178,11 +11193,11 @@ int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, } } -#line 238 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 251 "inweb/foundation-module/Chapter 4/Text Files.w" ; if (escape_oddities) { -#line 303 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 316 "inweb/foundation-module/Chapter 4/Text Files.w" if (c == 0x85) return '\x0d'; /* NEL, or "next line" */ if (c == 0xa0) return ' '; /* non-breaking space */ if ((c >= 0x2000) && (c <= 0x200a)) return ' '; /* space variants */ @@ -11192,7 +11207,7 @@ int TextFiles__utf8_fgetc(FILE *from, const char **or_from, int escape_oddities, if ((c >= 0x2028) && (c <= 0x2029)) return '\x0d'; /* fancy newlines */ } -#line 239 "inweb/foundation-module/Chapter 4/Text Files.w" +#line 252 "inweb/foundation-module/Chapter 4/Text Files.w" ; if (c == 0xFEFF) return c; /* the Unicode BOM non-character */ diff --git a/build.txt b/build.txt index b6df554..f7ebcd4 100644 --- a/build.txt +++ b/build.txt @@ -1,3 +1,3 @@ Prerelease: beta -Build Date: 4 May 2022 -Build Number: 1B02 +Build Date: 15 May 2022 +Build Number: 1B03 diff --git a/docs/docs-assets/Base.css b/docs/docs-assets/Base.css index 831d821..2e7c748 100644 --- a/docs/docs-assets/Base.css +++ b/docs/docs-assets/Base.css @@ -25,8 +25,15 @@ body { -webkit-font-smoothing: antialiased; } -a.function-link:link, a.function-link:visited { - text-decoration: black solid underline; +@media screen { + a.function-link:link, a.function-link:visited { + text-decoration: black solid underline; + } +} +@media print { + a.function-link { + text-decoration: none; + } } a.function-link:active, a.function-link:hover { font-weight: 700 diff --git a/docs/docs-assets/Breadcrumbs.css b/docs/docs-assets/Breadcrumbs.css index 9db352f..83808fb 100644 --- a/docs/docs-assets/Breadcrumbs.css +++ b/docs/docs-assets/Breadcrumbs.css @@ -6,6 +6,12 @@ div.breadcrumbs { padding-bottom: 4px; } +@media print { + div.breadcrumbs { + position: static; + } +} + .crumbs { border:1px solid #dedede; height:3em; @@ -32,4 +38,4 @@ div.breadcrumbs { .crumbs li a:hover, #crumbs li a:focus { color:#dd2c0d; -} +} \ No newline at end of file diff --git a/docs/docs-assets/Navigation.css b/docs/docs-assets/Navigation.css index 31a7677..cb13e33 100644 --- a/docs/docs-assets/Navigation.css +++ b/docs/docs-assets/Navigation.css @@ -133,11 +133,19 @@ nav[role="navigation"] h1 { margin-top: 0em } -main { - max-width: 1024px; - min-width: 320px; - margin-left: 250px; - min-height: 100%; - height: auto !important; - height: 100% +@media screen { + main { + max-width: 1024px; + min-width: 320px; + margin-left: 250px; + min-height: 100%; + height: auto !important; + height: 100% + } } + +@media print { + nav[role="navigation"] { + display: none; + } +} \ No newline at end of file diff --git a/docs/docs-assets/Popups.css b/docs/docs-assets/Popups.css index 6ba660a..58b9f62 100644 --- a/docs/docs-assets/Popups.css +++ b/docs/docs-assets/Popups.css @@ -9,6 +9,12 @@ user-select: none; } +@media print { + .popup { + display: none; + } +} + /* The actual popup */ .popup .popuptext { visibility: hidden; diff --git a/docs/docs-assets/Progress.css b/docs/docs-assets/Progress.css index cde5c9c..53f7e61 100644 --- a/docs/docs-assets/Progress.css +++ b/docs/docs-assets/Progress.css @@ -104,3 +104,9 @@ nav[role="progress"] ul li a:active { nav[role="progress"] ul li a:hover { color: #dd2c0d } + +@media print { + nav[role="progress"] { + display: none; + } +} \ No newline at end of file diff --git a/docs/foundation-module/1-fm.html b/docs/foundation-module/1-fm.html index 6471e77..5d1054c 100644 --- a/docs/foundation-module/1-fm.html +++ b/docs/foundation-module/1-fm.html @@ -142,7 +142,7 @@ never be used anywhere but here.
 void Foundation::start(int argc, char **argv) {
     CommandLine::set_locale(argc, argv);
-    Platform::configure_terminal();
+    Platform::configure_terminal();
     Memory::start();
     Register the default stream writers8.1;
     [[textliterals]];
diff --git a/docs/foundation-module/1-pp.html b/docs/foundation-module/1-pp.html
index e7068bd..e29db47 100644
--- a/docs/foundation-module/1-pp.html
+++ b/docs/foundation-module/1-pp.html
@@ -42,7 +42,7 @@
     
 

A version of our operating system interface suitable for POSIX-compliant operating systems.

-
+

§1. The C standard library leaves many questions unanswered about how to deal with the host operating system: for example, it knows very little about @@ -259,25 +259,12 @@ string.

§11. Shell commands.

-int Platform::system(const char *cmd) {
+int Platform::system(const char *cmd) {
     return system(cmd);
 }
 
-
  • This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.
  • The function Platform::system is used in §13, §16, Windows Platform (§8), Shell (§5).
-

§12. Snprintf. The C standard library function snprintf is not as standard as one might -like, and is oddly represented in some Cygwin libraries for Windows, -sometimes being differently named. -

- -

We would like to provide a wrapper function but this is troublesome with -variadic arguments, so instead here is a macro for the function name. -Happily, the Inform tools make very little use of this. -

- -
define PLATFORM_SNPRINTF snprintf
-
-
  • This paragraph is used only if PLATFORM_POSIX is defined.
-

§13. In MacOS 10.5, a new implementation of the C standard library +

  • This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.
  • The function Platform::system is used in §12, §15, Windows Platform (§7), Shell (§5).
+

§12. In MacOS 10.5, a new implementation of the C standard library crippled performance of system() by placing it behind a global mutex, so that it was impossible for two cores to be calling the function at the same time. The net effect of this is that the Inform test suite, executing in @@ -304,7 +291,7 @@ memory space. Using posix_spa extern char **environ; -int Platform::system(const char *cmd) { +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); @@ -318,11 +305,11 @@ memory space. Using posix_spa return -1; }

-
  • This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.
  • The function Platform::system is used in §11, §16, Windows Platform (§8), Shell (§5).
-

§14. Directory handling.

+
  • This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.
  • The function Platform::system is used in §11, §15, Windows Platform (§7), Shell (§5).
+

§13. Directory handling.

-int Platform::mkdir(char *transcoded_pathname) {
+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;
@@ -330,12 +317,12 @@ memory space. Using posix_spa
     return FALSE;
 }
 
-void *Platform::opendir(char *dir_name) {
+void *Platform::opendir(char *dir_name) {
     DIR *dirp = opendir(dir_name);
     return (void *) dirp;
 }
 
-int Platform::readdir(void *D, char *dir_name, char *leafname) {
+int Platform::readdir(void *D, char *dir_name, char *leafname) {
     char path_to[2*MAX_FILENAME_LENGTH+2];
     struct stat file_status;
     int rv;
@@ -350,13 +337,13 @@ memory space. Using posix_spa
     return TRUE;
 }
 
-void Platform::closedir(void *D) {
+void Platform::closedir(void *D) {
     DIR *dirp = (DIR *) D;
     closedir(dirp);
 }
 
-
  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::mkdir is used in Windows Platform (§9), Pathnames (§9).
  • The function Platform::opendir is used in Windows Platform (§9), Directories (§2).
  • The function Platform::readdir is used in Windows Platform (§9), Directories (§2).
  • The function Platform::closedir is used in Windows Platform (§9), Directories (§2).
-

§15. Timestamp and file size. There are implementations of the C standard library where time_t has +

  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::mkdir is used in Windows Platform (§8), Pathnames (§9).
  • The function Platform::opendir is used in Windows Platform (§8), Directories (§2).
  • The function Platform::readdir is used in Windows Platform (§8), Directories (§2).
  • The function Platform::closedir is used in Windows Platform (§8), Directories (§2).
+

§14. Timestamp and file size. There are implementations of the C standard library where time_t has super-weird behaviour, but on almost all POSIX systems, time 0 corresponds to midnight on 1 January 1970. All we really need is that the "never" value is one which is earlier than any possible timestamp on the files we'll @@ -364,24 +351,24 @@ be dealing with.

-time_t Platform::never_time(void) {
+time_t Platform::never_time(void) {
     return (time_t) 0;
 }
 
-time_t Platform::timestamp(char *transcoded_filename) {
+time_t Platform::timestamp(char *transcoded_filename) {
     struct stat filestat;
     if (stat(transcoded_filename, &filestat) != -1) return filestat.st_mtime;
-    return Platform::never_time();
+    return Platform::never_time();
 }
 
-off_t Platform::size(char *transcoded_filename) {
+off_t Platform::size(char *transcoded_filename) {
     struct stat filestat;
     if (stat(transcoded_filename, &filestat) != -1) return filestat.st_size;
     return (off_t) 0;
 }
 
-
  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::never_time is used in Windows Platform (§17).
  • The function Platform::timestamp is used in Windows Platform (§17), Filenames (§12).
  • The function Platform::size is used in Windows Platform (§17), Filenames (§12).
-

§16. Sync. Both names here are of directories which do exist. The function makes +

  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::never_time is used in Windows Platform (§16).
  • The function Platform::timestamp is used in Windows Platform (§16), Filenames (§12).
  • The function Platform::size is used in Windows Platform (§16), Filenames (§12).
+

§15. Sync. Both names here are of directories which do exist. The function makes the dest tree an exact copy of the source tree (and therefore deletes anything different which was originally in dest).

@@ -390,13 +377,13 @@ anything different which was originally in -void Platform::rsync(char *transcoded_source, char *transcoded_dest) { +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); + 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); + 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) { @@ -412,16 +399,16 @@ anything different which was originally in quoted[qp++] = 0; } -
  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::rsync is used in Windows Platform (§10), Pathnames (§10).
-

§17. Sleep.

+
  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::rsync is used in Windows Platform (§9), Pathnames (§10).
+

§16. Sleep.

-void Platform::sleep(int seconds) {
+void Platform::sleep(int seconds) {
     sleep((unsigned int) seconds);
 }
 
-
  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::sleep is used in Windows Platform (§11).
-

§18. Notifications. The "submarine" sound is a gloomy thunk; the "bell" is the three-tone rising +

  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::sleep is used in Windows Platform (§10).
+

§17. Notifications. The "submarine" sound is a gloomy thunk; the "bell" is the three-tone rising alert noise which iPhones make when they receive texts, but which hackers of a certain age will remember as the "I have ripped your music CD now" alert from SoundJam, the program which Apple bought and rebranded as iTunes. Apple now @@ -434,7 +421,7 @@ actually running a one-line AppleScript here.

-void Platform::notification(text_stream *text, int happy) {
+void Platform::notification(text_stream *text, int happy) {
     char *sound_name = "Bell.aiff";
     if (happy == FALSE) sound_name = "Submarine.aiff";
     TEMPORARY_TEXT(TEMP)
@@ -444,15 +431,15 @@ actually running a one-line AppleScript here.
     DISCARD_TEXT(TEMP)
 }
 
-
  • This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.
  • The function Platform::notification is used in §19, Windows Platform (§12).
-

§19.

+
  • This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.
  • The function Platform::notification is used in §18, Windows Platform (§11).
+

§18.

-void Platform::notification(text_stream *text, int happy) {
+void Platform::notification(text_stream *text, int happy) {
 }
 
-
  • This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.
  • The function Platform::notification is used in §18, Windows Platform (§12).
-

§20. Terminal setup. The idea of this function is that if anything needs to be done to enable the +

  • This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.
  • The function Platform::notification is used in §17, Windows Platform (§11).
+

§19. Terminal setup. The idea of this function is that if anything needs to be done to enable the output of ANSI-standard coloured terminal output, then this function has the chance to do it; similarly, it may need to configure itself to receive console output with the correct locale (calling Locales::get(CONSOLE_LOCALE) to @@ -463,11 +450,11 @@ find this).

-void Platform::configure_terminal(void) {
+void Platform::configure_terminal(void) {
 }
 
-
  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::configure_terminal is used in Foundation Module (§8), Windows Platform (§13).
-

§21. Concurrency. The following abstracts the pthread library, so that it can all be done +

  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::configure_terminal is used in Foundation Module (§8), Windows Platform (§12).
+

§20. Concurrency. The following abstracts the pthread library, so that it can all be done differently on Windows.

@@ -476,31 +463,31 @@ differently on Windows. typedef pthread_attr_t foundation_thread_attributes;
  • This paragraph is used only if PLATFORM_POSIX is defined.
-

§22.

+

§21.

-int Platform::create_thread(foundation_thread *pt,
+int Platform::create_thread(foundation_thread *pt,
     const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) {
     return pthread_create(pt, pa, fn, arg);
 }
 
-int Platform::join_thread(foundation_thread pt, void** rv) {
+int Platform::join_thread(foundation_thread pt, void** rv) {
     return pthread_join(pt, rv);
 }
 
-void Platform::init_thread(foundation_thread_attributes *pa, size_t size) {
+void Platform::init_thread(foundation_thread_attributes *pa, size_t size) {
     if (pthread_attr_init(pa) != 0) internal_error("thread initialisation failed");
     if (pthread_attr_setstacksize(pa, size) != 0) internal_error("thread stack sizing failed");
 }
 
-size_t Platform::get_thread_stack_size(foundation_thread_attributes *pa) {
+size_t Platform::get_thread_stack_size(foundation_thread_attributes *pa) {
     size_t mystacksize;
     pthread_attr_getstacksize(pa, &mystacksize);
     return mystacksize;
 }
 
-
  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::create_thread is used in Windows Platform (§15).
  • The function Platform::join_thread is used in Windows Platform (§15).
  • The function Platform::init_thread is used in Windows Platform (§15).
  • The function Platform::get_thread_stack_size is used in Windows Platform (§15).
-

§23. This function returns the number of logical cores in the host computer — +

  • This paragraph is used only if PLATFORM_POSIX is defined.
  • The function Platform::create_thread is used in Windows Platform (§14).
  • The function Platform::join_thread is used in Windows Platform (§14).
  • The function Platform::init_thread is used in Windows Platform (§14).
  • The function Platform::get_thread_stack_size is used in Windows Platform (§14).
+

§22. This function returns the number of logical cores in the host computer — i.e., twice the number of physical cores if there's hyperthreading. The result is used as a guess for an appropriate number of simultaneous threads to launch. @@ -515,27 +502,27 @@ MacOS does not support. #include <sys/sysinfo.h>

  • This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.
-

§24.

+

§23.

-int Platform::get_core_count(void) {
+int Platform::get_core_count(void) {
     int N = get_nprocs();
     if (N < 1) return 1;
     return N;
 }
 
-
  • This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.
  • The function Platform::get_core_count is used in §26, §27, Windows Platform (§16).
-

§25. While MacOS lacks sysinfo.h, it does have sysctl.h: +

  • This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.
  • The function Platform::get_core_count is used in §25, §26, Windows Platform (§15).
+

§24. While MacOS lacks sysinfo.h, it does have sysctl.h:

 #include <sys/sysctl.h>
 
  • This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.
-

§26.

+

§25.

-int Platform::get_core_count(void) {
+int Platform::get_core_count(void) {
     int N;
     size_t N_size = sizeof(int);
     sysctlbyname("hw.logicalcpu", &N, &N_size, NULL, 0);
@@ -543,17 +530,17 @@ MacOS does not support.
     return N;
 }
 
-
  • This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.
  • The function Platform::get_core_count is used in §24, §27, Windows Platform (§16).
-

§27. For Android it seems prudent simply to ignore multithreading: +

  • This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.
  • The function Platform::get_core_count is used in §23, §26, Windows Platform (§15).
+

§26. For Android it seems prudent simply to ignore multithreading:

-int Platform::get_core_count(void) {
+int Platform::get_core_count(void) {
     return 1;
 }
 
-
  • This paragraph is used only if PLATFORM_ANDROID and PLATFORM_POSIX are defined.
  • The function Platform::get_core_count is used in §24, §26, Windows Platform (§16).
-

§28. Mutexes.

+
  • This paragraph is used only if PLATFORM_ANDROID and PLATFORM_POSIX are defined.
  • The function Platform::get_core_count is used in §23, §25, Windows Platform (§15).
+

§27. Mutexes.

define CREATE_MUTEX(name)
     static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER;
diff --git a/docs/foundation-module/1-wp.html b/docs/foundation-module/1-wp.html
index ee1512b..2826d78 100644
--- a/docs/foundation-module/1-wp.html
+++ b/docs/foundation-module/1-wp.html
@@ -50,7 +50,7 @@ function togglePopup(material_id) {
     
 

A version of our operating system interface suitable for Microsoft Windows.

-
+

§1. This Foundation module comes with two variant versions of the Platform:: section of code. The one you're reading compiles on Windows, and the other @@ -156,20 +156,7 @@ just that installation and use of Foundation-built tools is less convenient.) }

  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§7. Snprintf. The C standard library function snprintf is not as standard as one might -like, and is oddly represented in some Cygwin libraries for Windows, -sometimes being differently named. -

- -

We would like to provide a wrapper function but this is troublesome with -variadic arguments, so instead here is a macro for the function name. -Happily, the Inform tools make very little use of this. -

- -
define PLATFORM_SNPRINTF snprintf
-
-
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§8. Shell commands.

+

§7. Shell commands.

  Check the first element of the command: if it has path separators in
@@ -191,12 +178,12 @@ Happily, the Inform tools make very little use of this.
     return 1;
 }
 
-int Platform::system(const char *cmd) {
+int Platform::system(const char *cmd) {
     char cmd_line[10*MAX_PATH];
 
      Check if the command should be executed with the Windows cmd interpreter
        or a Unix-like shell. */
-    int unix = Platform::Win32_is_unix_cmd(cmd);
+    int unix = Platform::Win32_is_unix_cmd(cmd);
     if (unix) {
          For a Unix shell command, escape any double quotes and backslashes.
         char *pcl;
@@ -243,10 +230,10 @@ Happily, the Inform tools make very little use of this.
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§9. Directory handling.

+

§8. Directory handling.

-int Platform::mkdir(char *transcoded_pathname) {
+int Platform::mkdir(char *transcoded_pathname) {
     errno = 0;
     int rv = mkdir(transcoded_pathname);
     if (rv == 0) return TRUE;
@@ -254,12 +241,12 @@ Happily, the Inform tools make very little use of this.
     return FALSE;
 }
 
-void *Platform::opendir(char *dir_name) {
+void *Platform::opendir(char *dir_name) {
     DIR *dirp = opendir(dir_name);
     return (void *) dirp;
 }
 
-int Platform::readdir(void *D, char *dir_name,
+int Platform::readdir(void *D, char *dir_name,
     char *leafname) {
     char path_to[2*MAX_FILENAME_LENGTH+2];
     struct _stat file_status;
@@ -276,13 +263,13 @@ Happily, the Inform tools make very little use of this.
     return TRUE;
 }
 
-void Platform::closedir(void *D) {
+void Platform::closedir(void *D) {
     DIR *dirp = (DIR *) D;
     closedir(dirp);
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§10. Sync.

+

§9. Sync.

 void Platform::path_add(const char* base, const char* add, char* path) {
@@ -295,20 +282,20 @@ Happily, the Inform tools make very little use of this.
   strcat(path, add);
 }
 
-void Platform::rsync(char *transcoded_source, char *transcoded_dest) {
+void Platform::rsync(char *transcoded_source, char *transcoded_dest) {
     char srcPath[MAX_PATH], destPath[MAX_PATH];
     WIN32_FIND_DATA findData = { 0 };
 
     SHCreateDirectoryExA(0, transcoded_dest, NULL);
 
-    Platform::path_add(transcoded_dest, "*", destPath);
+    Platform::path_add(transcoded_dest, "*", destPath);
     HANDLE findHandle = FindFirstFileA(destPath, &findData);
     if (findHandle != INVALID_HANDLE_VALUE) {
         do {
             if ((strcmp(findData.cFileName, ".") == 0) || (strcmp(findData.cFileName, "..") == 0))
                 continue;
 
-            Platform::path_add(transcoded_source, findData.cFileName, srcPath);
+            Platform::path_add(transcoded_source, findData.cFileName, srcPath);
 
             int remove = 1;
             {
@@ -319,7 +306,7 @@ Happily, the Inform tools make very little use of this.
                 }
             }
             if (remove) {
-                Platform::path_add(transcoded_dest, findData.cFileName, destPath);
+                Platform::path_add(transcoded_dest, findData.cFileName, destPath);
                 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                     SHFILEOPSTRUCTA oper = { 0 };
                     oper.wFunc = FO_DELETE;
@@ -334,19 +321,19 @@ Happily, the Inform tools make very little use of this.
         FindClose(findHandle);
     }
 
-    Platform::path_add(transcoded_source, "*", srcPath);
+    Platform::path_add(transcoded_source, "*", srcPath);
     findHandle = FindFirstFileA(srcPath, &findData);
     if (findHandle != INVALID_HANDLE_VALUE) {
         do {
             if ((strcmp(findData.cFileName, ".") == 0) || (strcmp(findData.cFileName, "..") == 0))
                 continue;
 
-            Platform::path_add(transcoded_source, findData.cFileName, srcPath);
-            Platform::path_add(transcoded_dest, findData.cFileName, destPath);
+            Platform::path_add(transcoded_source, findData.cFileName, srcPath);
+            Platform::path_add(transcoded_dest, findData.cFileName, destPath);
 
             if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                 CreateDirectoryA(destPath, 0);
-                Platform::rsync(srcPath, destPath);
+                Platform::rsync(srcPath, destPath);
             } else {
                 int needCopy = 1;
                 {
@@ -371,24 +358,24 @@ Happily, the Inform tools make very little use of this.
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§11. Sleep. The Windows Sleep call measures time in milliseconds, whereas +

§10. Sleep. The Windows Sleep call measures time in milliseconds, whereas POSIX sleep is for seconds.

-void Platform::sleep(int seconds) {
+void Platform::sleep(int seconds) {
     Sleep((DWORD)(1000*seconds));
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§12. Notifications.

+

§11. Notifications.

-void Platform::notification(text_stream *text, int happy) {
+void Platform::notification(text_stream *text, int happy) {
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§13. Terminal setup. The idea of this function is that if anything needs to be done to enable the +

§12. Terminal setup. The idea of this function is that if anything needs to be done to enable the output of ANSI-standard coloured terminal output, then this function has the chance to do it; similarly, it may need to configure itself to receive console output with the correct locale (calling Locales::get(CONSOLE_LOCALE) to @@ -412,7 +399,7 @@ find this). SetConsoleOutputCP(Win32_ConsoleOutCP); } -void Platform::configure_terminal(void) { +void Platform::configure_terminal(void) { HANDLE cons = GetStdHandle(STD_ERROR_HANDLE); if (cons) { if (GetConsoleMode(cons, &Win32_ConsoleMode)) { @@ -434,11 +421,11 @@ find this). if ((newCP != 0) && SetConsoleOutputCP(newCP)) Win32_ResetConsole |= WIN32CONS_RESET_OUTCP; - if (Win32_ResetConsole != 0) atexit(Platform::Win32_ResetConsole); + if (Win32_ResetConsole != 0) atexit(Platform::Win32_ResetConsole); }

  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§14. Concurrency.

+

§13. Concurrency.

 typedef HANDLE foundation_thread;
@@ -447,7 +434,7 @@ find this).
 struct Win32_Thread_Start { void *(*fn)(void *); void* arg; };
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§15.

+

§14.

 DWORD WINAPI Platform::Win32_Thread_Func(LPVOID param) {
@@ -457,7 +444,7 @@ find this).
     return 0;
 }
 
-int Platform::create_thread(foundation_thread *pt, const foundation_thread_attributes *pa,
+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;
@@ -472,26 +459,26 @@ find this).
     }
 }
 
-int Platform::join_thread(foundation_thread pt, void** rv) {
+int Platform::join_thread(foundation_thread pt, void** rv) {
     return (WaitForSingleObject(pt, INFINITE) == WAIT_OBJECT_0) ? 0 : 1;
 }
 
-void Platform::init_thread(foundation_thread_attributes* pa, size_t size) {
+void Platform::init_thread(foundation_thread_attributes* pa, size_t size) {
 }
 
-size_t Platform::get_thread_stack_size(foundation_thread_attributes* pa) {
+size_t Platform::get_thread_stack_size(foundation_thread_attributes* pa) {
     return 0;
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§16. This function returns the number of logical cores in the host computer — +

§15. This function returns the number of logical cores in the host computer — i.e., twice the number of physical cores if there's hyperthreading. The result is used as a guess for an appropriate number of simultaneous threads to launch.

-int Platform::get_core_count(void) {
+int Platform::get_core_count(void) {
     int count = 0;
     SYSTEM_INFO sysInfo;
     GetSystemInfo(&sysInfo);
@@ -505,7 +492,7 @@ to launch.
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§17. Timestamp and file size. There are implementations of the C standard library where time_t has +

§16. Timestamp and file size. There are implementations of the C standard library where time_t has super-weird behaviour, but on almost all POSIX systems, time 0 corresponds to midnight on 1 January 1970. All we really need is that the "never" value is one which is earlier than any possible timestamp on the files we'll @@ -513,24 +500,24 @@ be dealing with.

-time_t Platform::never_time(void) {
+time_t Platform::never_time(void) {
     return (time_t) 0;
 }
 
-time_t Platform::timestamp(char *transcoded_filename) {
+time_t Platform::timestamp(char *transcoded_filename) {
     struct stat filestat;
     if (stat(transcoded_filename, &filestat) != -1) return filestat.st_mtime;
-    return Platform::never_time();
+    return Platform::never_time();
 }
 
-off_t Platform::size(char *transcoded_filename) {
+off_t Platform::size(char *transcoded_filename) {
     struct stat filestat;
     if (stat(transcoded_filename, &filestat) != -1) return filestat.st_size;
     return (off_t) 0;
 }
 
  • This paragraph is used only if PLATFORM_WINDOWS is defined.
-

§18. Mutexes.

+

§17. Mutexes.

define CREATE_MUTEX(name)
     static struct Win32_Mutex name = { INIT_ONCE_STATIC_INIT, { 0 }};
diff --git a/docs/foundation-module/2-lcl.html b/docs/foundation-module/2-lcl.html
index 40901a5..33497bb 100644
--- a/docs/foundation-module/2-lcl.html
+++ b/docs/foundation-module/2-lcl.html
@@ -81,7 +81,7 @@ operating system".
 int locales_unset = TRUE;
 int locale_settings[NO_DEFINED_LOCALE_VALUES];
 
-int Locales::get(int L) {
+int Locales::get(int L) {
     if ((L < 0) || (L >= NO_DEFINED_LOCALE_VALUES)) Errors::fatal("locale out of range");
     if (locales_unset) return Locales::platform_locale();
     if (locale_settings[L] >= 0) return locale_settings[L];
diff --git a/docs/foundation-module/2-mmr.html b/docs/foundation-module/2-mmr.html
index 22a84a8..f1a7412 100644
--- a/docs/foundation-module/2-mmr.html
+++ b/docs/foundation-module/2-mmr.html
@@ -622,7 +622,7 @@ values of these functions are always non-
-void *Memory::calloc(int how_many, int size_in_bytes, int reason) {
+void *Memory::calloc(int how_many, int size_in_bytes, int reason) {
     return Memory::alloc_inner(how_many, size_in_bytes, reason);
 }
 void *Memory::malloc(int size_in_bytes, int reason) {
@@ -699,7 +699,7 @@ rarely and to allocate large blocks of memory.
 

-void Memory::I7_free(void *pointer, int R, int bytes_freed) {
+void Memory::I7_free(void *pointer, int R, int bytes_freed) {
     if ((R < 0) || (R >= NO_DEFINED_MREASON_VALUES)) internal_error("no such memory reason");
     if (pointer == NULL) internal_error("can't free NULL memory");
     LOCK_MUTEX(memory_statistics_mutex);
diff --git a/docs/foundation-module/2-wal.html b/docs/foundation-module/2-wal.html
index 9f85d73..6105d2d 100644
--- a/docs/foundation-module/2-wal.html
+++ b/docs/foundation-module/2-wal.html
@@ -312,14 +312,14 @@ file encodings, but expanding         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 (PLATFORM_SNPRINTF(temp, 255, format_string, ival) >= 255) strcpy(temp, "?");
+            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 (PLATFORM_SNPRINTF(temp, 255, format_string, dval) >= 255) strcpy(temp, "?");
+            if (snprintf(temp, 255, format_string, dval) >= 255) strcpy(temp, "?");
             for (int j = 0; temp[j]; j++) Streams::putc(temp[j], stream);
             break;
         }
diff --git a/docs/foundation-module/3-drc.html b/docs/foundation-module/3-drc.html
index 189542a..4f30b2c 100644
--- a/docs/foundation-module/3-drc.html
+++ b/docs/foundation-module/3-drc.html
@@ -67,22 +67,27 @@ transcoded the other way.
 

-scan_directory *Directories::open(pathname *P) {
+scan_directory *Directories::open_from(text_stream *name) {
     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);
+    Str::copy_to_locale_string(D->directory_name_written_out, name, 4*MAX_FILENAME_LENGTH);
+    D->directory_handle = Platform::opendir(D->directory_name_written_out);
     if (D->directory_handle == NULL) return NULL;
     return D;
 }
 
-int Directories::next(scan_directory *D, text_stream *leafname) {
+scan_directory *Directories::open(pathname *P) {
+    TEMPORARY_TEXT(pn)
+    WRITE_TO(pn, "%p", P);
+    scan_directory *D = Directories::open_from(pn);
+    DISCARD_TEXT(pn)
+    return D;
+}
+
+int Directories::next(scan_directory *D, text_stream *leafname) {
     char leafname_Cs[MAX_FILENAME_LENGTH];
     int rv = TRUE;
     while (rv) {
-        rv = Platform::readdir(D->directory_handle, D->directory_name_written_out, leafname_Cs);
+        rv = Platform::readdir(D->directory_handle, D->directory_name_written_out, leafname_Cs);
         if (leafname_Cs[0] != '.') break;
     }
     Str::clear(leafname);
@@ -90,11 +95,23 @@ transcoded the other way.
     return rv;
 }
 
-void Directories::close(scan_directory *D) {
-    Platform::closedir(D->directory_handle);
+void Directories::close(scan_directory *D) {
+    Platform::closedir(D->directory_handle);
 }
 
-

§3. It turns out to be useful to scan the contents of a directory in an order +

§3. Incredibly, this seems to be the most portable method for testing whether a +directory exists in the file system: +

+ +
+int Directories::exists(pathname *P) {
+    scan_directory *TRY = Directories::open(P);
+    if (TRY == NULL) return FALSE;
+    Directories::close(TRY);
+    return TRUE;
+}
+
+

§4. It turns out to be useful to scan the contents of a directory in an order which is predictable regardless of platform — Platform::readdir works in a different order on MacOS, Windows and Linux, even given the same directory of files to work on. So the following returns a linked list of the contents, @@ -129,7 +146,7 @@ directories holding upwards of 10,000 files or so, it'll be trivial. } Directories::close(D); } - qsort(listing_array, (size_t) used, sizeof(text_stream *), Directories::compare_names); + qsort(listing_array, (size_t) used, sizeof(text_stream *), Directories::compare_names); linked_list *L = NEW_LINKED_LIST(text_stream); for (int i=0; i<used; i++) ADD_TO_LINKED_LIST(listing_array[i], text_stream, L); Memory::I7_free(listing_array, ARRAY_SORTING_MREASON, capacity*((int) sizeof(text_stream *))); diff --git a/docs/foundation-module/3-fln.html b/docs/foundation-module/3-fln.html index 43e7f1c..2573c75 100644 --- a/docs/foundation-module/3-fln.html +++ b/docs/foundation-module/3-fln.html @@ -327,7 +327,7 @@ when printed out. 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); + time_t t = Platform::timestamp(transcoded_pathname); DISCARD_TEXT(FN) return t; } @@ -337,7 +337,7 @@ when printed out. TEMPORARY_TEXT(FN) WRITE_TO(FN, "%f", F); Str::copy_to_locale_string(transcoded_pathname, FN, 4*MAX_FILENAME_LENGTH); - int t = (int) Platform::size(transcoded_pathname); + int t = (int) Platform::size(transcoded_pathname); DISCARD_TEXT(FN) return t; } diff --git a/docs/foundation-module/3-pth.html b/docs/foundation-module/3-pth.html index f2efb87..392a423 100644 --- a/docs/foundation-module/3-pth.html +++ b/docs/foundation-module/3-pth.html @@ -317,7 +317,7 @@ on the file system with that path. 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); + P->known_to_exist = Platform::mkdir(transcoded_pathname); return P->known_to_exist; }

@@ -338,7 +338,7 @@ anything different which was originally in 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); + Platform::rsync(transcoded_source, transcoded_dest); }