home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / sysdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  12.2 KB  |  609 lines

  1. /*
  2.  *  Copyright (c) 1992, 1994 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5.  
  6. /*  This file is the interface to system specific files */
  7.  
  8. #ifdef AIX
  9. #define _ALL_SOURCE
  10. #define POSIX
  11. #endif
  12.  
  13. #ifdef POSIX
  14. #ifndef _POSIX_SOURCE
  15. #define _POSIX_SOURCE
  16. #endif
  17. #endif
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21.  
  22. #define USING_INPUT_BUFFER
  23. #define DONE_WITH_INPUT_BUFFER
  24.  
  25. #include "config.h"
  26. #include "buffer.h"
  27. #include "sysdep.h"
  28. #include "display.h"
  29. #include "file.h"
  30. #include "screen.h"
  31. #include "misc.h"
  32. #include "slang.h"
  33. #include "hooks.h"
  34.  
  35. /* These are hooks for porting to other systems */
  36.  
  37. int (*X_Read_Hook) (void);
  38. int (*X_Input_Pending_Hook) (void);
  39. void (*X_Get_Term_Size_Hook)(int *, int *);
  40. int (*X_Init_Term_Hook) (void);
  41. void (*X_Reset_Term_Hook) (void);
  42.  
  43. extern char *get_cwd(void);
  44. static int sys_input_pending(int *);
  45.  
  46. int Ignore_User_Abort = 1;           /* Abort char triggers S-Lang error */
  47.  
  48. unsigned char KeyBoard_Xlate[256] = 
  49. {
  50.    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
  51.  21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 
  52.  40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 
  53.  59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 
  54.  78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 
  55.  97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 
  56.  113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 
  57.  128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 
  58.  143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
  59.  158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
  60.  173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
  61.  188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
  62.  203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217,
  63.  218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
  64.  233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
  65.  248, 249, 250, 251, 252, 253, 254, 255
  66. };
  67.  
  68. #if defined   (msdos)
  69. #  define SLASH_CHAR '\\'
  70. #if !defined(__WATCOMC__)
  71. #  include    "ibmpc.c"
  72. #else
  73. #  include    "i386.c"
  74. #endif
  75. #else
  76. # if defined (__os2__)
  77. #    define SLASH_CHAR '\\'
  78. #    include "os2.c"
  79. # else
  80. #    if defined (VMS)
  81. #      define SLASH_CHAR ']'
  82. #      include "vms.c"
  83. #    else
  84. #      if defined (__GO32__)
  85. #        define SLASH_CHAR '\\'
  86. #        include "i386.c"
  87. #      else
  88. #        if defined (unix)
  89. #          define SLASH_CHAR '/'
  90. #          include "unix.c"
  91. #        endif
  92. #      endif
  93. #    endif
  94. # endif
  95. #endif
  96.  
  97. int Input_Buffer_Len = 0;
  98. unsigned char Input_Buffer[MAX_INPUT_BUFFER_LEN];
  99.  
  100. void map_character(int *fromp, int *top)
  101. {
  102.    int from = *fromp, to = *top;
  103.    if ((from > 255) || (to > 255) || (from < 0) || (to < 0)) return;
  104.    KeyBoard_Xlate[from] = to;
  105. }
  106.  
  107.  
  108. /* if input char arrives with hi bit set, it is replaced by 2 characters:
  109.  *   Meta_Char + char with hi bit off.  If Meta_Char is -1, then return 
  110.  * full 8 bits which self inserts */
  111.       
  112. /* By default, 8 bit chars self insert. */     
  113. int Meta_Char = -1;
  114. #if !defined(pc_system)
  115. int DEC_8Bit_Hack = 64;
  116. #else
  117. int DEC_8Bit_Hack = 0;
  118. #endif
  119.  
  120. int my_getkey()
  121. {
  122.    char buf[10];
  123.    int i, imax;
  124.    unsigned char ch;
  125.    
  126.    if (Batch)
  127.      {
  128.     fgets(buf, 9 ,stdin);
  129.     return (int) *buf;
  130.      }
  131.    
  132.    if (!Input_Buffer_Len)
  133.      {
  134.     /* if (Batch) ch = (unsigned char) getc(stdin); else ch = sys_getkey(); */
  135.     ch = (unsigned char) KeyBoard_Xlate[sys_getkey()];
  136.     if (ch & 0x80)
  137.       {
  138.          i = (ch & 0x7F);
  139.          if ((i < ' ') && DEC_8Bit_Hack)
  140.            {
  141.           i += DEC_8Bit_Hack;
  142.           ungetkey((int *) &i);
  143.           ch = 27;
  144.            }
  145.          else if (Meta_Char != -1)
  146.            {
  147.           ungetkey((int *) &i);
  148.           ch = Meta_Char;               /* escape char */
  149.            }
  150.       }
  151.     return((int) ch);
  152.      }
  153.    
  154.    ch = Input_Buffer[0];
  155.    if ((ch & 0x80) && ((Meta_Char != -1) || ((ch < 160) && DEC_8Bit_Hack)))
  156.      {
  157.     ch = (ch & 0x7F);
  158.     if ((ch < ' ') && DEC_8Bit_Hack) 
  159.       {
  160.          ch += DEC_8Bit_Hack;
  161.          i = 27;
  162.       }
  163.     else i = Meta_Char;
  164.  
  165.     Input_Buffer[0] = ch;
  166.     return ((int) (unsigned int) i);
  167.      }
  168.  
  169.    USING_INPUT_BUFFER
  170.    
  171.    Input_Buffer_Len--;
  172.    imax = Input_Buffer_Len;
  173.    
  174.    MEMCPY ((char *) Input_Buffer, (char *) (Input_Buffer + 1), imax);
  175.  
  176.    DONE_WITH_INPUT_BUFFER
  177.    
  178.    return((int) ch);
  179. }
  180.  
  181.  
  182. void ungetkey_string(char *s, int n)
  183. {
  184.    /* int i; */
  185.    register unsigned char *bmax, *b, *b1;
  186.    if (n + Input_Buffer_Len > MAX_INPUT_BUFFER_LEN - 3) return;
  187.  
  188.    USING_INPUT_BUFFER
  189.    
  190.    b = Input_Buffer;
  191.    bmax = b + (Input_Buffer_Len - 1);
  192.    b1 = bmax + n;
  193.    while (bmax >= b) *b1-- = *bmax--;
  194.    bmax = b + n;
  195.    while (b < bmax) *b++ = (unsigned char) *s++;
  196.    Input_Buffer_Len += n;
  197.    
  198.    DONE_WITH_INPUT_BUFFER
  199. }
  200.  
  201. void buffer_keystring(char *s, int n)
  202. {
  203.    if (n + Input_Buffer_Len > MAX_INPUT_BUFFER_LEN - 3) return;
  204.    
  205.    USING_INPUT_BUFFER
  206.    MEMCPY ((char *) Input_Buffer + Input_Buffer_Len, s, n);
  207.    Input_Buffer_Len += n;
  208.    DONE_WITH_INPUT_BUFFER
  209. }
  210.  
  211. void ungetkey(int *ci)
  212. {
  213.    char ch;
  214.    ch = (char) *ci;
  215.    ungetkey_string(&ch, 1);
  216. }
  217.  
  218. int input_pending (int *tsecs)
  219. {
  220.    int n;
  221.    int c;
  222.    
  223.    if (Input_Buffer_Len) return Input_Buffer_Len;
  224.    
  225.    n = sys_input_pending (tsecs);
  226.    if (n)
  227.      {
  228.     c = my_getkey ();
  229.     ungetkey (&c);
  230.      }
  231.    return n;
  232. }
  233.  
  234.  
  235. void flush_input()
  236. {
  237.    int quit = SLKeyBoard_Quit;
  238.    Input_Buffer_Len = 0;
  239.    SLKeyBoard_Quit = 0;
  240. #ifdef msdos
  241.    while (input_pending(&Number_Zero)) if (!my_getkey()) my_getkey();
  242. #else
  243. #ifdef __os2__
  244.    sys_flush_input();
  245. #endif
  246.    while (input_pending(&Number_Zero)) my_getkey();
  247. #endif
  248.    SLKeyBoard_Quit = quit;
  249. }
  250.  
  251. #include <time.h>
  252.  
  253. unsigned long sys_time(void)
  254. {
  255.    return((unsigned long) time((time_t *) 0));
  256. }
  257.  
  258. char *get_time()
  259. {
  260.     char *the_time;
  261. #ifndef __GO32__
  262.     time_t clock;
  263.  
  264.     clock = time((time_t *) 0);
  265.     the_time = (char *) ctime(&clock);
  266. #else
  267.    the_time = djgpp_current_time ();
  268. #endif
  269.    /* returns the form Sun Sep 16 01:03:52 1985\n\0 */
  270.    the_time[24] = '\0';
  271.    return(the_time);
  272. }
  273.  
  274. char *slash2slash(char *dir)
  275. {
  276. #ifndef VMS
  277.    register char *p = dir, ch;
  278.    
  279.    while ((ch = *p) != 0)
  280.      {
  281.     if ((ch == '/') || (ch == '\\')) *p = SLASH_CHAR;
  282.           p++;
  283.      }
  284. #endif 
  285.    return(dir);
  286. }
  287.  
  288. /* given a canonical filename, return pointer to its name */
  289. char *extract_file(char *file)
  290. {
  291.    char *f;
  292.    
  293.    f = file + strlen(file);
  294.    while ( f-- > file) if (*f == SLASH_CHAR) return f + 1;
  295.    return(file);
  296. }
  297.  
  298.  
  299. #ifndef VMS
  300. /* this routine returns a Static pointer which is considered volatile */
  301. char *expand_filename(char *file)
  302. {
  303.    register char *p;
  304.    char  *last, *p1;
  305. #if defined (pc_system)
  306.    static char work[256];
  307. #else
  308.    static char work[500];
  309. #endif
  310.  
  311.    *work = 0;
  312.    /* the following combinations indicate non-relative path names:
  313.     *    "//"    path from the root dir
  314.     *    "~/"    path from the $HOME dir
  315.     * for dos, os2 only
  316.     *   "x:/"    path from "x:/" dir
  317.     *   "x:"    same as "x:/"
  318.     */
  319.    p = slash2slash(file) + strlen(file);
  320.    while (p > file) {
  321.       if ( *p == SLASH_CHAR ) {
  322.      if ( *(p-1) == SLASH_CHAR ) {   /* "//" combination */
  323.         strcpy(work, p);
  324.         file = work;
  325.         break;
  326.      } else if ( *(p-1) == '~' ) { /* "~/" combination */
  327.         if ( (p1 = getenv("HOME")) == NULL) p1 = "/";
  328.         strcpy( work, p1 );
  329.         p1 = slash2slash(work) + strlen(work);
  330.         if ( *(--p1) == SLASH_CHAR ) *p1 = '\0';
  331.         strcat( work, p );
  332.         for (file = work; *file & (*file != SLASH_CHAR); file++ ); /* nil */
  333.         break;
  334.      }
  335. #if defined (pc_system)               /* DOS, OS/2 stuff */
  336.       } else if ( *p == ':' ) {           /* "c:" or "c:/" combination */
  337.      strcpy( work, (p-1) );
  338.      file = (work+2);           /* start file past the drive spec */
  339.      p++;
  340.      if ( *p != SLASH_CHAR ) {           /* "c:" combination */
  341.         strcpy( file, "\\");
  342.         strcat( work, p );
  343.      }
  344.      break;
  345. #endif /* pc_system */
  346.       }
  347.       p--;
  348.    }
  349.    
  350.    if ( *work == '\0' ) {           /* no special combinations */
  351.       if ( *file != SLASH_CHAR ) {
  352.      strcpy(work, get_cwd());      /* assume relative dir */
  353.      slash2slash(work);
  354.       }
  355.       strcat(work, file);
  356.       file = work;
  357.    }
  358.  
  359.    /* remove ../ and ./ stuff */
  360.  
  361.    p = last = file;
  362.    while (*p != 0) 
  363.      {
  364.     if ( *p == SLASH_CHAR ) last = p;
  365.     else if ( *p == '.' ) 
  366.       {
  367.          p++;
  368.          if ( *p == '.' ) 
  369.            {
  370.           p++;
  371.           if ( *p == SLASH_CHAR ) 
  372.             {
  373.                while ((last > file) && (*(--last) != SLASH_CHAR))
  374.                     ;/* find parent dir */
  375.            
  376.                p1 = last;
  377.                while ( *p )  *(p1++) = *(p++);
  378.                *p1 = 0;
  379.                p = last;
  380.             }
  381.            } 
  382.          else if ( *p == SLASH_CHAR )  
  383.            {
  384.           p1 = last;
  385.           while ( *p )  *(p1++) = *(p++);
  386.           *p1 = 0;
  387.           p = last;
  388.            }
  389.          else if (*p == 0) break;
  390.       }
  391.     p++;
  392.      }
  393.    
  394.    return(work);
  395. }
  396.  
  397. #endif /* ! VMS */
  398.  
  399. #ifdef sequent
  400. char *my_strstr(char *a, char *b)
  401. {
  402.    register char *bb, *aa, *amax;
  403.    
  404.    if (*b == 0) return(a);
  405.    
  406.    bb = b; while (*bb) bb++;
  407.    aa = a; while (*aa++);
  408.    
  409.    amax = aa - (bb - b);
  410.    
  411.    while (a < amax)
  412.      {
  413.     bb = b;
  414.     while ((a < amax) && (*a != *bb)) a++;
  415.     if (a == amax) return((char *) NULL);
  416.     
  417.     aa = a;
  418.     while (*aa && (*aa == *bb)) aa++, bb++;
  419.     if (! *bb) return(a);
  420.    
  421.     a++;
  422.      }
  423.    return((char *) NULL);
  424. }
  425.  
  426. #endif
  427.  
  428.  
  429. void deslash(char *dir)
  430. {
  431. #ifndef VMS
  432.    int n;
  433.  
  434.    if ((n = strlen(dir)) > 1) {
  435.       n--;
  436. #if defined (pc_system)
  437.       if ( (dir[n] == '\\' || dir[n] == '/') && dir[n - 1] != ':' ) 
  438.           dir[n] = '\0';
  439. #else
  440.       if ( dir[n] == '/' )
  441.           dir[n] = '\0';      
  442. #endif
  443.    }
  444. #endif /* !VMS */
  445. }
  446.  
  447. /* add trailing slash to dir */
  448. void fixup_dir(char *dir)
  449. {
  450. #ifndef VMS
  451.    int n;
  452.  
  453.    if ((n = strlen(dir)) > 1) 
  454.      {
  455.     n--;
  456. #if defined(pc_system) 
  457.       if ( dir[n] != '/' && dir[n] != '\\' ) 
  458.           strcat(dir, "\\" );
  459. #else
  460.       if ( dir[n] != '/' ) 
  461.           strcat(dir, "/" );
  462. #endif
  463.      }
  464. #endif /* !VMS */
  465. }
  466.  
  467. int make_directory(char *path)
  468. {
  469.    char work[256];
  470.    
  471.    strcpy(work, path);
  472.    
  473.    deslash(work);
  474.  
  475. #if defined (msdos) || (defined (__os2__) && !defined (__EMX__))
  476.    return !mkdir(work);
  477. #else
  478.    return !mkdir(work, 0777);
  479. #endif
  480. }
  481.  
  482. int delete_directory(char *path)
  483. {
  484.    char work[256];
  485.    
  486.    strcpy(work, path);
  487.    deslash(work);
  488.    return !rmdir(work);
  489. }
  490.  
  491.  /* ch_dir routine added during OS/2 port in order to
  492.     simplify script writing. */
  493.  
  494. int ch_dir(char *path)
  495. {
  496. #if defined(pc_system) || defined(__os2__)
  497.    char work[256];
  498.   
  499.    strcpy(work, path);
  500.    deslash(work);
  501.    return chdir(work);
  502. #else   
  503.    return chdir(path);
  504. #endif
  505. }
  506.  
  507. /* generate a random number */
  508. int make_random_number(int *seed, int *max)
  509. {
  510.    if (*seed == -1)               /* generate seed */
  511.      {
  512. #ifndef unix
  513.     srand((unsigned int)(time(0) & getpid()));
  514. #else
  515. #if defined(_HPUX_SOURCE) || defined(SYSV)
  516.         srand48((int)(time(0) & getpid()));
  517. #else
  518. #ifndef HAS_RANDOM
  519.     srand((unsigned int)(time(0) & getpid()));
  520. #else
  521.         srandom((int)(time(0) & getpid()));
  522. #endif
  523. #endif   
  524. #endif   
  525.      }
  526.    else if (*seed != 0)
  527.      {
  528. #ifndef unix
  529.     srand(*seed);
  530. #else
  531. #ifdef _HPUX_SOURCE
  532.         srand48(*seed);
  533. #else
  534. #ifndef HAS_RANDOM
  535.     srand(*seed);
  536. #else
  537.         srandom(*seed);
  538. #endif
  539. #endif   
  540. #endif   
  541.      }
  542.  
  543. #ifndef unix
  544.    return (int) rand() % *max;
  545. #else
  546. #ifdef _HPUX_SOURCE
  547.    return (int) lrand48() % *max;
  548. #else
  549. #ifndef HAS_RANDOM
  550.    return (int) rand () % *max;
  551. #else
  552.    return (int) random() % *max;
  553. #endif
  554. #endif
  555. #endif   
  556. }
  557.  
  558. #ifndef __GO32__
  559. #ifdef unix
  560. /* if non-zero, Flow control is enabled */
  561. void enable_flow_control(int *mode)
  562. {
  563.    /* This kills X windows.  For the time being, work around it as follows */
  564.    if (X_Init_Term_Hook != NULL) return;
  565.    Flow_Control = *mode;
  566.    reset_tty();
  567.    init_tty();
  568. }
  569. #endif
  570. #endif
  571.  
  572. #if defined(pc_system)
  573.  
  574. /* This routine converts  C:\  --> C:\ and C:\subdir\  -> C:\subdir */
  575. char *msdos_pinhead_fix_dir(char *f)
  576. {
  577.    static char file[256];
  578.    register char ch;
  579.    int n;
  580.    
  581.    if (*f == 0) return f;
  582.    strncpy (file, f, 255); file[255] = 0;
  583.    f = file;
  584.    /* skip past colon */
  585.    while (((ch = *f) != 0) && (ch != ':')) f++;
  586.    
  587.    if (ch == 0)                   /* no colon */
  588.      {
  589.     n = (int) (f - file);
  590.     f = file;
  591.      }
  592.    else
  593.      {
  594.     f++;
  595.     n = strlen (f);
  596.      }
  597.    if (n == 0) 
  598.      {
  599.     *f++ = '\\'; *f = 0;
  600.     return file;
  601.      }
  602.    if ((n == 1) && (*f == '\\')) return file;
  603.    
  604.    f += n - 1;
  605.    if (*f == '\\') *f = 0;
  606.    return file;
  607. }
  608. #endif
  609.