diff --git a/foundation-module/Chapter 1/Foundation Module.w b/foundation-module/Chapter_1/Foundation_Module.nw similarity index 100% rename from foundation-module/Chapter 1/Foundation Module.w rename to foundation-module/Chapter_1/Foundation_Module.nw diff --git a/foundation-module/Chapter 1/POSIX Platforms.w b/foundation-module/Chapter_1/POSIX_Platforms.nw similarity index 86% rename from foundation-module/Chapter 1/POSIX Platforms.w rename to foundation-module/Chapter_1/POSIX_Platforms.nw index df00ace..2ffe66b 100644 --- a/foundation-module/Chapter 1/POSIX Platforms.w +++ b/foundation-module/Chapter_1/POSIX_Platforms.nw @@ -18,10 +18,7 @@ operating system, and the other one on Windows. @ Some basics that apply to all POSIX-supporting systems. -@d FOLDER_SEPARATOR '/' -@d SHELL_QUOTE_CHARACTER '\'' - -= (very early code) +<<*>>= #include #include #include @@ -30,80 +27,92 @@ operating system, and the other one on Windows. #include #include -@h Mac OS X. ^"ifdef-PLATFORM_MACOS" +#define FOLDER_SEPARATOR '/' +#define SHELL_QUOTE_CHARACTER '\'' -@d PLATFORM_STRING "macos" -@d SHELL_QUOTE_CHARACTER '\'' -@d INFORM_FOLDER_RELATIVE_TO_HOME "Library" +@ \section{Mac OS X.} +<<*>>= +#ifdef PLATFORM_MACOS -@h Generic Unix. ^"ifdef-PLATFORM_UNIX" +#define PLATFORM_STRING "macos" +#define SHELL_QUOTE_CHARACTER '\'' +#define INFORM_FOLDER_RELATIVE_TO_HOME "Library" + +@ \section{Generic Unix.} +<<*>>= +#ifdef PLATFORM_UNIX + +@ These settings are used both for the Linux versions (both command-line, by +Adam Thornton, and for Ubuntu, Fedora, Debian and so forth, by Philip +Chimento) and also for Solaris variants: they can probably be used for any +Unix-based system. + +#define PLATFORM_STRING "unix" +#define INFORM_FOLDER_RELATIVE_TO_HOME "" + +<<*>>= +#include + +@ \section{Linux.} These settings are used both for the Linux versions (both command-line, by Adam Thornton, and for Ubuntu, Fedora, Debian and so forth, by Philip Chimento) and also for Solaris variants: they can probably be used for any Unix-based system. -@d PLATFORM_STRING "unix" -@d INFORM_FOLDER_RELATIVE_TO_HOME "" +<<*>>= +#ifdef PLATFORM_LINUX +#define PLATFORM_STRING "linux" +#define INFORM_FOLDER_RELATIVE_TO_HOME "" -= (very early code) +<<*>>= #include -@h Linux. ^"ifdef-PLATFORM_LINUX" -These settings are used both for the Linux versions (both command-line, by -Adam Thornton, and for Ubuntu, Fedora, Debian and so forth, by Philip -Chimento) and also for Solaris variants: they can probably be used for any -Unix-based system. - -@d PLATFORM_STRING "linux" -@d INFORM_FOLDER_RELATIVE_TO_HOME "" - -= (very early code) -#include - -@h Android. ^"ifdef-PLATFORM_ANDROID" +@ \section{Android.} These settings are used for Nathan Summers's Android versions. -@d PLATFORM_STRING "android" -@d SUPPRESS_MAIN -@d INFORM_FOLDER_RELATIVE_TO_HOME "" +<<*>>= +#ifdef PLATFORM_ANDROID +#define PLATFORM_STRING "android" +#define SUPPRESS_MAIN +#define INFORM_FOLDER_RELATIVE_TO_HOME "" -= (very early code) +<<*>>= #include -@h Folder separator. +@ \section{Folder separator.} When using a Unix-like system such as Cygwin on Windows, it's inevitable that paths will sometimes contain backslashes and sometimes forward slashes, meaning a folder (i.e. directory) divide in either case. So: (a) When writing such a divider, always write |FOLDER_SEPARATOR|, a backslash; (b) When testing for such a divider, call the following. -= +<<*>>= int Platform::is_folder_separator(wchar_t c) { return (c == FOLDER_SEPARATOR); } -@h Locale. +@ \section{Locale.} The following definition handles possible differences of text encoding in filenames, which depend on the current "locale". Locale is an odd piece of old Unix terminology, but one thing it includes is how the textual names of files are encoded (as ASCII, as ISO Latin-1, as UTF-8, etc.). The default here is UTF-8 since OS X and Linux both adopt this. -= +<<*>>= #ifndef LOCALE_IS_ISO #ifndef LOCALE_IS_UTF8 #define LOCALE_IS_UTF8 1 #endif #endif -@h Environment variables. +@ \section{Environment variables.} -= +<<*>>= char *Platform::getenv(const char *name) { return getenv(name); } -@h Executable location. ^"ifdef-PLATFORM_LINUX" +@ \section{Executable location.} Fill the wide-char buffer |p| with the path to the current executable, up to length |length|. This function is guaranteed to be called from only one thread. Should the information be unavailable, or fail to fit into |p|, @@ -111,7 +120,8 @@ truncate |p| to zero length. (On some platforms, the information will always be unavailable: that doesn't mean we can't run on those platforms, just that installation and use of Foundation-built tools is less convenient.) -= +<<*>>= +ifdef PLATFORM_LINUX void Platform::where_am_i(wchar_t *p, size_t length) { char buffer[PATH_MAX + 1]; @; @@ -123,7 +133,7 @@ Follow that link to find the path. Normally when reading a symlink, one uses |lstat()| to find the path length instead of guessing |PATH_MAX|, but the symlinks in |/proc| are special and don't provide a length to |lstat()|. -@ = +<>= ssize_t link_len = readlink("/proc/self/exe", buffer, PATH_MAX); if (link_len < 0) @; // unable to find buffer[link_len] = '\0'; @@ -132,13 +142,14 @@ symlinks in |/proc| are special and don't provide a length to |lstat()|. encoding, and possibly in a multibyte encoding such as UTF-8) to a wide-char string. -@ = +<>= size_t convert_len = mbstowcs(p, buffer, length); if (convert_len == (size_t)-1) @; // wouldn't fit -@ And now the Mac version: ^"ifdef-PLATFORM_MACOS" +@ And now the Mac version: -= (very early code) +<<*>>= +#ifdef PLATFORM_MACOS int _NSGetExecutablePath(char* buf, uint32_t* bufsize); void Platform::where_am_i(wchar_t *p, size_t length) { @@ -160,34 +171,35 @@ void Platform::where_am_i(wchar_t *p, size_t length) { if (convert_len == (size_t)-1) @; } -@ For Unix, there's nothing we can generically do. ^"ifdef-PLATFORM_UNIX" +@ For Unix, there's nothing we can generically do. #ifdef PLATFORM_UNIX" -= +<<*>>= void Platform::where_am_i(wchar_t *p, size_t length) { @; } -@ On Android, there's no real need for this. ^"ifdef-PLATFORM_ANDROID" +@ On Android, there's no real need for this. #ifdef PLATFORM_ANDROID" -= +<<*>>= void Platform::where_am_i(wchar_t *p, size_t length) { @; } @ All of the above make use of: -@ = +<>= p[0] = '\0'; return; -@h Shell commands. ^"ifndef-PLATFORM_MACOS" +@ \section{Shell commands.} -= +<<*>>= +#ifndef PLATFORM_MACOS int Platform::system(const char *cmd) { return system(cmd); } -@ ^"ifdef-PLATFORM_MACOS" +@ In MacOS 10.5, a new implementation of the C standard library crippled performance of |system()| by placing it behind a global mutex, so that it was impossible for two cores to be calling the function at the same @@ -207,7 +219,8 @@ about signal-handling -- led to obscure and unrepeatable memory corruption bugs in Intest, with the worker threads apparently writing on each other's memory space. Using |posix_spawn()| instead appears to work better. -= +<<*>>= +#ifdef PLATFORM_MACOS #include #include @@ -227,9 +240,9 @@ int Platform::system(const char *cmd) { return -1; } -@h Directory handling. +@ \section{ Directory handling.} -= +<<*>>= int Platform::mkdir(char *transcoded_pathname) { errno = 0; int rv = mkdir(transcoded_pathname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); @@ -263,14 +276,14 @@ void Platform::closedir(void *D) { closedir(dirp); } -@h Timestamp and file size. +@ \section{ Timestamp and file size. There are implementations of the C standard library where |time_t| has super-weird behaviour, but on almost all POSIX systems, time 0 corresponds to midnight on 1 January 1970. All we really need is that the "never" value is one which is earlier than any possible timestamp on the files we'll be dealing with. -= +<<*>>= time_t Platform::never_time(void) { return (time_t) 0; } @@ -287,14 +300,14 @@ off_t Platform::size(char *transcoded_filename) { return (off_t) 0; } -@h Sync. +@ \section{Sync.} Both names here are of directories which do exist. The function makes the |dest| tree an exact copy of the |source| tree (and therefore deletes anything different which was originally in |dest|). In POSIX world, we can fairly well depend on |rsync| being around: -= +<<*>>= void Platform::rsync(char *transcoded_source, char *transcoded_dest) { char rsync_command[10*MAX_FILENAME_LENGTH]; sprintf(rsync_command, "rsync -a --delete "); @@ -317,14 +330,14 @@ void Platform::quote_text(char *quoted, char *raw, int terminate) { quoted[qp++] = 0; } -@h Sleep. +@ \section{Sleep.} -= +<<*>>= void Platform::sleep(int seconds) { sleep((unsigned int) seconds); } -@h Notifications. ^"ifdef-PLATFORM_MACOS" +@ \section{Notifications.} The "submarine" sound is a gloomy thunk; the "bell" is the three-tone rising alert noise which iPhones make when they receive texts, but which hackers of a certain age will remember as the "I have ripped your music CD now" alert from @@ -335,7 +348,8 @@ It is anybody's guess how long Apple will permit the shell command |osascript| to survive, given the MacOS team's current hostility to scripting; we're actually running a one-line AppleScript here. -= +<<*>>= +#ifdef-PLATFORM_MACOS void Platform::notification(text_stream *text, int happy) { char *sound_name = "Bell.aiff"; if (happy == FALSE) sound_name = "Submarine.aiff"; @@ -346,13 +360,14 @@ void Platform::notification(text_stream *text, int happy) { DISCARD_TEXT(TEMP) } -@ ^"ifndef-PLATFORM_MACOS" +@ -= +<<*>>= +#ifndef PLATFORM_MACOS void Platform::notification(text_stream *text, int happy) { } -@h Terminal setup. +@ \section{Terminal setup.} The idea of this function is that if anything needs to be done to enable the output of ANSI-standard coloured terminal output, then this function has the chance to do it; similarly, it may need to configure itself to receive console @@ -361,19 +376,21 @@ find this). On POSIX platforms, so far as we know, nothing need be done. -= +<<*>>= void Platform::configure_terminal(void) { } -@h Concurrency. +@ \section{Concurrency.} The following abstracts the pthread library, so that it can all be done differently on Windows. -= (very early code) +<<*>>= typedef pthread_t foundation_thread; typedef pthread_attr_t foundation_thread_attributes; -@ = +@ + +<<*>>= int Platform::create_thread(foundation_thread *pt, const foundation_thread_attributes *pa, void *(*fn)(void *), void *arg) { return pthread_create(pt, pa, fn, arg); @@ -394,35 +411,36 @@ size_t Platform::get_thread_stack_size(foundation_thread_attributes *pa) { return mystacksize; } -@ ^"ifdef-PLATFORM_LINUX" +@ This function returns the number of logical cores in the host computer -- i.e., twice the number of physical cores if there's hyperthreading. The result is used as a guess for an appropriate number of simultaneous threads to launch. It's not easy to find a function which reliably does this on all POSIX platforms. -On Linux we can use |sys/sysinfo.h|, but this header is a POSIX extension which +On Linux we can use |sys/sysinfo.h|, but this section is a POSIX extension which MacOS does not support. -= (very early code) +<<*>>= +#ifdef PLATFORM_LINUX #include -@ ^"ifdef-PLATFORM_LINUX" -= +@ #ifdef PLATFORM_LINUX" +<<*>>= int Platform::get_core_count(void) { int N = get_nprocs(); if (N < 1) return 1; return N; } -@ ^"ifdef-PLATFORM_MACOS" +@ #ifdef PLATFORM_MACOS" While MacOS lacks |sysinfo.h|, it does have |sysctl.h|: -= (very early code) +<<*>>= #include -@ ^"ifdef-PLATFORM_MACOS" -= +@ #ifdef PLATFORM_MACOS" +<<*>>= int Platform::get_core_count(void) { int N; size_t N_size = sizeof(int); @@ -431,17 +449,17 @@ int Platform::get_core_count(void) { return N; } -@ ^"ifdef-PLATFORM_ANDROID" +@ #ifdef PLATFORM_ANDROID" For Android it seems prudent simply to ignore multithreading: -= +<<*>>= int Platform::get_core_count(void) { return 1; } -@h Mutexes. +@ \section{Mutexes.} -@d CREATE_MUTEX(name) +#define CREATE_MUTEX(name) static pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER; -@d LOCK_MUTEX(name) pthread_mutex_lock(&name); -@d UNLOCK_MUTEX(name) pthread_mutex_unlock(&name); +#define LOCK_MUTEX(name) pthread_mutex_lock(&name); +#define UNLOCK_MUTEX(name) pthread_mutex_unlock(&name); diff --git a/foundation-module/Chapter 1/Windows Platform.w b/foundation-module/Chapter_1/Windows Platform.w similarity index 100% rename from foundation-module/Chapter 1/Windows Platform.w rename to foundation-module/Chapter_1/Windows Platform.w diff --git a/foundation-module/Chapter 2/Debugging Log.w b/foundation-module/Chapter_2/Debugging Log.w similarity index 100% rename from foundation-module/Chapter 2/Debugging Log.w rename to foundation-module/Chapter_2/Debugging Log.w diff --git a/foundation-module/Chapter 2/Dictionaries.w b/foundation-module/Chapter_2/Dictionaries.w similarity index 100% rename from foundation-module/Chapter 2/Dictionaries.w rename to foundation-module/Chapter_2/Dictionaries.w diff --git a/foundation-module/Chapter 2/Foundation Classes.w b/foundation-module/Chapter_2/Foundation Classes.w similarity index 100% rename from foundation-module/Chapter 2/Foundation Classes.w rename to foundation-module/Chapter_2/Foundation Classes.w diff --git a/foundation-module/Chapter 2/Linked Lists and Stacks.w b/foundation-module/Chapter_2/Linked Lists and Stacks.w similarity index 100% rename from foundation-module/Chapter 2/Linked Lists and Stacks.w rename to foundation-module/Chapter_2/Linked Lists and Stacks.w diff --git a/foundation-module/Chapter 2/Locales.w b/foundation-module/Chapter_2/Locales.w similarity index 100% rename from foundation-module/Chapter 2/Locales.w rename to foundation-module/Chapter_2/Locales.w diff --git a/foundation-module/Chapter 2/Memory.w b/foundation-module/Chapter_2/Memory.w similarity index 100% rename from foundation-module/Chapter 2/Memory.w rename to foundation-module/Chapter_2/Memory.w diff --git a/foundation-module/Chapter 2/Methods.w b/foundation-module/Chapter_2/Methods.w similarity index 100% rename from foundation-module/Chapter 2/Methods.w rename to foundation-module/Chapter_2/Methods.w diff --git a/foundation-module/Chapter 2/Streams.w b/foundation-module/Chapter_2/Streams.w similarity index 100% rename from foundation-module/Chapter 2/Streams.w rename to foundation-module/Chapter_2/Streams.w diff --git a/foundation-module/Chapter 2/Trees.w b/foundation-module/Chapter_2/Trees.w similarity index 100% rename from foundation-module/Chapter 2/Trees.w rename to foundation-module/Chapter_2/Trees.w diff --git a/foundation-module/Chapter 2/Writers and Loggers.w b/foundation-module/Chapter_2/Writers and Loggers.w similarity index 100% rename from foundation-module/Chapter 2/Writers and Loggers.w rename to foundation-module/Chapter_2/Writers and Loggers.w diff --git a/foundation-module/Chapter 3/Case-Insensitive Filenames.w b/foundation-module/Chapter_3/Case-Insensitive Filenames.w similarity index 100% rename from foundation-module/Chapter 3/Case-Insensitive Filenames.w rename to foundation-module/Chapter_3/Case-Insensitive Filenames.w diff --git a/foundation-module/Chapter 3/Command Line Arguments.w b/foundation-module/Chapter_3/Command Line Arguments.w similarity index 100% rename from foundation-module/Chapter 3/Command Line Arguments.w rename to foundation-module/Chapter_3/Command Line Arguments.w diff --git a/foundation-module/Chapter 3/Directories.w b/foundation-module/Chapter_3/Directories.w similarity index 100% rename from foundation-module/Chapter 3/Directories.w rename to foundation-module/Chapter_3/Directories.w diff --git a/foundation-module/Chapter 3/Error Messages.w b/foundation-module/Chapter_3/Error Messages.w similarity index 100% rename from foundation-module/Chapter 3/Error Messages.w rename to foundation-module/Chapter_3/Error Messages.w diff --git a/foundation-module/Chapter 3/Filenames.w b/foundation-module/Chapter_3/Filenames.w similarity index 100% rename from foundation-module/Chapter 3/Filenames.w rename to foundation-module/Chapter_3/Filenames.w diff --git a/foundation-module/Chapter 3/Pathnames.w b/foundation-module/Chapter_3/Pathnames.w similarity index 100% rename from foundation-module/Chapter 3/Pathnames.w rename to foundation-module/Chapter_3/Pathnames.w diff --git a/foundation-module/Chapter 3/Shell.w b/foundation-module/Chapter_3/Shell.w similarity index 100% rename from foundation-module/Chapter 3/Shell.w rename to foundation-module/Chapter_3/Shell.w diff --git a/foundation-module/Chapter 3/Time.w b/foundation-module/Chapter_3/Time.w similarity index 100% rename from foundation-module/Chapter 3/Time.w rename to foundation-module/Chapter_3/Time.w diff --git a/foundation-module/Chapter 4/C Strings.w b/foundation-module/Chapter_4/C Strings.w similarity index 100% rename from foundation-module/Chapter 4/C Strings.w rename to foundation-module/Chapter_4/C Strings.w diff --git a/foundation-module/Chapter 4/Characters.w b/foundation-module/Chapter_4/Characters.w similarity index 100% rename from foundation-module/Chapter 4/Characters.w rename to foundation-module/Chapter_4/Characters.w diff --git a/foundation-module/Chapter 4/JSON.w b/foundation-module/Chapter_4/JSON.w similarity index 100% rename from foundation-module/Chapter 4/JSON.w rename to foundation-module/Chapter_4/JSON.w diff --git a/foundation-module/Chapter 4/Pattern Matching.w b/foundation-module/Chapter_4/Pattern Matching.w similarity index 100% rename from foundation-module/Chapter 4/Pattern Matching.w rename to foundation-module/Chapter_4/Pattern Matching.w diff --git a/foundation-module/Chapter 4/Preprocessor.w b/foundation-module/Chapter_4/Preprocessor.w similarity index 100% rename from foundation-module/Chapter 4/Preprocessor.w rename to foundation-module/Chapter_4/Preprocessor.w diff --git a/foundation-module/Chapter 4/String Manipulation.w b/foundation-module/Chapter_4/String Manipulation.w similarity index 100% rename from foundation-module/Chapter 4/String Manipulation.w rename to foundation-module/Chapter_4/String Manipulation.w diff --git a/foundation-module/Chapter 4/Text Files.w b/foundation-module/Chapter_4/Text Files.w similarity index 100% rename from foundation-module/Chapter 4/Text Files.w rename to foundation-module/Chapter_4/Text Files.w diff --git a/foundation-module/Chapter 4/Tries and Avinues.w b/foundation-module/Chapter_4/Tries and Avinues.w similarity index 100% rename from foundation-module/Chapter 4/Tries and Avinues.w rename to foundation-module/Chapter_4/Tries and Avinues.w diff --git a/foundation-module/Chapter 4/Wide Strings.w b/foundation-module/Chapter_4/Wide Strings.w similarity index 100% rename from foundation-module/Chapter 4/Wide Strings.w rename to foundation-module/Chapter_4/Wide Strings.w diff --git a/foundation-module/Chapter 5/Epub Ebooks.w b/foundation-module/Chapter_5/Epub Ebooks.w similarity index 100% rename from foundation-module/Chapter 5/Epub Ebooks.w rename to foundation-module/Chapter_5/Epub Ebooks.w diff --git a/foundation-module/Chapter 5/HTML.w b/foundation-module/Chapter_5/HTML.w similarity index 100% rename from foundation-module/Chapter 5/HTML.w rename to foundation-module/Chapter_5/HTML.w diff --git a/foundation-module/Chapter 6/Binary Files.w b/foundation-module/Chapter_6/Binary Files.w similarity index 100% rename from foundation-module/Chapter 6/Binary Files.w rename to foundation-module/Chapter_6/Binary Files.w diff --git a/foundation-module/Chapter 6/Image Dimensions.w b/foundation-module/Chapter_6/Image Dimensions.w similarity index 100% rename from foundation-module/Chapter 6/Image Dimensions.w rename to foundation-module/Chapter_6/Image Dimensions.w diff --git a/foundation-module/Chapter 6/Sound Durations.w b/foundation-module/Chapter_6/Sound Durations.w similarity index 100% rename from foundation-module/Chapter 6/Sound Durations.w rename to foundation-module/Chapter_6/Sound Durations.w diff --git a/foundation-module/Chapter 7/Version Number Ranges.w b/foundation-module/Chapter_7/Version Number Ranges.w similarity index 100% rename from foundation-module/Chapter 7/Version Number Ranges.w rename to foundation-module/Chapter_7/Version Number Ranges.w diff --git a/foundation-module/Chapter 7/Version Numbers.w b/foundation-module/Chapter_7/Version Numbers.w similarity index 100% rename from foundation-module/Chapter 7/Version Numbers.w rename to foundation-module/Chapter_7/Version Numbers.w diff --git a/foundation-module/Chapter 8/Bibliographic Data for Webs.w b/foundation-module/Chapter_8/Bibliographic Data for Webs.w similarity index 100% rename from foundation-module/Chapter 8/Bibliographic Data for Webs.w rename to foundation-module/Chapter_8/Bibliographic Data for Webs.w diff --git a/foundation-module/Chapter 8/Build Files.w b/foundation-module/Chapter_8/Build Files.w similarity index 100% rename from foundation-module/Chapter 8/Build Files.w rename to foundation-module/Chapter_8/Build Files.w diff --git a/foundation-module/Chapter 8/Simple Tangler.w b/foundation-module/Chapter_8/Simple Tangler.w similarity index 100% rename from foundation-module/Chapter 8/Simple Tangler.w rename to foundation-module/Chapter_8/Simple Tangler.w diff --git a/foundation-module/Chapter 8/Web Modules.w b/foundation-module/Chapter_8/Web Modules.w similarity index 100% rename from foundation-module/Chapter 8/Web Modules.w rename to foundation-module/Chapter_8/Web Modules.w diff --git a/foundation-module/Chapter 8/Web Structure.w b/foundation-module/Chapter_8/Web Structure.w similarity index 100% rename from foundation-module/Chapter 8/Web Structure.w rename to foundation-module/Chapter_8/Web Structure.w