misc.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees.
  2. See file COPYING. */
  3. #include <stdio.h>
  4. #include <stdlib.h> /* for getenv(), etc. (POSIX?/ANSI) */
  5. #include <string.h> /* for strncpy(), etc. (POSIX/ANSI) */
  6. #include <errno.h>
  7. #include <windows.h>
  8. /*
  9. Expanding Windows filenames
  10. Windows Sucks. Unix Sucks. C Sucks.
  11. Richard Kelsey Wed Jan 17 21:40:26 EST 1990 (for the Unix version)
  12. Later rewritten by others who wish to remain anonymous.
  13. Expands ~/ in string `name', leaving the result in `buffer'.
  14. `buffer_len' is the length of `buffer'.
  15. */
  16. char *s48_expand_file_name (char *name, char *buffer, int buffer_len)
  17. {
  18. char *drive = NULL, *path = NULL, *dir = NULL;
  19. int dir_len;
  20. int name_len = strlen(name);
  21. if ((name_len >= 2) && (name[0] == '~') && ((name[1] == '\\' || (name[1] == '/'))))
  22. {
  23. drive = getenv("HOMEDRIVE");
  24. /* HOMEPATH is usually \.
  25. * I have no idea if it will have trailing \ for a subdirectory.
  26. */
  27. path = getenv("HOMEPATH");
  28. name += 1;
  29. name_len -= 2;
  30. }
  31. else if ((name_len >= 3) && (name[0] == '%'))
  32. {
  33. char *pos = strchr(name + 2, '%');
  34. if (pos)
  35. {
  36. *pos = '\0';
  37. dir = getenv(name+1);
  38. name = pos + 1;
  39. name_len -= (pos - name) + 1;
  40. }
  41. }
  42. if ((drive && path) || dir)
  43. {
  44. if (drive && path)
  45. dir_len = strlen(drive) + strlen(path);
  46. else
  47. dir_len = strlen(dir);
  48. if ((name_len + dir_len + 1) > buffer_len)
  49. {
  50. fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
  51. return(NULL);
  52. };
  53. if (drive && path)
  54. {
  55. int drive_length = strlen(drive);
  56. strcpy(buffer, drive);
  57. strcpy(buffer + drive_length, path);
  58. strcpy(buffer + dir_len, name);
  59. }
  60. else
  61. {
  62. strcpy(buffer, dir);
  63. strcpy(buffer + dir_len, name);
  64. }
  65. }
  66. else
  67. {
  68. if ((name_len + 1) > buffer_len)
  69. {
  70. fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
  71. return NULL;
  72. };
  73. strcpy(buffer, name);
  74. }
  75. return(buffer);
  76. }
  77. /* test routine */
  78. /*
  79. main(argc, argv)
  80. int argc;
  81. char *argv[];
  82. {
  83. char buffer[512];
  84. s48_expand_file_name(argv[1], buffer, 512);
  85. printf("%s\n", buffer);
  86. return(0);
  87. }
  88. /* */
  89. /* Driver loop for tail-recursive calls */
  90. long s48_return_value;
  91. long
  92. s48_run_machine(long (*proc) (void))
  93. {
  94. while (proc != 0)
  95. proc = (long (*) (void)) (*proc)();
  96. return s48_return_value;
  97. }
  98. /* Infinities and NaNs */
  99. /* Visual C++ barfs when trying to evaluate 1.0/0.0 statically. */
  100. static double double_zero = 0.0;
  101. double
  102. ps_pos_infinity(void)
  103. {
  104. return 1.0 / double_zero;
  105. }
  106. double
  107. ps_neg_infinity(void)
  108. {
  109. return -1.0 / double_zero;
  110. }
  111. double
  112. ps_not_a_number(void)
  113. {
  114. return (-1.0 / double_zero) + (1.0 / double_zero);
  115. }
  116. unsigned char *
  117. ps_error_string(long the_errno)
  118. {
  119. DWORD id = (DWORD) the_errno;
  120. #define ERROR_BUFFER_SIZE 512
  121. static WCHAR buf[ERROR_BUFFER_SIZE + 1];
  122. static char utf8[(ERROR_BUFFER_SIZE * 4) + 1];
  123. for (;;)
  124. {
  125. if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
  126. NULL, /* lpSource */
  127. id,
  128. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  129. buf, ERROR_BUFFER_SIZE,
  130. NULL)) /* arguments ... */
  131. {
  132. int count
  133. = WideCharToMultiByte(CP_UTF8,
  134. 0, /* dwFlags */
  135. buf,
  136. -1,
  137. utf8,
  138. ERROR_BUFFER_SIZE * 4 + 1,
  139. NULL, /* lpDefaultChar */
  140. NULL /* lpUsedDefaultChar */
  141. );
  142. /* get rid of annoying trailing line end */
  143. if ((count > 3) && (utf8[count-3] == 0x0d) && (utf8[count-2] == 0x0a))
  144. utf8[count-3] = '\0';
  145. return utf8;
  146. }
  147. else
  148. /* risky, but we assume some amount of sanity on the side of
  149. the Windows implementors---haha */
  150. id = GetLastError();
  151. }
  152. #undef ERROR_BUFFER_SIZE
  153. }
  154. /* Getting the length of a file. */
  155. long
  156. s48_get_file_size(unsigned char *name)
  157. {
  158. HANDLE handle = CreateFile(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  159. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  160. if (handle == INVALID_HANDLE_VALUE)
  161. return -1;
  162. {
  163. DWORD dwSize = GetFileSize(handle, NULL);
  164. CloseHandle(handle);
  165. if (dwSize == 0xFFFFFFFF)
  166. return -1;
  167. else
  168. return (long) dwSize;
  169. }
  170. }