home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / adav313.zip / gnat-3_13p-os2-bin-20010916.zip / emx / gnatlib / a-sysdep.c < prev    next >
C/C++ Source or Header  |  2000-07-19  |  17KB  |  603 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*                         GNAT COMPILER COMPONENTS                         */
  4. /*                                                                          */
  5. /*                              A - S Y S D E P                             */
  6. /*                                                                          */
  7. /*                          C Implementation File                           */
  8. /*                                                                          */
  9. /*                            $Revision: 1.57 $
  10. /*                                                                          */
  11. /*       Copyright (C) 1992-1999-2000 Free Software Foundation, Inc.        */
  12. /*                                                                          */
  13. /* GNAT is free software;  you can  redistribute it  and/or modify it under */
  14. /* terms of the  GNU General Public License as published  by the Free Soft- */
  15. /* ware  Foundation;  either version 2,  or (at your option) any later ver- */
  16. /* sion.  GNAT is distributed in the hope that it will be useful, but WITH- */
  17. /* OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY */
  18. /* or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License */
  19. /* for  more details.  You should have  received  a copy of the GNU General */
  20. /* Public License  distributed with GNAT;  see file COPYING.  If not, write */
  21. /* to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, */
  22. /* MA 02111-1307, USA.                                                      */
  23. /*                                                                          */
  24. /* As a  special  exception,  if you  link  this file  with other  files to */
  25. /* produce an executable,  this file does not by itself cause the resulting */
  26. /* executable to be covered by the GNU General Public License. This except- */
  27. /* ion does not  however invalidate  any other reasons  why the  executable */
  28. /* file might be covered by the  GNU Public License.                        */
  29. /*                                                                          */
  30. /* GNAT was originally developed  by the GNAT team at  New York University. */
  31. /* It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). */
  32. /*                                                                          */
  33. /****************************************************************************/
  34.  
  35. /* This file contains system dependent symbols that are referenced in the
  36.    GNAT Run Time Library */
  37.  
  38. #ifdef __vxworks
  39. #include "vxWorks.h"
  40. #endif
  41.  
  42. #include "config.h"
  43. #include <fcntl.h>
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #include <errno.h>
  47. #include <stdio.h>
  48.  
  49. /*
  50.    mode_read_text
  51.    open text file for reading
  52.    rt for DOS and Windows NT, r for Unix
  53.  
  54.    mode_write_text
  55.    truncate to zero length or create text file for writing
  56.    wt for DOS and Windows NT, w for Unix
  57.  
  58.    mode_append_text
  59.    append; open or create text file for writing at end-of-file
  60.    at for DOS and Windows NT, a for Unix
  61.  
  62.    mode_read_binary
  63.    open binary file for reading
  64.    rb for DOS and Windows NT, r for Unix
  65.  
  66.    mode_write_binary
  67.    truncate to zero length or create binary file for writing
  68.    wb for DOS and Windows NT, w for Unix
  69.  
  70.    mode_append_binary
  71.    append; open or create binary file for writing at end-of-file
  72.    ab for DOS and Windows NT, a for Unix
  73.  
  74.    mode_read_text_plus
  75.    open text file for update (reading and writing)
  76.    r+t for DOS and Windows NT, r+ for Unix
  77.  
  78.    mode_write_text_plus
  79.    truncate to zero length or create text file for update
  80.    w+t for DOS and Windows NT, w+ for Unix
  81.  
  82.    mode_append_text_plus
  83.    append; open or create text file for update, writing at end-of-file
  84.    a+t for DOS and Windows NT, a+ for Unix
  85.  
  86.    mode_read_binary_plus
  87.    open binary file for update (reading and writing)
  88.    r+b for DOS and Windows NT, r+ for Unix
  89.  
  90.    mode_write_binary_plus
  91.    truncate to zero length or create binary file for update
  92.    w+b for DOS and Windows NT, w+ for Unix
  93.  
  94.    mode_append_binary_plus
  95.    append; open or create binary file for update, writing at end-of-file
  96.    a+b for DOS and Windows NT, a+ for Unix
  97.  
  98.    Notes:
  99.  
  100.    (1) Opening a file with read mode fails if the file does not exist or
  101.    cannot be read.
  102.  
  103.    (2) Opening a file with append mode causes all subsequent writes to the
  104.    file to be forced to the then current end-of-file, regardless of
  105.    intervening calls to the fseek function.
  106.  
  107.    (3) When a file is opened with update mode, both input and output may be
  108.    performed on the associated stream.  However, output may not be directly
  109.    followed by input without an intervening call to the fflush function or
  110.    to a file positioning function (fseek, fsetpos, or rewind), and input
  111.    may not be directly followed by output without an intervening call to a
  112.    file positioning function, unless the input operation encounters
  113.    end-of-file.
  114.  
  115.    The other target dependent declarations here are for the two functions
  116.    set_binary_mode and set_text_mode:
  117.  
  118.       void set_binary_mode (int handle);
  119.       void set_text_mode   (int handle);
  120.  
  121.    These functions have no effect in Unix (or similar systems where there is
  122.    no distinction between binary and text files), but in DOS (and similar
  123.    systems where text mode does CR/LF translation), these functions allow
  124.    the mode of the stream with the given handle (fileno can be used to get
  125.    the handle of a stream) to be changed dynamically. The returned result
  126.    is 0 if no error occurs and -1 if an error occurs.
  127.  
  128.    Finally there is a boolean (character) variable
  129.  
  130.       char text_translation_required;
  131.  
  132.    which is zero (false) in Unix mode, and one (true) in DOS mode, with a
  133.    true value indicating that text translation is required on text files
  134.    and that fopen supports the trailing t and b modifiers.
  135.  
  136. */
  137.  
  138. #if defined(WINNT) || defined (MSDOS) || defined (__EMX__)
  139.  
  140. const char *mode_read_text = "rt";
  141. const char *mode_write_text = "wt";
  142. const char *mode_append_text = "at";
  143. const char *mode_read_binary = "rb";
  144. const char *mode_write_binary = "wb";
  145. const char *mode_append_binary = "ab";
  146. const char *mode_read_text_plus = "r+t";
  147. const char *mode_write_text_plus = "w+t";
  148. const char *mode_append_text_plus = "a+t";
  149. const char *mode_read_binary_plus = "r+b";
  150. const char *mode_write_binary_plus = "w+b";
  151. const char *mode_append_binary_plus = "a+b";
  152. const char text_translation_required = 1;
  153.  
  154. /* For now these functions do nothing, must be fixed later??? */
  155. void
  156. set_binary_mode (handle)
  157.      int handle;
  158. {
  159. }
  160.  
  161. void
  162. set_text_mode (handle)
  163.      int handle;
  164. {
  165. }
  166.  
  167. #ifdef __MINGW32__
  168.  
  169. #include <windows.h>
  170.  
  171. /* Return the name of the tty.   Under windows there is no name for
  172.    the tty, so this function, if connected to a tty, returns the generic name
  173.    "console".  */
  174.  
  175. char *
  176. ttyname (filedes)
  177.      int filedes;
  178. {
  179.   if (isatty (filedes))
  180.     return "console";
  181.   else
  182.     return NULL;
  183. }
  184.  
  185. /* This function is needed to fix a bug under Win95/98. Under these plateforms
  186.    doing :
  187.                 ch1 = getch();
  188.         ch1 = fgetc (stdin);
  189.    will put the same character into ch1 and ch2. It seem that the character
  190.    read by getch() is not correctly removed from the buffer. Even a
  191.    fflush(stdin) does not fix the bug. This bug does not appear under Window
  192.    NT but we call winflush anyway because it would be a big overhead to test
  193.    (at runtime) each time if we are running under 95/98 or NT.
  194.  
  195.    Calling FlushConsoleInputBuffer just after getch() fix the bug.
  196.  */
  197. void 
  198. winflush (void)
  199. {
  200.   FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
  201. }
  202.  
  203. #endif
  204.  
  205. #else
  206.  
  207. const char *mode_read_text = "r";
  208. const char *mode_write_text = "w";
  209. const char *mode_append_text = "a";
  210. const char *mode_read_binary = "r";
  211. const char *mode_write_binary = "w";
  212. const char *mode_append_binary = "a";
  213. const char *mode_read_text_plus = "r+";
  214. const char *mode_write_text_plus = "w+";
  215. const char *mode_append_text_plus = "a+";
  216. const char *mode_read_binary_plus = "r+";
  217. const char *mode_write_binary_plus = "w+";
  218. const char *mode_append_binary_plus = "a+";
  219. const char text_translation_required = 0;
  220.  
  221. /* These functions do nothing in non-DOS systems. */
  222.  
  223. void
  224. set_binary_mode (stream)
  225.      FILE *stream;
  226. {
  227. }
  228.  
  229. void
  230. set_text_mode (stream)
  231.      FILE *stream;
  232. {
  233. }
  234.  
  235. #endif
  236.  
  237. #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
  238.   || (defined (__osf__) && ! defined (__alpha_vxworks)) || defined (WINNT) \
  239.   || defined (__MACHTEN__)
  240. #include <termios.h>
  241. #include <fcntl.h>
  242. #elif defined (VMS)
  243. extern char *decc$ga_stdscr;
  244. static int initted = 0;
  245. #endif
  246.  
  247. /* Implements the common processing for getc_immediate and
  248.    getc_immediate_nowait. */
  249.  
  250. void getc_immediate_common (FILE *, int *, int *, int *, int);
  251.  
  252. /* Called by Get_Immediate (Foo); */
  253.  
  254. void
  255. getc_immediate (stream, ch, end_of_file)
  256.      FILE *stream;
  257.      int *ch;
  258.      int *end_of_file;
  259. {
  260.   int avail;
  261.  
  262.   getc_immediate_common (stream, ch, end_of_file, &avail, 1);
  263. }
  264.  
  265. /* Called by Get_Immediate (Foo, Available); */
  266.  
  267. void
  268. getc_immediate_nowait (stream, ch, end_of_file, avail)
  269.      FILE *stream;
  270.      int *ch;
  271.      int *end_of_file;
  272.      int *avail;
  273. {
  274.   getc_immediate_common (stream, ch, end_of_file, avail, 0);
  275. }
  276.  
  277. /* Called by getc_immediate () and getc_immediate_nowait () */
  278.  
  279. void
  280. getc_immediate_common (stream, ch, end_of_file, avail, waiting)
  281.      FILE *stream;
  282.      int *ch;
  283.      int *end_of_file;
  284.      int *avail;
  285.      int waiting;
  286. {
  287. #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
  288.     || (defined (__osf__) && ! defined (__alpha_vxworks)) \
  289.     || defined (__CYGWIN32__) || defined (__MACHTEN__)
  290.   char c;
  291.   int nread;
  292.   int good_one = 0;
  293.   int eof_ch = 4; /* Ctrl-D */
  294.   int fd = fileno (stream);
  295.   struct termios otermios_rec, termios_rec;
  296.  
  297.   if (isatty (fd))
  298.     {
  299.       tcgetattr (fd, &termios_rec);
  300.       memcpy (&otermios_rec, &termios_rec, sizeof (struct termios));
  301.       while (! good_one)
  302.         {
  303.           /* Set RAW mode */
  304.           termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON;
  305. #if defined(sgi) || defined (sun) || defined (__EMX__) || defined (__osf__) \
  306.       || defined (linux) || defined (__MACHTEN__)
  307.           eof_ch = termios_rec.c_cc[VEOF];
  308.  
  309.           /* If waiting (i.e. Get_Immediate (Char)), set MIN = 1 and wait for
  310.              a character forever. This doesn't seem to effect Ctrl-Z or
  311.              Ctrl-C processing except on OS/2 where Ctrl-C won't work right
  312.              unless we do a read loop. Luckily we can delay a bit between
  313.              iterations. If not waiting (i.e. Get_Immediate (Char, Available)),
  314.              don't wait for anything but timeout immediately. */
  315. #ifdef __EMX__
  316.           termios_rec.c_cc[VMIN] = 0;
  317.           termios_rec.c_cc[VTIME] = waiting;
  318. #else
  319.           termios_rec.c_cc[VMIN] = waiting;
  320.           termios_rec.c_cc[VTIME] = 0;
  321. #endif
  322. #endif
  323.           tcsetattr (fd, TCSANOW, &termios_rec);
  324.  
  325.           /* Read() is used here instead of fread(), because fread() doesn't
  326.              work on Solaris5 and Sunos4 in this situation.  Maybe because we
  327.              are mixing calls that use file descriptors and streams. */
  328.  
  329.           nread = read (fd, &c, 1);
  330.           if (nread > 0)
  331.             {
  332.               /* On Unix terminals, Ctrl-D (EOT) is an End of File. */
  333.               if (c == eof_ch)
  334.                 {
  335.                   *avail = 0;
  336.                   *end_of_file = 1;
  337.                   good_one = 1;
  338.                 }
  339.  
  340.               /* Everything else is ok */
  341.               else if (c != eof_ch)
  342.                 {
  343.                   *avail = 1;
  344.                   *end_of_file = 0;
  345.                   good_one = 1;
  346.                 }
  347.             }
  348.  
  349.           else if (! waiting)
  350.             {
  351.               *avail = 0;
  352.               *end_of_file = 0;
  353.               good_one = 1;
  354.             }
  355.           else
  356.             {
  357.               good_one = 0;
  358.             }
  359.         }
  360.  
  361.       tcsetattr (fd, TCSANOW, &otermios_rec);
  362.       *ch = c;
  363.     }
  364.  
  365.   else
  366. #elif defined (VMS)
  367.   int fd = fileno (stream);
  368.  
  369.   if (isatty (fd))
  370.     {
  371.       if (initted == 0)
  372.     {
  373.       decc$bsd_initscr ();
  374.       initted = 1;
  375.     }
  376.       decc$bsd_cbreak ();
  377.       *ch = decc$bsd_wgetch (decc$ga_stdscr);
  378.  
  379.       if (*ch == 4)
  380.     *end_of_file = 1;
  381.       else
  382.     *end_of_file = 0;
  383.  
  384.       *avail = 1;
  385.       decc$bsd_nocbreak ();
  386.     }
  387.   else
  388. #elif defined (__MINGW32__)
  389.   int fd = fileno (stream);
  390.   int char_waiting;
  391.   int eot_ch = 4; /* Ctrl-D */
  392.  
  393.   if (isatty (fd))
  394.     {
  395.       if (waiting)
  396.     {
  397.       *ch = getch();
  398.       winflush(); /* see comments before winflush definition */
  399.  
  400.       if (*ch == eot_ch)
  401.         *end_of_file = 1;
  402.       else
  403.         *end_of_file = 0;
  404.  
  405.       *avail = 1;
  406.     }
  407.       else /* ! waiting */
  408.     {
  409.       char_waiting = kbhit();
  410.  
  411.       if (char_waiting == 1)
  412.         {
  413.           *avail = 1;
  414.           *ch = getch();
  415.           winflush(); /* see comments before winflush definition */
  416.  
  417.           if (*ch == eot_ch)
  418.         *end_of_file = 1;
  419.           else
  420.         *end_of_file = 0;
  421.         }
  422.       else
  423.         {
  424.           *avail = 0;
  425.           *end_of_file = 0;
  426.         }
  427.     }
  428.     }
  429.   else
  430. #endif
  431.     {
  432.       /* If we're not on a terminal, then we don't need any fancy processing.
  433.      Also this is the only thing that's left if we're not on one of the
  434.      supported systems. */
  435.       *ch = fgetc (stream);
  436.       if (feof (stream))
  437.         {
  438.           *end_of_file = 1;
  439.           *avail = 0;
  440.         }
  441.       else
  442.         {
  443.           *end_of_file = 0;
  444.           *avail = 1;
  445.         }
  446.     }
  447. }
  448.  
  449. /* The following definitions are provided in NT to support Windows based
  450.    Ada programs.  */
  451.  
  452. #ifdef WINNT
  453. #include <windows.h>
  454.  
  455. /* Provide functions to echo the values passed to WinMain (windows bindings
  456.    will want to import these).  We use the same names as the routines used
  457.    by AdaMagic for compatibility.  */
  458.  
  459. char *rts_get_hInstance     (void) { return (GetModuleHandleA (0)); }
  460. char *rts_get_hPrevInstance (void) { return (0); }
  461. char *rts_get_lpCommandLine (void) { return (GetCommandLineA ()); }
  462. int   rts_get_nShowCmd      (void) { return (1); }
  463.  
  464. #endif /* WINNT */
  465.  
  466. #ifdef VMS
  467.  
  468. /* This gets around a problem with using the old threads library on VMS 7.0. */
  469.  
  470. #include <time.h>
  471. long
  472. get_gmtoff ()
  473. {
  474.   time_t t;
  475.   struct tm *ts;
  476.  
  477.   t = time ((time_t) 0);
  478.   ts = localtime (&t);
  479.   return ts->tm_gmtoff;
  480. }
  481. #endif
  482.  
  483. /* Definition of __gnat_locatime_r used by a-calend.adb */
  484.  
  485. #if defined (_AIX) || defined (__EMX__)
  486. #include <string.h>
  487. #include <time.h>
  488.  
  489. #define Lock_Task system__soft_links__lock_task
  490. extern void (*Lock_Task) (void);
  491.  
  492. #define Unlock_Task system__soft_links__unlock_task
  493. extern void (*Unlock_Task) (void);
  494.  
  495. /* Provide reentrant version of localtime on Aix and OS/2. Note that AiX does
  496.    provide localtime_r, but in the library libc_r which doesn't get included
  497.    systematically, so we can't use it. */
  498.  
  499. struct tm *
  500. __gnat_localtime_r (const time_t *timer, struct tm *tp)
  501. {
  502.   struct tm *tmp;
  503.  
  504.   (*Lock_Task) ();
  505.   tmp = localtime (timer);
  506.   memcpy (tp, tmp, sizeof (struct tm));
  507.   (*Unlock_Task) ();
  508.   return tp;
  509. }
  510.  
  511. #elif defined (__Lynx__)
  512.  
  513. #include <time.h>
  514.  
  515. /* LynxOS provides a non standard localtime_r */
  516.  
  517. struct tm *
  518. __gnat_localtime_r (const time_t *timer, struct tm *tp)
  519. {
  520.   return localtime_r (tp, timer);
  521. }
  522.  
  523. #elif defined (VMS) || defined (__MINGW32__)
  524.  
  525. /* __gnat_localtime_r is not needed on NT and VMS */
  526.  
  527. #else
  528. #include <time.h>
  529.  
  530. /* All other targets provide a standard localtime_r */
  531.  
  532. struct tm *
  533. __gnat_localtime_r (const time_t *timer, struct tm *tp)
  534. {
  535.   return (struct tm *)localtime_r (timer, tp);
  536. }
  537. #endif
  538.  
  539. #if 0
  540. #if defined(_X86_) && defined(__MINGW32__)
  541. /* this could be used by other x86 OS like OS/2, Linux, Solaris x86 */
  542.  
  543. /* The following code is a speed up for Long_Long_Integer arithmetic.
  544.  
  545.    This method based on using the FPU387 for operators "/" and "rem" under
  546.    64-bit integers. Normally GCC library use the long and few slower integer
  547.    register based functions __divdi3 and __moddi3.
  548.  
  549.    This code is from Dmitriy Anisimkov
  550.  
  551.    It speed-up by a factor of 2 the "/" and "rem" */
  552.  
  553. /* division of integer_64 
  554.    80387 FPU based */
  555.  
  556. asm (".globl I387_Div_cwchop");
  557. asm (".data");
  558. asm (".align 2");
  559. asm ("I387_Div_cwchop: .word 0x1F32");
  560. asm (".text");
  561. asm (".align 2");
  562. asm (".globl ___divdi3");
  563. asm ("___divdi3:");
  564. asm ("   pushl %ebp");
  565. asm ("   movl %esp,%ebp");
  566. asm ("   subl $4,%esp");
  567. asm ("   fildq 8(%ebp)");
  568. asm ("   fildq 16(%ebp)");
  569. asm ("   fstcw (%esp)");
  570. asm ("   fldcw I387_Div_cwchop");
  571. asm ("   fdivp %st(1),%st");
  572. asm ("   fistpq 8(%ebp)");
  573. asm ("   fldcw (%esp)");
  574. asm ("   fwait");
  575. asm ("   movl 8(%ebp),%eax");
  576. asm ("   movl 12(%ebp),%edx");
  577. asm ("   addl $4,%esp");
  578. asm ("   leave");
  579. asm ("   ret");
  580.  
  581. /* remainder from division of integer_64
  582.    80387 FPU based */
  583. asm (".text");
  584. asm (".align 2");
  585. asm (".globl ___moddi3");
  586. asm ("___moddi3:");
  587. asm ("   pushl %ebp");
  588. asm ("   movl %esp,%ebp");
  589. asm ("   fildq 16(%ebp)");
  590. asm ("   fildq 8(%ebp)");
  591. asm ("   fprem");
  592. asm ("   fstp %st(1);");
  593. asm ("   fistpq 8(%ebp)");
  594. asm ("   fwait");
  595. asm ("   movl 8(%ebp),%eax");
  596. asm ("   movl 12(%ebp),%edx");
  597. asm ("   leave");
  598. asm ("   ret");
  599.  
  600. #endif
  601. #endif
  602.  
  603.