sysmac.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* sysmac.c Copyright (C) 1989-92 Codemist Ltd */
  2. /*
  3. * Macintosh system-specific stuff
  4. */
  5. /* Signature: 6546de39 07-Mar-2000 */
  6. #include "machine.h"
  7. #include <stdarg.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include "tags.h"
  12. #include "externs.h"
  13. #include <sysequ.h>
  14. #include <unix.h>
  15. #include <files.h>
  16. #include <unix.h>
  17. #include <retrace.h>
  18. #include <timer.h>
  19. #undef nil /* #define'd by Think C headers but not wanted (by me) */
  20. static void get_home_directory(char *b, int length);
  21. static void get_users_home_directory(char *b, int length);
  22. #include "filename.c"
  23. /*
  24. * This is a dummy definition of get_truename, here so that everything
  25. * will link. Both the calling convention used here and the exact
  26. * meaning and implementation may be under gentle review!
  27. */
  28. char *get_truename(char *filename, char *old, size_t n)
  29. {
  30. char *w;
  31. process_file_name(filename, old, n);
  32. if (*filename == 0)
  33. { aerror("truename");
  34. return NULL;
  35. }
  36. w = (char *)malloc(1+strlen(filename));
  37. if (w == NULL) return w;
  38. strcpy(w, filename);
  39. return w;
  40. }
  41. char *my_getenv(char *s)
  42. {
  43. return getenv(s);
  44. }
  45. int my_system(char *s)
  46. {
  47. return 0; /* Not available - sorry! */
  48. }
  49. static void get_home_directory(char *b, int length)
  50. {
  51. char *w = my_getenv("home");
  52. if (w != NULL) strcpy(b, w);
  53. else
  54. strcpy(b, ":"); /* Not satisfactory */
  55. }
  56. static void get_users_home_directory(char *b, int length)
  57. {
  58. char *w, h[LONGEST_LEGAL_FILENAME];
  59. sprintf(h, "home$%s", b);
  60. w = my_getenv(h);
  61. if (w != NULL) strcpy(b, w);
  62. else
  63. strcpy(b, ":"); /* Not satisfactory */
  64. }
  65. int batchp()
  66. {
  67. return !isatty(fileno(stdin));
  68. }
  69. /*
  70. * The next procedure is responsible for establishing information about
  71. * where the main checkpoint image should be recovered from, and where
  72. * and fasl files should come from.
  73. */
  74. char *find_image_directory(int argc, char *argv[])
  75. {
  76. char image[LONGEST_LEGAL_FILENAME];
  77. char pgmname[LONGEST_LEGAL_FILENAME];
  78. char *w;
  79. /*
  80. * For the Macintosh I use the data fork of the application image as
  81. * a place to store useful stuff.
  82. */
  83. WDPBRec pb1;
  84. CInfoPBRec pb2;
  85. int i, j, r, p = LONGEST_LEGAL_FILENAME;
  86. long id;
  87. pgmname[--p] = 0;
  88. sprintf(image, "%#s", CurApName); /* name of current application */
  89. strcpy(image, program_name);
  90. i = strlen(image);
  91. p -= i;
  92. memcpy(&pgmname[p], image, i); /* copy to the end of a buffer */
  93. pb1.ioNamePtr = (unsigned char *)image;
  94. PBHGetVolSync(&pb1); /* find current working dir & volume */
  95. id = pb1.ioWDDirID; /* working directory identifier */
  96. while (id != 0)
  97. { pb2.dirInfo.ioFDirIndex = -1; /* use directory ID, not file name/index */
  98. pb2.dirInfo.ioVRefNum = pb1.ioVRefNum; /* look in this volume */
  99. pb2.dirInfo.ioDrDirID = id; /* get info about this directory */
  100. pb2.dirInfo.ioNamePtr = (unsigned char *)image;
  101. r = PBGetCatInfoSync(&pb2); /* Read catalogue - find name & parent */
  102. if (r != 0) break; /* failed - must be at top of tree */
  103. id = pb2.dirInfo.ioDrParID; /* go on up to parent directory */
  104. i = image[0] & 0xff; /* length of name of this directory */
  105. pgmname[--p] = ':';
  106. p -= i;
  107. if (p < 10)
  108. { fprintf(stderr, "\nPlease re-install this package nearer the top of\n");
  109. fprintf(stderr, "your directory hierarchy. It will not work this far down\n");
  110. abort();
  111. }
  112. memcpy(&pgmname[p], &image[1], i); /* stick names together with ':'s */
  113. }
  114. strcpy(image, &pgmname[p]); /* Put complete name in convenient place */
  115. /*
  116. * I copy from local vectors into malloc'd space to hand my
  117. * answer back.
  118. */
  119. w = (char *)malloc(1+strlen(image));
  120. /*
  121. * The error exit here seem unsatisfactory...
  122. */
  123. if (w == NULL)
  124. { fprintf(stderr, "\n+++ Panic - run out of space\n");
  125. exit(EXIT_FAILURE);
  126. }
  127. strcpy(w, image);
  128. return w;
  129. }
  130. int truncate_file(FILE *f, long int where)
  131. {
  132. if (fflush(f) != 0) return 1;
  133. return SetEOF(fileno(f), where); /* Returns zero if successs */
  134. }
  135. #ifdef TICK_STREAM
  136. void accept_tick(void)
  137. {
  138. /*
  139. * This is where I can put things that need to be done regularly.
  140. * This will need to involve prodding the window manager etc etc.
  141. * At present I do NOTHING...
  142. */
  143. return;
  144. }
  145. #ifdef USE_VBL
  146. static VBLTask VBL_control_block;
  147. static pascal void deal_with_tick(void)
  148. {
  149. /*
  150. * This way of recovering register a5 was OK before the multi-finder,
  151. * but is UNSATISFACTORY now. It is proper to use the time manager
  152. * instead of VBL, but only recent versions of the time manager are any good
  153. * so it is a bit of a mess.
  154. */
  155. asm { move.l a5, -(sp)
  156. movea.l CurrentA5, a5 }
  157. VBL_control_block.vblCount = 5;
  158. if (tick_pending == 0)
  159. {
  160. if (already_in_gc) tick_on_gc_exit = YES;
  161. else
  162. { Lisp_Object nil = C_nil;
  163. CSLbool xxx = NO;
  164. if (exception_pending()) flip_exception(), xxx = YES;
  165. tick_pending = YES;
  166. saveheaplimit = heaplimit;
  167. heaplimit = fringe;
  168. savevheaplimit = vheaplimit;
  169. vheaplimit = vfringe;
  170. savecodelimit = codelimit;
  171. codelimit = codefringe;
  172. savestacklimit = stacklimit;
  173. stacklimit = stackbase;
  174. if (xxx) flip_exception();
  175. }
  176. }
  177. asm { movea.l (sp)+, a5 }
  178. return;
  179. }
  180. void remove_ticker(void)
  181. {
  182. VRemove((QElemPtr)&VBL_control_block);
  183. }
  184. void add_ticker(void)
  185. {
  186. VBL_control_block.qType = vType;
  187. VBL_control_block.vblAddr = deal_with_tick;
  188. VBL_control_block.vblCount = 1;
  189. VBL_control_block.vblPhase = 0;
  190. VInstall((QElemPtr)&VBL_control_block);
  191. }
  192. #else /* USE_VBL */
  193. typedef struct xTMTask
  194. {
  195. struct TMTask a;
  196. long int a5save;
  197. } xTMTask;
  198. static pascal void do_tick(void)
  199. {
  200. QElemPtr w;
  201. long int savea5;
  202. asm { move.l a5, savea5
  203. move.l offsetof(xTMTask, a5save)(a1), a5
  204. move.l a1, w }
  205. if (tick_pending == 0)
  206. {
  207. if (already_in_gc) tick_on_gc_exit = YES;
  208. else
  209. { Lisp_Object nil = C_nil;
  210. CSLbool xxx = NO;
  211. if (exception_pending()) flip_exception(), xxx = YES;
  212. tick_pending = YES;
  213. saveheaplimit = heaplimit;
  214. heaplimit = fringe;
  215. savevheaplimit = vheaplimit;
  216. vheaplimit = vfringe;
  217. savecodelimit = codelimit;
  218. codelimit = codefringe;
  219. savestacklimit = stacklimit;
  220. stacklimit = stackbase;
  221. if (xxx) flip_exception();
  222. }
  223. }
  224. PrimeTime(w, 1000);
  225. asm { move.l savea5, a5 }
  226. return;
  227. }
  228. static xTMTask ticker;
  229. void remove_ticker(void)
  230. {
  231. RmvTime((QElemPtr)&ticker);
  232. }
  233. void add_ticker()
  234. {
  235. ticker.a.tmAddr = do_tick;
  236. ticker.a.tmCount = 0;
  237. ticker.a.tmWakeUp = 0;
  238. ticker.a.tmReserved = 0;
  239. asm { move.l a5,ticker.a5save }
  240. InsTime((QElemPtr) &ticker);
  241. PrimeTime((QElemPtr) &ticker, 1000);
  242. }
  243. #endif /* USE_VBL */
  244. #endif /* TICK_STREAM */
  245. /* end of sysmac.c */