home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mitsch75.zip / scheme-7_5_17-src.zip / scheme-7.5.17 / src / microcode / os2env.c < prev    next >
C/C++ Source or Header  |  1999-04-07  |  8KB  |  341 lines

  1. /* -*-C-*-
  2.  
  3. $Id: os2env.c,v 1.12 1999/04/07 04:01:45 cph Exp $
  4.  
  5. Copyright (c) 1994-1999 Massachusetts Institute of Technology
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or (at
  10. your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful, but
  13. WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include "scheme.h"
  23. #include "os2.h"
  24. #include "osenv.h"
  25. #include <time.h>
  26. #include <sys\types.h>
  27.  
  28. #ifdef __IBMC__
  29. #include <sys\timeb.h>
  30. #define NC_TIMEZONE _timezone
  31. #define NC_DAYLIGHT _daylight
  32. #define NC_FTIME _ftime
  33. #endif
  34.  
  35. #if defined(__WATCOMC__) || defined(__EMX__)
  36. #include <sys\timeb.h>
  37. #define NC_TIMEZONE timezone
  38. #define NC_DAYLIGHT daylight
  39. #define NC_FTIME ftime
  40. #endif
  41.  
  42. #ifdef __GCC2__
  43. #include <errno.h>
  44. #include <sys/times.h>
  45. #endif
  46.  
  47. static void initialize_real_time_clock (void);
  48. static double get_real_time_clock (void);
  49.  
  50. static void initialize_timer (void);
  51. static void timer_thread (void *);
  52. static void handle_timer_event (msg_t *);
  53.  
  54. void
  55. OS2_initialize_environment (void)
  56. {
  57.   initialize_real_time_clock ();
  58.   initialize_timer ();
  59. }
  60.  
  61. time_t
  62. OS_encoded_time (void)
  63. {
  64.   time_t t = (time (0));
  65.   if (t < 0)
  66.     OS2_error_system_call (errno, syscall_time);
  67.   return (t);
  68. }
  69.  
  70. void
  71. OS_decode_time (time_t t, struct time_structure * buffer)
  72. {
  73.   struct tm * ts = (localtime (&t));
  74.   if (ts == 0)
  75.     OS2_error_system_call (errno, syscall_localtime);
  76.   (buffer -> year) = ((ts -> tm_year) + 1900);
  77.   (buffer -> month) = ((ts -> tm_mon) + 1);
  78.   (buffer -> day) = (ts -> tm_mday);
  79.   (buffer -> hour) = (ts -> tm_hour);
  80.   (buffer -> minute) = (ts -> tm_min);
  81.   (buffer -> second) = (ts -> tm_sec);
  82.   (buffer -> daylight_savings_time) = (ts -> tm_isdst);
  83. #ifdef NC_TIMEZONE
  84.   (buffer -> time_zone) = NC_TIMEZONE;
  85. #else
  86.   (buffer -> time_zone) = INT_MAX;
  87. #endif
  88.   {
  89.     /* In localtime() encoding, 0 is Sunday; in ours, it's Monday. */
  90.     int wday = (ts -> tm_wday);
  91.     (buffer -> day_of_week) = ((wday == 0) ? 6 : (wday - 1));
  92.   }
  93. }  
  94.  
  95. void
  96. OS_decode_utc (time_t t, struct time_structure * buffer)
  97. {
  98.   struct tm * ts = (gmtime (&t));
  99.   if (ts == 0)
  100.     OS2_error_system_call (errno, syscall_gmtime);
  101.   (buffer -> year) = ((ts -> tm_year) + 1900);
  102.   (buffer -> month) = ((ts -> tm_mon) + 1);
  103.   (buffer -> day) = (ts -> tm_mday);
  104.   (buffer -> hour) = (ts -> tm_hour);
  105.   (buffer -> minute) = (ts -> tm_min);
  106.   (buffer -> second) = (ts -> tm_sec);
  107.   (buffer -> daylight_savings_time) = (ts -> tm_isdst);
  108.   (buffer -> time_zone) = 0;
  109.   {
  110.     /* In gmtime() encoding, 0 is Sunday; in ours, it's Monday. */
  111.     int wday = (ts -> tm_wday);
  112.     (buffer -> day_of_week) = ((wday == 0) ? 6 : (wday - 1));
  113.   }
  114. }  
  115.  
  116. time_t
  117. OS_encode_time (struct time_structure * buffer)
  118. {
  119.   struct tm ts;
  120.   (ts . tm_year) = ((buffer -> year) - 1900);
  121.   (ts . tm_mon) = ((buffer -> month) - 1);
  122.   (ts . tm_mday) = (buffer -> day);
  123.   (ts . tm_hour) = (buffer -> hour);
  124.   (ts . tm_min) = (buffer -> minute);
  125.   (ts . tm_sec) = (buffer -> second);
  126.   (ts . tm_isdst) = (buffer -> daylight_savings_time);
  127.   {
  128.     time_t t = (mktime (&ts));
  129.     if (t < 0)
  130.       OS2_error_system_call (errno, syscall_mktime);
  131. #ifdef NC_TIMEZONE
  132.     /* mktime assumes its argument is local time, and converts it to
  133.        UTC; if the specified time zone is different, adjust the result.  */
  134.     if (((buffer -> time_zone) != INT_MAX)
  135.     && ((buffer -> time_zone) != NC_TIMEZONE))
  136.       t = ((t - NC_TIMEZONE) + (buffer -> time_zone));
  137. #endif
  138.     return (t);
  139.   }
  140. }
  141.  
  142. long
  143. OS2_timezone (void)
  144. {
  145. #ifdef NC_TIMEZONE
  146.   return (NC_TIMEZONE);
  147. #else
  148.   return (0);
  149. #endif
  150. }
  151.  
  152. int
  153. OS2_daylight_savings_p (void)
  154. {
  155. #ifdef NC_DAYLIGHT
  156.   return (NC_DAYLIGHT);
  157. #else
  158.   return (-1);
  159. #endif
  160. }
  161.  
  162. static double initial_rtc;
  163.  
  164. static void
  165. initialize_real_time_clock (void)
  166. {
  167.   initial_rtc = (get_real_time_clock ());
  168. }
  169.  
  170. double
  171. OS_real_time_clock (void)
  172. {
  173.   return ((get_real_time_clock ()) - initial_rtc);
  174. }
  175.  
  176. static double
  177. get_real_time_clock (void)
  178. {
  179. #ifdef NC_FTIME
  180.   struct timeb rtc;
  181.   NC_FTIME (&rtc);
  182.   return ((((double) (rtc . time)) * 1000.0) + ((double) (rtc . millitm)));
  183. #endif
  184. #ifdef __GCC2__
  185.   struct tms rtc;
  186.   times (&rtc);
  187.   return (((double) (rtc . tms_utime)) * (1000.0 / ((double) CLK_TCK)));
  188. #endif
  189. }
  190.  
  191. double
  192. OS_process_clock (void)
  193. {
  194.   /* This must not signal an error in normal use. */
  195.   return (OS_real_time_clock ());
  196. }
  197.  
  198. static HEV timer_event;
  199. static int timer_handle_valid;
  200. static HTIMER timer_handle;
  201. TID OS2_timer_tid;
  202.  
  203. static void
  204. initialize_timer (void)
  205. {
  206.   timer_event = (OS2_create_event_semaphore (0, 1));
  207.   timer_handle_valid = 0;
  208.   OS2_timer_tid = (OS2_beginthread (timer_thread, 0, 0));
  209. }
  210.  
  211. static void
  212. timer_thread (void * arg)
  213. {
  214.   EXCEPTIONREGISTRATIONRECORD registration;
  215.   (void) OS2_thread_initialize ((®istration), QID_NONE);
  216.   while (1)
  217.     {
  218.       ULONG count = (OS2_reset_event_semaphore (timer_event));
  219.       while (count > 0)
  220.     {
  221.       OS2_send_message (OS2_interrupt_qid,
  222.                 (OS2_create_message (mt_timer_event)));
  223.       count -= 1;
  224.     }
  225.       (void) OS2_wait_event_semaphore (timer_event, 1);
  226.     }
  227. }
  228.  
  229. void
  230. OS_real_timer_set (clock_t first, clock_t interval)
  231. {
  232.   /* **** No support for (first != interval), but runtime system never
  233.      does that anyway.  */
  234.   OS_real_timer_clear ();
  235.   if (interval != 0)
  236.     {
  237.       STD_API_CALL (dos_start_timer, (interval,
  238.                       ((HSEM) timer_event),
  239.                       (&timer_handle)));
  240.       timer_handle_valid = 1;
  241.     }
  242.   else if (first != 0)
  243.     {
  244.       STD_API_CALL (dos_async_timer, (first,
  245.                       ((HSEM) timer_event),
  246.                       (&timer_handle)));
  247.       timer_handle_valid = 1;
  248.     }
  249. }
  250.  
  251. void
  252. OS_real_timer_clear (void)
  253. {
  254.   if (timer_handle_valid)
  255.     {
  256.       STD_API_CALL (dos_stop_timer, (timer_handle));
  257.       timer_handle_valid = 0;
  258.     }
  259.   (void) OS2_reset_event_semaphore (timer_event);
  260. }
  261.  
  262. void
  263. OS_process_timer_set (clock_t first, clock_t interval)
  264. {
  265.   OS2_error_unimplemented_primitive ();
  266. }
  267.  
  268. void
  269. OS_process_timer_clear (void)
  270. {
  271. }
  272.  
  273. void
  274. OS_profile_timer_set (clock_t first, clock_t interval)
  275. {
  276.   OS2_error_unimplemented_primitive ();
  277. }
  278.  
  279. void
  280. OS_profile_timer_clear (void)
  281. {
  282. }
  283.  
  284. static size_t current_dir_path_size = 0;
  285. static char * current_dir_path = 0;
  286.  
  287. const char *
  288. OS_working_dir_pathname (void)
  289. {
  290.   ULONG drive_number;
  291.   {
  292.     ULONG drive_map;
  293.     STD_API_CALL (dos_query_current_disk, ((&drive_number), (&drive_map)));
  294.   }
  295.   if ((current_dir_path_size == 0) || (current_dir_path == 0))
  296.     {
  297.       current_dir_path_size = 1024;
  298.       current_dir_path = (OS_malloc (current_dir_path_size));
  299.     }
  300.   while (1)
  301.     {
  302.       ULONG size = (current_dir_path_size - 3);
  303.       {
  304.     APIRET rc =
  305.       (dos_query_current_dir
  306.        (drive_number, (current_dir_path + 3), (&size)));
  307.     if (rc == NO_ERROR)
  308.       break;
  309.     if (rc != ERROR_BUFFER_OVERFLOW)
  310.       OS2_error_system_call (rc, syscall_dos_query_current_dir);
  311.       }
  312.       do
  313.     current_dir_path_size *= 2;
  314.       while ((current_dir_path_size - 3) < size);
  315.       OS_free (current_dir_path);
  316.       current_dir_path = (OS_malloc (current_dir_path_size));
  317.     }
  318.   (current_dir_path[0]) = ('a' + drive_number - 1);
  319.   (current_dir_path[1]) = ':';
  320.   (current_dir_path[2]) = '\\';
  321.   return (current_dir_path);
  322. }
  323.  
  324. void
  325. OS_set_working_dir_pathname (const char * name)
  326. {
  327.   extern char * OS2_remove_trailing_backslash (const char *);
  328.   unsigned int length;
  329.   name = (OS2_remove_trailing_backslash (name));
  330.   length = (strlen (name));
  331.   if ((length >= 2) && ((name[1]) == ':'))
  332.     {
  333.       STD_API_CALL
  334.     (dos_set_default_disk,
  335.      ((name[0]) - ((islower (name[0])) ? 'a' : 'A') + 1));
  336.       name += 2;
  337.       length -= 2;
  338.     }
  339.   STD_API_CALL (dos_set_current_dir, ((length == 0) ? "\\" : ((char *) name)));
  340. }
  341.