More reliable text file existence checking

This commit is contained in:
Graham Nelson 2022-05-15 15:35:53 +01:00
parent 8371bb04c2
commit cca0366c8f
23 changed files with 373 additions and 292 deletions

View file

@ -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

View file

@ -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 <sys/sysinfo.h>
#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 <sys/sysctl.h>
#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 <spawn.h>
#include <sys/wait.h>
@ -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 */

View file

@ -1,3 +1,3 @@
Prerelease: beta
Build Date: 4 May 2022
Build Number: 1B02
Build Date: 15 May 2022
Build Number: 1B03

View file

@ -25,8 +25,15 @@ body {
-webkit-font-smoothing: antialiased;
}
a.function-link:link, a.function-link:visited {
@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

View file

@ -6,6 +6,12 @@ div.breadcrumbs {
padding-bottom: 4px;
}
@media print {
div.breadcrumbs {
position: static;
}
}
.crumbs {
border:1px solid #dedede;
height:3em;

View file

@ -133,11 +133,19 @@ nav[role="navigation"] h1 {
margin-top: 0em
}
main {
@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;
}
}

View file

@ -9,6 +9,12 @@
user-select: none;
}
@media print {
.popup {
display: none;
}
}
/* The actual popup */
.popup .popuptext {
visibility: hidden;

View file

@ -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;
}
}

View file

@ -142,7 +142,7 @@ never be used anywhere but here.
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Foundation::start</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">argc</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> **</span><span class="identifier-syntax">argv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-cla.html#SP8" class="function-link"><span class="function-syntax">CommandLine::set_locale</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">argc</span><span class="plain-syntax">, </span><span class="identifier-syntax">argv</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP13" class="function-link"><span class="function-syntax">Platform::configure_terminal</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::configure_terminal</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><a href="2-mmr.html#SP5" class="function-link"><span class="function-syntax">Memory::start</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="1-fm.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Register the default stream writers</span><span class="named-paragraph-number">8.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax"> [[</span><span class="identifier-syntax">textliterals</span><span class="plain-syntax">]];</span>

View file

@ -42,7 +42,7 @@
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>POSIX Platforms</b></li></ul></div>
<p class="purpose">A version of our operating system interface suitable for POSIX-compliant operating systems.</p>
<ul class="toc"><li><a href="1-pp.html#SP3">&#167;3. Mac OS X</a></li><li><a href="1-pp.html#SP4">&#167;4. Generic Unix</a></li><li><a href="1-pp.html#SP5">&#167;5. Linux</a></li><li><a href="1-pp.html#SP6">&#167;6. Android</a></li><li><a href="1-pp.html#SP7">&#167;7. Folder separator</a></li><li><a href="1-pp.html#SP8">&#167;8. Locale</a></li><li><a href="1-pp.html#SP9">&#167;9. Environment variables</a></li><li><a href="1-pp.html#SP10">&#167;10. Executable location</a></li><li><a href="1-pp.html#SP11">&#167;11. Shell commands</a></li><li><a href="1-pp.html#SP12">&#167;12. Snprintf</a></li><li><a href="1-pp.html#SP14">&#167;14. Directory handling</a></li><li><a href="1-pp.html#SP15">&#167;15. Timestamp and file size</a></li><li><a href="1-pp.html#SP16">&#167;16. Sync</a></li><li><a href="1-pp.html#SP17">&#167;17. Sleep</a></li><li><a href="1-pp.html#SP18">&#167;18. Notifications</a></li><li><a href="1-pp.html#SP20">&#167;20. Terminal setup</a></li><li><a href="1-pp.html#SP21">&#167;21. Concurrency</a></li><li><a href="1-pp.html#SP28">&#167;28. Mutexes</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="1-pp.html#SP3">&#167;3. Mac OS X</a></li><li><a href="1-pp.html#SP4">&#167;4. Generic Unix</a></li><li><a href="1-pp.html#SP5">&#167;5. Linux</a></li><li><a href="1-pp.html#SP6">&#167;6. Android</a></li><li><a href="1-pp.html#SP7">&#167;7. Folder separator</a></li><li><a href="1-pp.html#SP8">&#167;8. Locale</a></li><li><a href="1-pp.html#SP9">&#167;9. Environment variables</a></li><li><a href="1-pp.html#SP10">&#167;10. Executable location</a></li><li><a href="1-pp.html#SP11">&#167;11. Shell commands</a></li><li><a href="1-pp.html#SP13">&#167;13. Directory handling</a></li><li><a href="1-pp.html#SP14">&#167;14. Timestamp and file size</a></li><li><a href="1-pp.html#SP15">&#167;15. Sync</a></li><li><a href="1-pp.html#SP16">&#167;16. Sleep</a></li><li><a href="1-pp.html#SP17">&#167;17. Notifications</a></li><li><a href="1-pp.html#SP19">&#167;19. Terminal setup</a></li><li><a href="1-pp.html#SP20">&#167;20. Concurrency</a></li><li><a href="1-pp.html#SP27">&#167;27. Mutexes</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>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.
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Shell commands. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">system</span><span class="plain-syntax">(</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.</li><li>The function Platform::system is used in <a href="1-pp.html#SP13">&#167;13</a>, <a href="1-pp.html#SP16">&#167;16</a>, Windows Platform (<a href="1-wp.html#SP8">&#167;8</a>), Shell (<a href="3-shl.html#SP5">&#167;5</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Snprintf. </b>The C standard library function <span class="extract"><span class="extract-syntax">snprintf</span></span> is not as standard as one might
like, and is oddly represented in some Cygwin libraries for Windows,
sometimes being differently named.
</p>
<p class="commentary">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.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_SNPRINTF</span><span class="plain-syntax"> </span><span class="identifier-syntax">snprintf</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>In MacOS 10.5, a new implementation of the C standard library
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.</li><li>The function Platform::system is used in <a href="1-pp.html#SP12">&#167;12</a>, <a href="1-pp.html#SP15">&#167;15</a>, Windows Platform (<a href="1-wp.html#SP7">&#167;7</a>), Shell (<a href="3-shl.html#SP5">&#167;5</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>In MacOS 10.5, a new implementation of the C standard library
crippled performance of <span class="extract"><span class="extract-syntax">system()</span></span> 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 <span class="extract"><span class="extract-syntax">posix_spa
<span class="reserved-syntax">extern</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> **</span><span class="identifier-syntax">environ</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">argv</span><span class="plain-syntax">[] = {</span><span class="string-syntax">"sh"</span><span class="plain-syntax">, </span><span class="string-syntax">"-c"</span><span class="plain-syntax">, (</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">cmd</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">};</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pid_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">pid</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">status</span><span class="plain-syntax"> = </span><span class="identifier-syntax">posix_spawn</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">pid</span><span class="plain-syntax">, </span><span class="string-syntax">"/bin/sh"</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="identifier-syntax">argv</span><span class="plain-syntax">, </span><span class="identifier-syntax">environ</span><span class="plain-syntax">);</span>
@ -318,11 +305,11 @@ memory space. Using <span class="extract"><span class="extract-syntax">posix_spa
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -1;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::system is used in <a href="1-pp.html#SP11">&#167;11</a>, <a href="1-pp.html#SP16">&#167;16</a>, Windows Platform (<a href="1-wp.html#SP8">&#167;8</a>), Shell (<a href="3-shl.html#SP5">&#167;5</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Directory handling. </b></p>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::system is used in <a href="1-pp.html#SP11">&#167;11</a>, <a href="1-pp.html#SP15">&#167;15</a>, Windows Platform (<a href="1-wp.html#SP7">&#167;7</a>), Shell (<a href="3-shl.html#SP5">&#167;5</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Directory handling. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::mkdir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::mkdir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mkdir</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">S_IRWXU</span><span class="plain-syntax"> | </span><span class="identifier-syntax">S_IRWXG</span><span class="plain-syntax"> | </span><span class="identifier-syntax">S_IROTH</span><span class="plain-syntax"> | </span><span class="identifier-syntax">S_IXOTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
@ -330,12 +317,12 @@ memory space. Using <span class="extract"><span class="extract-syntax">posix_spa
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::opendir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::opendir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">opendir</span><span class="plain-syntax">(</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">dirp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::readdir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::readdir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">path_to</span><span class="plain-syntax">[2*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">+2];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_status</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
@ -350,13 +337,13 @@ memory space. Using <span class="extract"><span class="extract-syntax">posix_spa
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::closedir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::closedir</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">closedir</span><span class="plain-syntax">(</span><span class="identifier-syntax">dirp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::mkdir is used in Windows Platform (<a href="1-wp.html#SP9">&#167;9</a>), Pathnames (<a href="3-pth.html#SP9">&#167;9</a>).</li><li>The function Platform::opendir is used in Windows Platform (<a href="1-wp.html#SP9">&#167;9</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li><li>The function Platform::readdir is used in Windows Platform (<a href="1-wp.html#SP9">&#167;9</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li><li>The function Platform::closedir is used in Windows Platform (<a href="1-wp.html#SP9">&#167;9</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Timestamp and file size. </b>There are implementations of the C standard library where <span class="extract"><span class="extract-syntax">time_t</span></span> has
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::mkdir is used in Windows Platform (<a href="1-wp.html#SP8">&#167;8</a>), Pathnames (<a href="3-pth.html#SP9">&#167;9</a>).</li><li>The function Platform::opendir is used in Windows Platform (<a href="1-wp.html#SP8">&#167;8</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li><li>The function Platform::readdir is used in Windows Platform (<a href="1-wp.html#SP8">&#167;8</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li><li>The function Platform::closedir is used in Windows Platform (<a href="1-wp.html#SP8">&#167;8</a>), Directories (<a href="3-drc.html#SP2">&#167;2</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Timestamp and file size. </b>There are implementations of the C standard library where <span class="extract"><span class="extract-syntax">time_t</span></span> 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.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP17" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">time_t</span><span class="plain-syntax">) </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP17" class="function-link"><span class="function-syntax">Platform::timestamp</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::timestamp</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stat</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">filestat</span><span class="plain-syntax">) != -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">.</span><span class="identifier-syntax">st_mtime</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="1-wp.html#SP17" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">off_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP17" class="function-link"><span class="function-syntax">Platform::size</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">off_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::size</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stat</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">filestat</span><span class="plain-syntax">) != -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">.</span><span class="identifier-syntax">st_size</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">off_t</span><span class="plain-syntax">) </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::never_time is used in Windows Platform (<a href="1-wp.html#SP17">&#167;17</a>).</li><li>The function Platform::timestamp is used in Windows Platform (<a href="1-wp.html#SP17">&#167;17</a>), Filenames (<a href="3-fln.html#SP12">&#167;12</a>).</li><li>The function Platform::size is used in Windows Platform (<a href="1-wp.html#SP17">&#167;17</a>), Filenames (<a href="3-fln.html#SP12">&#167;12</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Sync. </b>Both names here are of directories which do exist. The function makes
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::never_time is used in Windows Platform (<a href="1-wp.html#SP16">&#167;16</a>).</li><li>The function Platform::timestamp is used in Windows Platform (<a href="1-wp.html#SP16">&#167;16</a>), Filenames (<a href="3-fln.html#SP12">&#167;12</a>).</li><li>The function Platform::size is used in Windows Platform (<a href="1-wp.html#SP16">&#167;16</a>), Filenames (<a href="3-fln.html#SP12">&#167;12</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. Sync. </b>Both names here are of directories which do exist. The function makes
the <span class="extract"><span class="extract-syntax">dest</span></span> tree an exact copy of the <span class="extract"><span class="extract-syntax">source</span></span> tree (and therefore deletes
anything different which was originally in <span class="extract"><span class="extract-syntax">dest</span></span>).
</p>
@ -390,13 +377,13 @@ anything different which was originally in <span class="extract"><span class="ex
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::rsync</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::rsync</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">[10*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">, </span><span class="string-syntax">"rsync -a --delete "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-pp.html#SP16" class="function-link"><span class="function-syntax">Platform::quote_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-pp.html#SP15" class="function-link"><span class="function-syntax">Platform::quote_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-pp.html#SP16" class="function-link"><span class="function-syntax">Platform::quote_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-pp.html#SP15" class="function-link"><span class="function-syntax">Platform::quote_text</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax"> + </span><span class="identifier-syntax">strlen</span><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">), </span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">rsync_command</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::quote_text</span><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">quoted</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">raw</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">terminate</span><span class="plain-syntax">) {</span>
@ -412,16 +399,16 @@ anything different which was originally in <span class="extract"><span class="ex
<span class="plain-syntax"> </span><span class="identifier-syntax">quoted</span><span class="plain-syntax">[</span><span class="identifier-syntax">qp</span><span class="plain-syntax">++] = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::rsync is used in Windows Platform (<a href="1-wp.html#SP10">&#167;10</a>), Pathnames (<a href="3-pth.html#SP10">&#167;10</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Sleep. </b></p>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::rsync is used in Windows Platform (<a href="1-wp.html#SP9">&#167;9</a>), Pathnames (<a href="3-pth.html#SP10">&#167;10</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Sleep. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP11" class="function-link"><span class="function-syntax">Platform::sleep</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seconds</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::sleep</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seconds</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sleep</span><span class="plain-syntax">((</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">seconds</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::sleep is used in Windows Platform (<a href="1-wp.html#SP11">&#167;11</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. Notifications. </b>The "submarine" sound is a gloomy thunk; the "bell" is the three-tone rising
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::sleep is used in Windows Platform (<a href="1-wp.html#SP10">&#167;10</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Notifications. </b>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.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::notification</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP11" class="function-link"><span class="function-syntax">Platform::notification</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">sound_name</span><span class="plain-syntax"> = </span><span class="string-syntax">"Bell.aiff"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">happy</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">sound_name</span><span class="plain-syntax"> = </span><span class="string-syntax">"Submarine.aiff"</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
@ -444,15 +431,15 @@ actually running a one-line AppleScript here.
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">TEMP</span><span class="plain-syntax">)</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::notification is used in <a href="1-pp.html#SP19">&#167;19</a>, Windows Platform (<a href="1-wp.html#SP12">&#167;12</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. </b></p>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::notification is used in <a href="1-pp.html#SP18">&#167;18</a>, Windows Platform (<a href="1-wp.html#SP11">&#167;11</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::notification</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP11" class="function-link"><span class="function-syntax">Platform::notification</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.</li><li>The function Platform::notification is used in <a href="1-pp.html#SP18">&#167;18</a>, Windows Platform (<a href="1-wp.html#SP12">&#167;12</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Terminal setup. </b>The idea of this function is that if anything needs to be done to enable the
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined and if PLATFORM_MACOS is undefined.</li><li>The function Platform::notification is used in <a href="1-pp.html#SP17">&#167;17</a>, Windows Platform (<a href="1-wp.html#SP11">&#167;11</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP19" class="paragraph-anchor"></a><b>&#167;19. Terminal setup. </b>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 <span class="extract"><span class="extract-syntax">Locales::get(CONSOLE_LOCALE)</span></span> to
@ -463,11 +450,11 @@ find this).
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP13" class="function-link"><span class="function-syntax">Platform::configure_terminal</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::configure_terminal</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::configure_terminal is used in Foundation Module (<a href="1-fm.html#SP8">&#167;8</a>), Windows Platform (<a href="1-wp.html#SP13">&#167;13</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. Concurrency. </b>The following abstracts the pthread library, so that it can all be done
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::configure_terminal is used in Foundation Module (<a href="1-fm.html#SP8">&#167;8</a>), Windows Platform (<a href="1-wp.html#SP12">&#167;12</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP20" class="paragraph-anchor"></a><b>&#167;20. Concurrency. </b>The following abstracts the pthread library, so that it can all be done
differently on Windows.
</p>
@ -476,31 +463,31 @@ differently on Windows.
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_attr_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b></p>
<p class="commentary firstcommentary"><a id="SP21" class="paragraph-anchor"></a><b>&#167;21. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP15" class="function-link"><span class="function-syntax">Platform::create_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">,</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP14" class="function-link"><span class="function-syntax">Platform::create_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *(*</span><span class="identifier-syntax">fn</span><span class="plain-syntax">)(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *), </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">arg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_create</span><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">fn</span><span class="plain-syntax">, </span><span class="identifier-syntax">arg</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP15" class="function-link"><span class="function-syntax">Platform::join_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">** </span><span class="identifier-syntax">rv</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP14" class="function-link"><span class="function-syntax">Platform::join_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">** </span><span class="identifier-syntax">rv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_join</span><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">rv</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP15" class="function-link"><span class="function-syntax">Platform::init_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><a href="1-wp.html#SP14" class="function-link"><span class="function-syntax">Platform::init_thread</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pthread_attr_init</span><span class="plain-syntax">(</span><span class="identifier-syntax">pa</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"thread initialisation failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pthread_attr_setstacksize</span><span class="plain-syntax">(</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">size</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"thread stack sizing failed"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP15" class="function-link"><span class="function-syntax">Platform::get_thread_stack_size</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><a href="1-wp.html#SP14" class="function-link"><span class="function-syntax">Platform::get_thread_stack_size</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">mystacksize</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pthread_attr_getstacksize</span><span class="plain-syntax">(</span><span class="identifier-syntax">pa</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">mystacksize</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">mystacksize</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::create_thread is used in Windows Platform (<a href="1-wp.html#SP15">&#167;15</a>).</li><li>The function Platform::join_thread is used in Windows Platform (<a href="1-wp.html#SP15">&#167;15</a>).</li><li>The function Platform::init_thread is used in Windows Platform (<a href="1-wp.html#SP15">&#167;15</a>).</li><li>The function Platform::get_thread_stack_size is used in Windows Platform (<a href="1-wp.html#SP15">&#167;15</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b>This function returns the number of logical cores in the host computer &mdash;
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_POSIX is defined.</li><li>The function Platform::create_thread is used in Windows Platform (<a href="1-wp.html#SP14">&#167;14</a>).</li><li>The function Platform::join_thread is used in Windows Platform (<a href="1-wp.html#SP14">&#167;14</a>).</li><li>The function Platform::init_thread is used in Windows Platform (<a href="1-wp.html#SP14">&#167;14</a>).</li><li>The function Platform::get_thread_stack_size is used in Windows Platform (<a href="1-wp.html#SP14">&#167;14</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP22" class="paragraph-anchor"></a><b>&#167;22. </b>This function returns the number of logical cores in the host computer &mdash;
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.
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;sys/sysinfo.h&gt;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b></p>
<p class="commentary firstcommentary"><a id="SP23" class="paragraph-anchor"></a><b>&#167;23. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::get_core_count</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP15" class="function-link"><span class="function-syntax">Platform::get_core_count</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">get_nprocs</span><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.</li><li>The function Platform::get_core_count is used in <a href="1-pp.html#SP26">&#167;26</a>, <a href="1-pp.html#SP27">&#167;27</a>, Windows Platform (<a href="1-wp.html#SP16">&#167;16</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b>While MacOS lacks <span class="extract"><span class="extract-syntax">sysinfo.h</span></span>, it does have <span class="extract"><span class="extract-syntax">sysctl.h</span></span>:
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_LINUX and PLATFORM_POSIX are defined.</li><li>The function Platform::get_core_count is used in <a href="1-pp.html#SP25">&#167;25</a>, <a href="1-pp.html#SP26">&#167;26</a>, Windows Platform (<a href="1-wp.html#SP15">&#167;15</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP24" class="paragraph-anchor"></a><b>&#167;24. </b>While MacOS lacks <span class="extract"><span class="extract-syntax">sysinfo.h</span></span>, it does have <span class="extract"><span class="extract-syntax">sysctl.h</span></span>:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">#</span><span class="identifier-syntax">include</span><span class="plain-syntax"> </span><span class="function-syntax">&lt;sys/sysctl.h&gt;</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. </b></p>
<p class="commentary firstcommentary"><a id="SP25" class="paragraph-anchor"></a><b>&#167;25. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::get_core_count</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP15" class="function-link"><span class="function-syntax">Platform::get_core_count</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">N_size</span><span class="plain-syntax"> = </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">sysctlbyname</span><span class="plain-syntax">(</span><span class="string-syntax">"hw.logicalcpu"</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">N</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">N_size</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
@ -543,17 +530,17 @@ MacOS does not support.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::get_core_count is used in <a href="1-pp.html#SP24">&#167;24</a>, <a href="1-pp.html#SP27">&#167;27</a>, Windows Platform (<a href="1-wp.html#SP16">&#167;16</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. </b>For Android it seems prudent simply to ignore multithreading:
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_MACOS and PLATFORM_POSIX are defined.</li><li>The function Platform::get_core_count is used in <a href="1-pp.html#SP23">&#167;23</a>, <a href="1-pp.html#SP26">&#167;26</a>, Windows Platform (<a href="1-wp.html#SP15">&#167;15</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP26" class="paragraph-anchor"></a><b>&#167;26. </b>For Android it seems prudent simply to ignore multithreading:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::get_core_count</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><a href="1-wp.html#SP15" class="function-link"><span class="function-syntax">Platform::get_core_count</span></a><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_ANDROID and PLATFORM_POSIX are defined.</li><li>The function Platform::get_core_count is used in <a href="1-pp.html#SP24">&#167;24</a>, <a href="1-pp.html#SP26">&#167;26</a>, Windows Platform (<a href="1-wp.html#SP16">&#167;16</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP28" class="paragraph-anchor"></a><b>&#167;28. Mutexes. </b></p>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_ANDROID and PLATFORM_POSIX are defined.</li><li>The function Platform::get_core_count is used in <a href="1-pp.html#SP23">&#167;23</a>, <a href="1-pp.html#SP25">&#167;25</a>, Windows Platform (<a href="1-wp.html#SP15">&#167;15</a>).</li></ul>
<p class="commentary firstcommentary"><a id="SP27" class="paragraph-anchor"></a><b>&#167;27. Mutexes. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">CREATE_MUTEX</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">static</span><span class="plain-syntax"> </span><span class="identifier-syntax">pthread_mutex_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PTHREAD_MUTEX_INITIALIZER</span><span class="plain-syntax">;</span>

View file

@ -50,7 +50,7 @@ function togglePopup(material_id) {
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#1">Chapter 1: Setting Up</a></li><li><b>Windows Platform</b></li></ul></div>
<p class="purpose">A version of our operating system interface suitable for Microsoft Windows.</p>
<ul class="toc"><li><a href="1-wp.html#SP2">&#167;2. Microsoft Windows</a></li><li><a href="1-wp.html#SP4">&#167;4. Folder separator</a></li><li><a href="1-wp.html#SP5">&#167;5. Environment variables</a></li><li><a href="1-wp.html#SP6">&#167;6. Executable location</a></li><li><a href="1-wp.html#SP7">&#167;7. Snprintf</a></li><li><a href="1-wp.html#SP8">&#167;8. Shell commands</a></li><li><a href="1-wp.html#SP9">&#167;9. Directory handling</a></li><li><a href="1-wp.html#SP10">&#167;10. Sync</a></li><li><a href="1-wp.html#SP11">&#167;11. Sleep</a></li><li><a href="1-wp.html#SP12">&#167;12. Notifications</a></li><li><a href="1-wp.html#SP13">&#167;13. Terminal setup</a></li><li><a href="1-wp.html#SP14">&#167;14. Concurrency</a></li><li><a href="1-wp.html#SP17">&#167;17. Timestamp and file size</a></li><li><a href="1-wp.html#SP18">&#167;18. Mutexes</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="1-wp.html#SP2">&#167;2. Microsoft Windows</a></li><li><a href="1-wp.html#SP4">&#167;4. Folder separator</a></li><li><a href="1-wp.html#SP5">&#167;5. Environment variables</a></li><li><a href="1-wp.html#SP6">&#167;6. Executable location</a></li><li><a href="1-wp.html#SP7">&#167;7. Shell commands</a></li><li><a href="1-wp.html#SP8">&#167;8. Directory handling</a></li><li><a href="1-wp.html#SP9">&#167;9. Sync</a></li><li><a href="1-wp.html#SP10">&#167;10. Sleep</a></li><li><a href="1-wp.html#SP11">&#167;11. Notifications</a></li><li><a href="1-wp.html#SP12">&#167;12. Terminal setup</a></li><li><a href="1-wp.html#SP13">&#167;13. Concurrency</a></li><li><a href="1-wp.html#SP16">&#167;16. Timestamp and file size</a></li><li><a href="1-wp.html#SP17">&#167;17. Mutexes</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>This Foundation module comes with two variant versions of the <span class="extract"><span class="extract-syntax">Platform::</span></span>
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.)
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Snprintf. </b>The C standard library function <span class="extract"><span class="extract-syntax">snprintf</span></span> is not as standard as one might
like, and is oddly represented in some Cygwin libraries for Windows,
sometimes being differently named.
</p>
<p class="commentary">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.
</p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">PLATFORM_SNPRINTF</span><span class="plain-syntax"> </span><span class="identifier-syntax">snprintf</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Shell commands. </b></p>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Shell commands. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="comment-syntax"> Check the first element of the command: if it has path separators in</span>
@ -191,12 +178,12 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::system</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Platform::system</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP11">&#167;11</a>, <a href="1-pp.html#SP13">&#167;13</a>, <a href="1-pp.html#SP16">&#167;16</a><br/>Shell - <a href="3-shl.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::system</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Platform::system</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP11">&#167;11</a>, <a href="1-pp.html#SP12">&#167;12</a>, <a href="1-pp.html#SP15">&#167;15</a><br/>Shell - <a href="3-shl.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">cmd_line</span><span class="plain-syntax">[10*</span><span class="identifier-syntax">MAX_PATH</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Check if the command should be executed with the Windows cmd interpreter</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">or</span><span class="plain-syntax"> </span><span class="identifier-syntax">a</span><span class="plain-syntax"> </span><span class="identifier-syntax">Unix</span><span class="plain-syntax">-</span><span class="identifier-syntax">like</span><span class="plain-syntax"> </span><span class="identifier-syntax">shell</span><span class="plain-syntax">. */</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unix</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::Win32_is_unix_cmd</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">unix</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::Win32_is_unix_cmd</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">cmd</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">unix</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> For a Unix shell command, escape any double quotes and backslashes.</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pcl</span><span class="plain-syntax">;</span>
@ -243,10 +230,10 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Directory handling. </b></p>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Directory handling. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::mkdir</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Platform::mkdir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP14">&#167;14</a><br/>Pathnames - <a href="3-pth.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::mkdir</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Platform::mkdir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP13">&#167;13</a><br/>Pathnames - <a href="3-pth.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">errno</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mkdir</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
@ -254,12 +241,12 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Platform::opendir</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Platform::opendir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP14">&#167;14</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Platform::opendir</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Platform::opendir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP13">&#167;13</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">opendir</span><span class="plain-syntax">(</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">dirp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::readdir</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Platform::readdir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP14">&#167;14</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">,</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::readdir</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Platform::readdir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP13">&#167;13</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dir_name</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">path_to</span><span class="plain-syntax">[2*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">+2];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">_stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">file_status</span><span class="plain-syntax">;</span>
@ -276,13 +263,13 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::closedir</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Platform::closedir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP14">&#167;14</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::closedir</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Platform::closedir</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP13">&#167;13</a><br/>Directories - <a href="3-drc.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dirp</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">DIR</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">closedir</span><span class="plain-syntax">(</span><span class="identifier-syntax">dirp</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Sync. </b></p>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Sync. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::path_add</span><span class="plain-syntax">(</span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">* </span><span class="identifier-syntax">base</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax">* </span><span class="identifier-syntax">add</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax">* </span><span class="identifier-syntax">path</span><span class="plain-syntax">) {</span>
@ -295,20 +282,20 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax"> </span><span class="identifier-syntax">strcat</span><span class="plain-syntax">(</span><span class="identifier-syntax">path</span><span class="plain-syntax">, </span><span class="identifier-syntax">add</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::rsync</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Platform::rsync</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP16">&#167;16</a><br/>Pathnames - <a href="3-pth.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::rsync</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Platform::rsync</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP15">&#167;15</a><br/>Pathnames - <a href="3-pth.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">[</span><span class="identifier-syntax">MAX_PATH</span><span class="plain-syntax">], </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">[</span><span class="identifier-syntax">MAX_PATH</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WIN32_FIND_DATA</span><span class="plain-syntax"> </span><span class="identifier-syntax">findData</span><span class="plain-syntax"> = { </span><span class="constant-syntax">0</span><span class="plain-syntax"> };</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SHCreateDirectoryExA</span><span class="plain-syntax">(0, </span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="string-syntax">"*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="string-syntax">"*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HANDLE</span><span class="plain-syntax"> </span><span class="identifier-syntax">findHandle</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FindFirstFileA</span><span class="plain-syntax">(</span><span class="identifier-syntax">destPath</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">findData</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">findHandle</span><span class="plain-syntax"> != </span><span class="identifier-syntax">INVALID_HANDLE_VALUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">do</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">strcmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="string-syntax">"."</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">strcmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="string-syntax">".."</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">remove</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> {</span>
@ -319,7 +306,7 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">remove</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">dwFileAttributes</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">FILE_ATTRIBUTE_DIRECTORY</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SHFILEOPSTRUCTA</span><span class="plain-syntax"> </span><span class="identifier-syntax">oper</span><span class="plain-syntax"> = { </span><span class="constant-syntax">0</span><span class="plain-syntax"> };</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">oper</span><span class="plain-syntax">.</span><span class="identifier-syntax">wFunc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FO_DELETE</span><span class="plain-syntax">;</span>
@ -334,19 +321,19 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax"> </span><span class="identifier-syntax">FindClose</span><span class="plain-syntax">(</span><span class="identifier-syntax">findHandle</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="string-syntax">"*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="string-syntax">"*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">findHandle</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FindFirstFileA</span><span class="plain-syntax">(</span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">findData</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">findHandle</span><span class="plain-syntax"> != </span><span class="identifier-syntax">INVALID_HANDLE_VALUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">do</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">strcmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="string-syntax">"."</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">strcmp</span><span class="plain-syntax">(</span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="string-syntax">".."</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::path_add</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">cFileName</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">findData</span><span class="plain-syntax">.</span><span class="identifier-syntax">dwFileAttributes</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">FILE_ATTRIBUTE_DIRECTORY</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">CreateDirectoryA</span><span class="plain-syntax">(</span><span class="identifier-syntax">destPath</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::rsync</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::rsync</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">srcPath</span><span class="plain-syntax">, </span><span class="identifier-syntax">destPath</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">needCopy</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> {</span>
@ -371,24 +358,24 @@ Happily, the Inform tools make very little use of this.
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Sleep. </b>The Windows <span class="extract"><span class="extract-syntax">Sleep</span></span> call measures time in milliseconds, whereas
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Sleep. </b>The Windows <span class="extract"><span class="extract-syntax">Sleep</span></span> call measures time in milliseconds, whereas
POSIX <span class="extract"><span class="extract-syntax">sleep</span></span> is for seconds.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::sleep</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Platform::sleep</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP17">&#167;17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seconds</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::sleep</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Platform::sleep</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP16">&#167;16</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seconds</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Sleep</span><span class="plain-syntax">((</span><span class="identifier-syntax">DWORD</span><span class="plain-syntax">)(1000*</span><span class="identifier-syntax">seconds</span><span class="plain-syntax">));</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Notifications. </b></p>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. Notifications. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::notification</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Platform::notification</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP18">&#167;18</a>, <a href="1-pp.html#SP19">&#167;19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::notification</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Platform::notification</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP17">&#167;17</a>, <a href="1-pp.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">happy</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Terminal setup. </b>The idea of this function is that if anything needs to be done to enable the
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Terminal setup. </b>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 <span class="extract"><span class="extract-syntax">Locales::get(CONSOLE_LOCALE)</span></span> to
@ -412,7 +399,7 @@ find this).
<span class="plain-syntax"> </span><span class="identifier-syntax">SetConsoleOutputCP</span><span class="plain-syntax">(</span><span class="identifier-syntax">Win32_ConsoleOutCP</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::configure_terminal</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Platform::configure_terminal</span></span>:<br/>Foundation Module - <a href="1-fm.html#SP8">&#167;8</a><br/>POSIX Platforms - <a href="1-pp.html#SP20">&#167;20</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::configure_terminal</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Platform::configure_terminal</span></span>:<br/>Foundation Module - <a href="1-fm.html#SP8">&#167;8</a><br/>POSIX Platforms - <a href="1-pp.html#SP19">&#167;19</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">HANDLE</span><span class="plain-syntax"> </span><span class="identifier-syntax">cons</span><span class="plain-syntax"> = </span><span class="identifier-syntax">GetStdHandle</span><span class="plain-syntax">(</span><span class="identifier-syntax">STD_ERROR_HANDLE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cons</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">GetConsoleMode</span><span class="plain-syntax">(</span><span class="identifier-syntax">cons</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">Win32_ConsoleMode</span><span class="plain-syntax">)) {</span>
@ -434,11 +421,11 @@ find this).
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">newCP</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; </span><span class="identifier-syntax">SetConsoleOutputCP</span><span class="plain-syntax">(</span><span class="identifier-syntax">newCP</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">Win32_ResetConsole</span><span class="plain-syntax"> |= </span><span class="identifier-syntax">WIN32CONS_RESET_OUTCP</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Win32_ResetConsole</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">atexit</span><span class="plain-syntax">(</span><a href="1-wp.html#SP13" class="function-link"><span class="function-syntax">Platform::Win32_ResetConsole</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Win32_ResetConsole</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">atexit</span><span class="plain-syntax">(</span><a href="1-wp.html#SP12" class="function-link"><span class="function-syntax">Platform::Win32_ResetConsole</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Concurrency. </b></p>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Concurrency. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="identifier-syntax">HANDLE</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax">;</span>
@ -447,7 +434,7 @@ find this).
<span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">Win32_Thread_Start</span><span class="plain-syntax"> { </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *(*</span><span class="identifier-syntax">fn</span><span class="plain-syntax">)(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *); </span><span class="reserved-syntax">void</span><span class="plain-syntax">* </span><span class="identifier-syntax">arg</span><span class="plain-syntax">; };</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b></p>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">DWORD</span><span class="plain-syntax"> </span><span class="identifier-syntax">WINAPI</span><span class="plain-syntax"> </span><span class="identifier-syntax">Platform::Win32_Thread_Func</span><span class="plain-syntax">(</span><span class="identifier-syntax">LPVOID</span><span class="plain-syntax"> </span><span class="identifier-syntax">param</span><span class="plain-syntax">) {</span>
@ -457,7 +444,7 @@ find this).
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::create_thread</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Platform::create_thread</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP22">&#167;22</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">,</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::create_thread</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Platform::create_thread</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">const</span><span class="plain-syntax"> </span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pa</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *(*</span><span class="identifier-syntax">fn</span><span class="plain-syntax">)(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *), </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">arg</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">Win32_Thread_Start</span><span class="plain-syntax">* </span><span class="identifier-syntax">start</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">Win32_Thread_Start</span><span class="plain-syntax">*) </span><span class="identifier-syntax">malloc</span><span class="plain-syntax">(</span><span class="reserved-syntax">sizeof</span><span class="plain-syntax"> (</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">Win32_Thread_Start</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">start</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fn</span><span class="plain-syntax">;</span>
@ -472,26 +459,26 @@ find this).
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::join_thread</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Platform::join_thread</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP22">&#167;22</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">** </span><span class="identifier-syntax">rv</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::join_thread</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Platform::join_thread</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread</span><span class="plain-syntax"> </span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax">** </span><span class="identifier-syntax">rv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">WaitForSingleObject</span><span class="plain-syntax">(</span><span class="identifier-syntax">pt</span><span class="plain-syntax">, </span><span class="identifier-syntax">INFINITE</span><span class="plain-syntax">) == </span><span class="identifier-syntax">WAIT_OBJECT_0</span><span class="plain-syntax">) ? </span><span class="constant-syntax">0</span><span class="plain-syntax"> : </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::init_thread</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Platform::init_thread</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP22">&#167;22</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax">* </span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::init_thread</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Platform::init_thread</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax">* </span><span class="identifier-syntax">pa</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">size</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::get_thread_stack_size</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Platform::get_thread_stack_size</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP22">&#167;22</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax">* </span><span class="identifier-syntax">pa</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">size_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::get_thread_stack_size</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Platform::get_thread_stack_size</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">foundation_thread_attributes</span><span class="plain-syntax">* </span><span class="identifier-syntax">pa</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. </b>This function returns the number of logical cores in the host computer &mdash;
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>&#167;15. </b>This function returns the number of logical cores in the host computer &mdash;
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.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::get_core_count</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Platform::get_core_count</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP24">&#167;24</a>, <a href="1-pp.html#SP26">&#167;26</a>, <a href="1-pp.html#SP27">&#167;27</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::get_core_count</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Platform::get_core_count</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP23">&#167;23</a>, <a href="1-pp.html#SP25">&#167;25</a>, <a href="1-pp.html#SP26">&#167;26</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">SYSTEM_INFO</span><span class="plain-syntax"> </span><span class="identifier-syntax">sysInfo</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">GetSystemInfo</span><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">sysInfo</span><span class="plain-syntax">);</span>
@ -505,7 +492,7 @@ to launch.
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Timestamp and file size. </b>There are implementations of the C standard library where <span class="extract"><span class="extract-syntax">time_t</span></span> has
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>&#167;16. Timestamp and file size. </b>There are implementations of the C standard library where <span class="extract"><span class="extract-syntax">time_t</span></span> 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.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::never_time</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Platform::never_time</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP15">&#167;15</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::never_time</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Platform::never_time</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">time_t</span><span class="plain-syntax">) </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::timestamp</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Platform::timestamp</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP15">&#167;15</a><br/>Filenames - <a href="3-fln.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::timestamp</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Platform::timestamp</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP14">&#167;14</a><br/>Filenames - <a href="3-fln.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stat</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">filestat</span><span class="plain-syntax">) != -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">.</span><span class="identifier-syntax">st_mtime</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="1-wp.html#SP17" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::never_time</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">}</span>
<span class="identifier-syntax">off_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::size</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Platform::size</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP15">&#167;15</a><br/>Filenames - <a href="3-fln.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="identifier-syntax">off_t</span><span class="plain-syntax"> </span><span class="function-syntax">Platform::size</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Platform::size</span></span>:<br/>POSIX Platforms - <a href="1-pp.html#SP14">&#167;14</a><br/>Filenames - <a href="3-fln.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">stat</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">stat</span><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_filename</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">filestat</span><span class="plain-syntax">) != -1) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">filestat</span><span class="plain-syntax">.</span><span class="identifier-syntax">st_size</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> (</span><span class="identifier-syntax">off_t</span><span class="plain-syntax">) </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>This paragraph is used only if PLATFORM_WINDOWS is defined.</li></ul>
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>&#167;18. Mutexes. </b></p>
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>&#167;17. Mutexes. </b></p>
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">CREATE_MUTEX</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">static</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">Win32_Mutex</span><span class="plain-syntax"> </span><span class="identifier-syntax">name</span><span class="plain-syntax"> = { </span><span class="identifier-syntax">INIT_ONCE_STATIC_INIT</span><span class="plain-syntax">, { </span><span class="constant-syntax">0</span><span class="plain-syntax"> }};</span>

View file

@ -81,7 +81,7 @@ operating system".
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">locales_unset</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">locale_settings</span><span class="plain-syntax">[</span><span class="identifier-syntax">NO_DEFINED_LOCALE_VALUES</span><span class="plain-syntax">];</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Locales::get</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Locales::get</span></span>:<br/><a href="2-lcl.html#SP4">&#167;4</a><br/>Windows Platform - <a href="1-wp.html#SP13">&#167;13</a><br/>Streams - <a href="2-str.html#SP22">&#167;22</a>, <a href="2-str.html#SP23">&#167;23</a>, <a href="2-str.html#SP32">&#167;32</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Locales::get</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Locales::get</span></span>:<br/><a href="2-lcl.html#SP4">&#167;4</a><br/>Windows Platform - <a href="1-wp.html#SP12">&#167;12</a><br/>Streams - <a href="2-str.html#SP22">&#167;22</a>, <a href="2-str.html#SP23">&#167;23</a>, <a href="2-str.html#SP32">&#167;32</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">L</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">NO_DEFINED_LOCALE_VALUES</span><span class="plain-syntax">)) </span><a href="3-em.html#SP2" class="function-link"><span class="function-syntax">Errors::fatal</span></a><span class="plain-syntax">(</span><span class="string-syntax">"locale out of range"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">locales_unset</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-lcl.html#SP5" class="function-link"><span class="function-syntax">Locales::platform_locale</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">locale_settings</span><span class="plain-syntax">[</span><span class="identifier-syntax">L</span><span class="plain-syntax">] &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">locale_settings</span><span class="plain-syntax">[</span><span class="identifier-syntax">L</span><span class="plain-syntax">];</span>

View file

@ -622,7 +622,7 @@ values of these functions are always non-<span class="extract"><span class="extr
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Memory::calloc</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Memory::calloc</span></span>:<br/>Streams - <a href="2-str.html#SP26">&#167;26</a><br/>Dictionaries - <a href="2-dct.html#SP2">&#167;2</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">&#167;14</a><br/>Directories - <a href="3-drc.html#SP3">&#167;3</a><br/>Time - <a href="3-tm.html#SP7_1">&#167;7.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">how_many</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Memory::calloc</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Memory::calloc</span></span>:<br/>Streams - <a href="2-str.html#SP26">&#167;26</a><br/>Dictionaries - <a href="2-dct.html#SP2">&#167;2</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">&#167;14</a><br/>Directories - <a href="3-drc.html#SP4">&#167;4</a><br/>Time - <a href="3-tm.html#SP7_1">&#167;7.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">how_many</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-mmr.html#SP25" class="function-link"><span class="function-syntax">Memory::alloc_inner</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">how_many</span><span class="plain-syntax">, </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="identifier-syntax">reason</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="function-syntax">Memory::malloc</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Memory::malloc</span></span>:<br/>Streams - <a href="2-str.html#SP35_3">&#167;35.3</a><br/>C Strings - <a href="4-cst.html#SP11">&#167;11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">size_in_bytes</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">reason</span><span class="plain-syntax">) {</span>
@ -699,7 +699,7 @@ rarely and to allocate large blocks of memory.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Memory::I7_free</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Memory::I7_free</span></span>:<br/>Streams - <a href="2-str.html#SP34_2">&#167;34.2</a><br/>Dictionaries - <a href="2-dct.html#SP7_2">&#167;7.2</a>, <a href="2-dct.html#SP11">&#167;11</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">&#167;14</a><br/>Directories - <a href="3-drc.html#SP3">&#167;3</a><br/>C Strings - <a href="4-cst.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pointer</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bytes_freed</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Memory::I7_free</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Memory::I7_free</span></span>:<br/>Streams - <a href="2-str.html#SP34_2">&#167;34.2</a><br/>Dictionaries - <a href="2-dct.html#SP7_2">&#167;7.2</a>, <a href="2-dct.html#SP11">&#167;11</a><br/>Command Line Arguments - <a href="3-cla.html#SP14">&#167;14</a><br/>Directories - <a href="3-drc.html#SP4">&#167;4</a><br/>C Strings - <a href="4-cst.html#SP12">&#167;12</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pointer</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">R</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bytes_freed</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">R</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">NO_DEFINED_MREASON_VALUES</span><span class="plain-syntax">)) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no such memory reason"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pointer</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't free NULL memory"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOCK_MUTEX</span><span class="plain-syntax">(</span><span class="identifier-syntax">memory_statistics_mutex</span><span class="plain-syntax">);</span>

View file

@ -312,14 +312,14 @@ file encodings, but expanding <span class="extract"><span class="extract-syntax"
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'c'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'d'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'i'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'x'</span><span class="plain-syntax">: { </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">char</span></span><span class="comment-syntax"> is promoted to </span><span class="extract"><span class="extract-syntax">int</span></span><span class="comment-syntax"> in variable arguments</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ival</span><span class="plain-syntax"> = </span><span class="identifier-syntax">va_arg</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">temp</span><span class="plain-syntax">[256];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="constant-syntax">PLATFORM_SNPRINTF</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="constant-syntax">255</span><span class="plain-syntax">, </span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">ival</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">255</span><span class="plain-syntax">) </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="string-syntax">"?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">snprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="constant-syntax">255</span><span class="plain-syntax">, </span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">ival</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">255</span><span class="plain-syntax">) </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="string-syntax">"?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">temp</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) </span><a href="2-str.html#SP35" class="function-link"><span class="function-syntax">Streams::putc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">], </span><span class="identifier-syntax">stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'g'</span><span class="plain-syntax">: {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">double</span><span class="plain-syntax"> </span><span class="identifier-syntax">dval</span><span class="plain-syntax"> = </span><span class="identifier-syntax">va_arg</span><span class="plain-syntax">(</span><span class="identifier-syntax">ap</span><span class="plain-syntax">, </span><span class="reserved-syntax">double</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">temp</span><span class="plain-syntax">[256];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="constant-syntax">PLATFORM_SNPRINTF</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="constant-syntax">255</span><span class="plain-syntax">, </span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">dval</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">255</span><span class="plain-syntax">) </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="string-syntax">"?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">snprintf</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="constant-syntax">255</span><span class="plain-syntax">, </span><span class="identifier-syntax">format_string</span><span class="plain-syntax">, </span><span class="identifier-syntax">dval</span><span class="plain-syntax">) &gt;= </span><span class="constant-syntax">255</span><span class="plain-syntax">) </span><span class="identifier-syntax">strcpy</span><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">, </span><span class="string-syntax">"?"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">temp</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">]; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) </span><a href="2-str.html#SP35" class="function-link"><span class="function-syntax">Streams::putc</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">temp</span><span class="plain-syntax">[</span><span class="identifier-syntax">j</span><span class="plain-syntax">], </span><span class="identifier-syntax">stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>

View file

@ -67,22 +67,27 @@ transcoded the other way.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="function-syntax">Directories::open</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Directories::open</span></span>:<br/><a href="3-drc.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="function-syntax">Directories::open_from</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Directories::open_from</span></span>:<br/>Text Files - <a href="4-tf.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_locale_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_name_written_out</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_handle</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::opendir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_name_written_out</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_locale_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_name_written_out</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_handle</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::opendir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_name_written_out</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">directory_handle</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::next</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Directories::next</span></span>:<br/><a href="3-drc.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="function-syntax">Directories::open</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Directories::open</span></span>:<br/><a href="3-drc.html#SP3">&#167;3</a>, <a href="3-drc.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::open_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">D</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::next</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Directories::next</span></span>:<br/><a href="3-drc.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">leafname_Cs</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::readdir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_handle</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_name_written_out</span><span class="plain-syntax">, </span><span class="identifier-syntax">leafname_Cs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::readdir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_handle</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_name_written_out</span><span class="plain-syntax">, </span><span class="identifier-syntax">leafname_Cs</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">leafname_Cs</span><span class="plain-syntax">[0] != </span><span class="character-syntax">'.'</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">leafname</span><span class="plain-syntax">);</span>
@ -90,11 +95,23 @@ transcoded the other way.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::close</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Directories::close</span></span>:<br/><a href="3-drc.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::closedir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_handle</span><span class="plain-syntax">);</span>
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::close</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Directories::close</span></span>:<br/><a href="3-drc.html#SP3">&#167;3</a>, <a href="3-drc.html#SP4">&#167;4</a><br/>Text Files - <a href="4-tf.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::closedir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">directory_handle</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>It turns out to be useful to scan the contents of a directory in an order
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>Incredibly, this seems to be the most portable method for testing whether a
directory exists in the file system:
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Directories::exists</span><span class="plain-syntax">(</span><span class="reserved-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">TRY</span><span class="plain-syntax"> = </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::open</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">TRY</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::close</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">TRY</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>It turns out to be useful to scan the contents of a directory in an order
which is predictable regardless of platform &mdash; <span class="extract"><span class="extract-syntax">Platform::readdir</span></span> 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.
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::close</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">qsort</span><span class="plain-syntax">(</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">, (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">used</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *), </span><a href="3-drc.html#SP3" class="function-link"><span class="function-syntax">Directories::compare_names</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">qsort</span><span class="plain-syntax">(</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">, (</span><span class="identifier-syntax">size_t</span><span class="plain-syntax">) </span><span class="identifier-syntax">used</span><span class="plain-syntax">, </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *), </span><a href="3-drc.html#SP4" class="function-link"><span class="function-syntax">Directories::compare_names</span></a><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">used</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="2-mmr.html#SP26" class="function-link"><span class="function-syntax">Memory::I7_free</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">listing_array</span><span class="plain-syntax">, </span><span class="constant-syntax">ARRAY_SORTING_MREASON</span><span class="plain-syntax">, </span><span class="identifier-syntax">capacity</span><span class="plain-syntax">*((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="reserved-syntax">sizeof</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *)));</span>

View file

@ -327,7 +327,7 @@ when printed out.
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">FN</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">FN</span><span class="plain-syntax">, </span><span class="string-syntax">"%f"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_locale_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">FN</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP17" class="function-link"><span class="function-syntax">Platform::timestamp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">time_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::timestamp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">FN</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
@ -337,7 +337,7 @@ when printed out.
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">FN</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">FN</span><span class="plain-syntax">, </span><span class="string-syntax">"%f"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_locale_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">FN</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><a href="1-wp.html#SP17" class="function-link"><span class="function-syntax">Platform::size</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><a href="1-wp.html#SP16" class="function-link"><span class="function-syntax">Platform::size</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">FN</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">t</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

View file

@ -317,7 +317,7 @@ on the file system with that path.
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_locale_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">known_to_exist</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::mkdir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">known_to_exist</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::mkdir</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_pathname</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">known_to_exist</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
@ -338,7 +338,7 @@ anything different which was originally in <span class="extract"><span class="ex
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn2</span><span class="plain-syntax">, </span><span class="string-syntax">"%p"</span><span class="plain-syntax">, </span><span class="identifier-syntax">dest</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="4-sm.html#SP6" class="function-link"><span class="function-syntax">Str::copy_to_locale_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">, </span><span class="identifier-syntax">pn2</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">*</span><span class="constant-syntax">MAX_FILENAME_LENGTH</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn2</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP10" class="function-link"><span class="function-syntax">Platform::rsync</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="1-wp.html#SP9" class="function-link"><span class="function-syntax">Platform::rsync</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">transcoded_source</span><span class="plain-syntax">, </span><span class="identifier-syntax">transcoded_dest</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">

View file

@ -160,7 +160,7 @@ all transcoded to UTF-8 in the most unlucky way imaginable.
<span class="plain-syntax"> </span><span class="identifier-syntax">shell_verbosity</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Shell::run</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Shell::run</span></span>:<br/><a href="3-shl.html#SP2">&#167;2</a>, <a href="3-shl.html#SP3">&#167;3</a><br/>POSIX Platforms - <a href="1-pp.html#SP18">&#167;18</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_4_1">&#167;7.4.1</a>, <a href="5-ee.html#SP7_4_2">&#167;7.4.2</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Shell::run</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Shell::run</span></span>:<br/><a href="3-shl.html#SP2">&#167;2</a>, <a href="3-shl.html#SP3">&#167;3</a><br/>POSIX Platforms - <a href="1-pp.html#SP17">&#167;17</a><br/>Epub Ebooks - <a href="5-ee.html#SP7_4_1">&#167;7.4.1</a>, <a href="5-ee.html#SP7_4_2">&#167;7.4.2</a></span></button><span class="plain-syntax">(</span><span class="constant-syntax">OUTPUT_STREAM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">shell_verbosity</span><span class="plain-syntax">) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"shell: %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">SHELL_USAGE</span><span class="plain-syntax">, </span><span class="string-syntax">"shell: %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">spool</span><span class="plain-syntax">[</span><span class="constant-syntax">SPOOL_LENGTH</span><span class="plain-syntax">];</span>
@ -169,7 +169,7 @@ all transcoded to UTF-8 in the most unlucky way imaginable.
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDOUT</span><span class="plain-syntax">, </span><span class="string-syntax">"debugger mode suppressing shell command: %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP8" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spool</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><a href="1-wp.html#SP7" class="function-link"><span class="function-syntax">Platform::system</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spool</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">rv</span><span class="plain-syntax"> == -1) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="constant-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"shell: %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"OS shell error"</span><span class="plain-syntax">);</span>

View file

@ -88,7 +88,7 @@ access.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Str::new</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">&#167;4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">&#167;6</a>, <a href="3-cla.html#SP11">&#167;11</a><br/>Directories - <a href="3-drc.html#SP3">&#167;3</a><br/>Preprocessor - <a href="4-prp.html#SP3_2_1">&#167;3.2.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP4_1_3_1_3">&#167;4.1.3.1.3</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">&#167;5.2</a>, <a href="8-ws.html#SP6_1">&#167;6.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Str::new</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Str::new</span></span>:<br/><a href="4-sm.html#SP3">&#167;3</a><br/>Debugging Log - <a href="2-dl.html#SP4_1">&#167;4.1</a><br/>Dictionaries - <a href="2-dct.html#SP7_3_1">&#167;7.3.1</a><br/>Command Line Arguments - <a href="3-cla.html#SP6">&#167;6</a>, <a href="3-cla.html#SP11">&#167;11</a><br/>Directories - <a href="3-drc.html#SP4">&#167;4</a><br/>Preprocessor - <a href="4-prp.html#SP3_2_1">&#167;3.2.1</a>, <a href="4-prp.html#SP4_1_3_1_1">&#167;4.1.3.1.1</a>, <a href="4-prp.html#SP4_1_3_1_3">&#167;4.1.3.1.3</a><br/>HTML - <a href="5-htm.html#SP27_2">&#167;27.2</a><br/>Epub Ebooks - <a href="5-ee.html#SP5">&#167;5</a><br/>Version Numbers - <a href="7-vn.html#SP7">&#167;7</a><br/>Web Structure - <a href="8-ws.html#SP5_2">&#167;5.2</a>, <a href="8-ws.html#SP6_1">&#167;6.1</a>, <a href="8-ws.html#SP7_2_1">&#167;7.2.1</a>, <a href="8-ws.html#SP7_2_2_1">&#167;7.2.2.1</a><br/>Build Files - <a href="8-bf.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">void</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new_with_capacity</span></a><span class="plain-syntax">(32);</span>
<span class="plain-syntax">}</span>
@ -462,7 +462,7 @@ around 1%.
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L1</span><span class="plain-syntax"> - </span><span class="identifier-syntax">L2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::cmp_insensitive</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">Str::cmp_insensitive</span></span>:<br/><a href="4-sm.html#SP19">&#167;19</a><br/>Command Line Arguments - <a href="3-cla.html#SP15">&#167;15</a><br/>Directories - <a href="3-drc.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Str::cmp_insensitive</span><button class="popup" onclick="togglePopup('usagePopup29')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup29">Usage of <span class="code-font"><span class="function-syntax">Str::cmp_insensitive</span></span>:<br/><a href="4-sm.html#SP19">&#167;19</a><br/>Command Line Arguments - <a href="3-cla.html#SP15">&#167;15</a><br/>Directories - <a href="3-drc.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S1</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">string_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">Str::start</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">), </span><span class="identifier-syntax">Q</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP10" class="function-link"><span class="function-syntax">Str::start</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S2</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">.</span><span class="identifier-syntax">index</span><span class="plain-syntax"> &lt; </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S1</span><span class="plain-syntax">)) &amp;&amp; (</span><span class="identifier-syntax">Q</span><span class="plain-syntax">.</span><span class="element-syntax">index</span><span class="plain-syntax"> &lt; </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">S2</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">Str::forward</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">), </span><span class="identifier-syntax">Q</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP11" class="function-link"><span class="function-syntax">Str::forward</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Q</span><span class="plain-syntax">)) {</span>

View file

@ -59,11 +59,24 @@ standard way to read in and iterate through lines of a text file.
</p>
<p class="commentary">First, though, here is a perhaps clumsy but effective way to test if a
file actually exists on disc at a given filename:
file actually exists on disc at a given filename. Note that under the C standard,
it's entirely legal for <span class="extract"><span class="extract-syntax">fopen</span></span> to behave more or less as it likes if asked to
open a directory as a file; and on MacOS, it sometimes opens a directory exactly
as if it were an empty text file. The safest way to ensure that a directory is
never confused with a file seems to be to try <span class="extract"><span class="extract-syntax">opendir</span></span> on it, and the following
does essentially that.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">TextFiles::exists</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">TextFiles::exists</span></span>:<br/>Web Structure - <a href="8-ws.html#SP7_2_2_4">&#167;7.2.2.4</a>, <a href="8-ws.html#SP8">&#167;8</a><br/>Build Files - <a href="8-bf.html#SP1">&#167;1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">, </span><span class="string-syntax">"%f"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">scan_directory</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::open_from</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pn</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-drc.html#SP2" class="function-link"><span class="function-syntax">Directories::close</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HANDLE</span><span class="plain-syntax"> = </span><a href="3-fln.html#SP10" class="function-link"><span class="function-syntax">Filenames::fopen</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="string-syntax">"rb"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">HANDLE</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fclose</span><span class="plain-syntax">(</span><span class="identifier-syntax">HANDLE</span><span class="plain-syntax">);</span>

Binary file not shown.

View file

@ -16,17 +16,22 @@ whatever the locale encoding is; the filenames coming back have to be
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)
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;
@ -43,6 +48,17 @@ void Directories::close(scan_directory *D) {
Platform::closedir(D->directory_handle);
}
@ 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;
}
@ 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

View file

@ -9,10 +9,23 @@ files, HTML, XML and so on. The main aim of this section is to provide a
standard way to read in and iterate through lines of a text file.
First, though, here is a perhaps clumsy but effective way to test if a
file actually exists on disc at a given filename:
file actually exists on disc at a given filename. Note that under the C standard,
it's entirely legal for |fopen| to behave more or less as it likes if asked to
open a directory as a file; and on MacOS, it sometimes opens a directory exactly
as if it were an empty text file. The safest way to ensure that a directory is
never confused with a file seems to be to try |opendir| on it, and the following
does essentially that.
=
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);