misc.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. *
  3. * Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h> /* for getenv(), etc. (POSIX?/ANSI) */
  7. #include <string.h> /* for strncpy(), etc. (POSIX/ANSI) */
  8. #include <pwd.h> /* for getpwnam() (POSIX.1) */
  9. #include <unistd.h> /* for sysconf(), etc. (POSIX.1/.2)*/
  10. #include <errno.h>
  11. #include <sys/stat.h>
  12. #include <locale.h> /* ISO C99 */
  13. #include "sysdep.h"
  14. #include "c-mods.h"
  15. /*
  16. Expanding Unix filenames
  17. Unix Sucks
  18. Richard Kelsey Wed Jan 17 21:40:26 EST 1990
  19. Later modified by others who wish to remain anonymous
  20. Expands initial ~ and ~/ in string `name', leaving the result in `buffer'.
  21. `buffer_len' is the length of `buffer'.
  22. Note: strncpy(x, y, n) copies from y to x.
  23. */
  24. char *s48_expand_file_name (char *name, char *buffer, int buffer_len)
  25. {
  26. #define USER_NAME_SIZE 256
  27. char *dir, *p, user_name[USER_NAME_SIZE];
  28. struct passwd *user_data;
  29. int dir_len, i;
  30. int name_len = strlen(name);
  31. dir = 0;
  32. if (name[0] == '~') {
  33. name++; name_len--;
  34. if (name[0] == '/' || name[0] == 0) {
  35. dir = getenv("HOME"); }
  36. else {
  37. for (i = 0, p = name; i < name_len && *p != '/'; i++, p++)
  38. if (i > (USER_NAME_SIZE - 2)) {
  39. fprintf(stderr,
  40. "\ns48_expand_file_name: user name longer than %d characters\n",
  41. USER_NAME_SIZE - 3);
  42. return(NULL); };
  43. strncpy(user_name, name, i);
  44. user_name[i] = 0;
  45. user_data = getpwnam(user_name);
  46. if (!user_data) {
  47. fprintf(stderr, "\ns48_expand_file_name: unknown user \"%s\"\n",
  48. user_name);
  49. return(NULL); };
  50. name_len -= i;
  51. name = p;
  52. dir = user_data->pw_dir; } }
  53. else if (name[0] == '$') {
  54. name++; name_len--;
  55. for (i = 0, p = name; i < name_len && *p != '/'; i++, p++)
  56. if (i > (USER_NAME_SIZE - 2)) {
  57. fprintf(stderr,
  58. "\ns48_expand_file_name: environment variable longer than %d characters\n",
  59. USER_NAME_SIZE - 3);
  60. return(NULL); };
  61. strncpy(user_name, name, i);
  62. user_name[i] = 0;
  63. name_len -= i;
  64. name = p;
  65. dir = getenv(user_name); }
  66. if (dir) {
  67. dir_len = strlen(dir);
  68. if ((name_len + dir_len + 1) > buffer_len) {
  69. fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
  70. return(NULL); };
  71. strncpy(buffer, dir, dir_len);
  72. strncpy(buffer + dir_len, name, name_len);
  73. buffer[name_len + dir_len] = 0; }
  74. else {
  75. if ((name_len + 1) > buffer_len) {
  76. fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
  77. return(NULL); };
  78. strncpy(buffer, name, name_len);
  79. buffer[name_len] = 0; }
  80. return(buffer);
  81. }
  82. /* test routine
  83. main(argc, argv)
  84. int argc;
  85. char *argv[];
  86. {
  87. char buffer[32];
  88. s48_expand_file_name(argv[1], buffer, 32);
  89. printf("%s\n", buffer);
  90. return(0);
  91. }
  92. */
  93. /* Driver loop for tail-recursive calls */
  94. long s48_return_value;
  95. long
  96. s48_run_machine(long (*proc) (void))
  97. {
  98. while (proc != 0)
  99. proc = (long (*) (void)) (*proc)();
  100. return s48_return_value;
  101. }
  102. /* Infinities and NaNs */
  103. /* Some compilers barf when trying to evaluate 1.0/0.0 statically. */
  104. static double double_zero = 0.0;
  105. double
  106. ps_pos_infinity(void)
  107. {
  108. return 1.0 / double_zero;
  109. }
  110. double
  111. ps_neg_infinity(void)
  112. {
  113. return -1.0 / double_zero;
  114. }
  115. double
  116. ps_not_a_number(void)
  117. {
  118. return (-1.0 / double_zero) + (1.0 / double_zero);
  119. }
  120. unsigned char *
  121. ps_error_string(long the_errno)
  122. {
  123. return((unsigned char *)strerror(the_errno));
  124. }
  125. /* Getting the length of a file. */
  126. long
  127. s48_get_file_size(unsigned char *name)
  128. {
  129. struct stat file_data;
  130. int status;
  131. if (-1 == stat((char*)name, &file_data) ||
  132. ! S_ISREG(file_data.st_mode))
  133. return -1;
  134. else
  135. return file_data.st_size;
  136. }
  137. /* encoding of argv */
  138. char*
  139. s48_get_os_string_encoding(void)
  140. {
  141. static char setlocale_called = PSFALSE;
  142. char *codeset;
  143. static char* encoding = NULL;
  144. /* Mike has no clue what the rationale for needing this is. */
  145. if (!setlocale_called)
  146. {
  147. setlocale(LC_CTYPE, "");
  148. setlocale_called = PSTRUE;
  149. }
  150. if (encoding == NULL)
  151. {
  152. codeset = nl_langinfo(CODESET); /* this ain't reentrant */
  153. encoding = malloc(strlen(codeset) + 1);
  154. if (encoding == NULL)
  155. return NULL;
  156. strcpy(encoding, codeset);
  157. }
  158. return encoding;
  159. }