foundation-module: Replace spaces in file names to underscores.

This commit is contained in:
AwesomeAdam54321 2024-03-07 15:48:31 +08:00
parent 7c2efe9851
commit 4b2c8bd3ff
42 changed files with 100 additions and 82 deletions

View file

@ -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 <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
@ -30,80 +27,92 @@ operating system, and the other one on Windows.
#include <limits.h>
#include <unistd.h>
@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 <strings.h>
@ \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 <strings.h>
@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 <strings.h>
@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 <strings.h>
@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];
@<Follow the proc filesystem symlink to the real filesystem's file@>;
@ -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()|.
@<Follow the proc filesystem symlink to the real filesystem's file@> =
<<Follow the proc filesystem symlink to the real filesystem's file>>=
ssize_t link_len = readlink("/proc/self/exe", buffer, PATH_MAX);
if (link_len < 0) @<Fail@>; // 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.
@<Transcode buffer, which is locale-encoded, into the wide-char buffer@> =
<<Transcode buffer, which is locale-encoded, into the wide-char buffer>>=
size_t convert_len = mbstowcs(p, buffer, length);
if (convert_len == (size_t)-1) @<Fail@>; // 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) @<Fail@>;
}
@ 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) {
@<Fail@>;
}
@ 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) {
@<Fail@>;
}
@ All of the above make use of:
@<Fail@> =
<<Fail>>=
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 <spawn.h>
#include <sys/wait.h>
@ -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 <sys/sysinfo.h>
@ ^"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 <sys/sysctl.h>
@ ^"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);