123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /* Part of Scheme 48 1.9. See file COPYING for notices and license.
- *
- * Authors: Mike Sperber
- */
- #include <stdio.h>
- #include <stdlib.h> /* for getenv(), etc. (POSIX?/ANSI) */
- #include <string.h> /* for strncpy(), etc. (POSIX/ANSI) */
- #include <errno.h>
- #include <windows.h>
- /*
- Expanding Windows filenames
- Windows Sucks. Unix Sucks. C Sucks.
- Richard Kelsey Wed Jan 17 21:40:26 EST 1990 (for the Unix version)
- Later rewritten by others who wish to remain anonymous.
- Expands ~/ in string `name', leaving the result in `buffer'.
- `buffer_len' is the length of `buffer'.
- */
- char *s48_expand_file_name (char *name, char *buffer, int buffer_len)
- {
- char *drive = NULL, *path = NULL, *dir = NULL;
- int dir_len;
- int name_len = strlen(name);
- if ((name_len >= 2) && (name[0] == '~') && ((name[1] == '\\' || (name[1] == '/'))))
- {
- drive = getenv("HOMEDRIVE");
- /* HOMEPATH is usually \.
- * I have no idea if it will have trailing \ for a subdirectory.
- */
- path = getenv("HOMEPATH");
- name += 1;
- name_len -= 2;
- }
- else if ((name_len >= 3) && (name[0] == '%'))
- {
- char *pos = strchr(name + 2, '%');
- if (pos)
- {
- *pos = '\0';
- dir = getenv(name+1);
- name = pos + 1;
- name_len -= (pos - name) + 1;
- }
- }
- if ((drive && path) || dir)
- {
- if (drive && path)
- dir_len = strlen(drive) + strlen(path);
- else
- dir_len = strlen(dir);
- if ((name_len + dir_len + 1) > buffer_len)
- {
- fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
- return(NULL);
- };
- if (drive && path)
- {
- int drive_length = strlen(drive);
- strcpy(buffer, drive);
- strcpy(buffer + drive_length, path);
- strcpy(buffer + dir_len, name);
- }
- else
- {
- strcpy(buffer, dir);
- strcpy(buffer + dir_len, name);
- }
- }
- else
- {
- if ((name_len + 1) > buffer_len)
- {
- fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
- return NULL;
- };
- strcpy(buffer, name);
- }
- return(buffer);
- }
- /* test routine */
- /*
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char buffer[512];
- s48_expand_file_name(argv[1], buffer, 512);
- printf("%s\n", buffer);
- return(0);
- }
- /* */
- /* Driver loop for tail-recursive calls */
- long s48_return_value;
- long
- s48_run_machine(long (*proc) (void))
- {
- while (proc != 0)
- proc = (long (*) (void)) (*proc)();
- return s48_return_value;
- }
- /* Infinities and NaNs */
- /* Visual C++ barfs when trying to evaluate 1.0/0.0 statically. */
- static double double_zero = 0.0;
- double
- ps_pos_infinity(void)
- {
- return 1.0 / double_zero;
- }
- double
- ps_neg_infinity(void)
- {
- return -1.0 / double_zero;
- }
- double
- ps_not_a_number(void)
- {
- return (-1.0 / double_zero) + (1.0 / double_zero);
- }
- unsigned char *
- ps_error_string(long the_errno)
- {
- DWORD id = (DWORD) the_errno;
- #define ERROR_BUFFER_SIZE 512
- static WCHAR buf[ERROR_BUFFER_SIZE + 1];
- static char utf8[(ERROR_BUFFER_SIZE * 4) + 1];
- for (;;)
- {
- if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, /* lpSource */
- id,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buf, ERROR_BUFFER_SIZE,
- NULL)) /* arguments ... */
- {
- int count
- = WideCharToMultiByte(CP_UTF8,
- 0, /* dwFlags */
- buf,
- -1,
- utf8,
- ERROR_BUFFER_SIZE * 4 + 1,
- NULL, /* lpDefaultChar */
- NULL /* lpUsedDefaultChar */
- );
- /* get rid of annoying trailing line end */
- if ((count > 3) && (utf8[count-3] == 0x0d) && (utf8[count-2] == 0x0a))
- utf8[count-3] = '\0';
- return utf8;
- }
- else
- /* risky, but we assume some amount of sanity on the side of
- the Windows implementors---haha */
- id = GetLastError();
- }
- #undef ERROR_BUFFER_SIZE
- }
- /* Getting the length of a file. */
- long
- s48_get_file_size(unsigned char *name)
- {
- HANDLE handle = CreateFile(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (handle == INVALID_HANDLE_VALUE)
- return -1;
-
- {
- DWORD dwSize = GetFileSize(handle, NULL);
-
- CloseHandle(handle);
-
- if (dwSize == 0xFFFFFFFF)
- return -1;
- else
- return (long) dwSize;
- }
- }
|