home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / EDITOR / MG2A_SRC.ZIP / SYS / ATARI / MISC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-23  |  6.0 KB  |  284 lines

  1. /* misc.c -- Miscellaneous ST-specific code for MG.
  2.  *
  3.  * author :  Sandra Loosemore
  4.  * date   :  24 Oct 1987
  5.  * changes:  Marion Hakanson -- Jan 1988
  6.  *
  7.  */
  8.  
  9.  
  10. #include    "..\..\def.h"
  11.  
  12. #ifdef MWC
  13. static char *
  14. mwc_cpr="Portions of this program, copyright 1984, Mark Williams Co.";
  15. #endif /* MWC */
  16.  
  17.  
  18. /* Exit as quickly as possible.  */
  19.  
  20. VOID panic (s)
  21.     char* s;
  22. {   Cconws (s);
  23.     Pterm (-1);
  24.     }
  25.  
  26.  
  27. #ifdef MWC
  28. extern char **environ;
  29. #else
  30. typedef struct
  31.     {
  32.     char    *p_lowtpa;
  33.     char    *p_hitpa;
  34.     char    *p_tbase;
  35.     long    p_tlen;
  36.     char    *p_dbase;
  37.     long    p_dlen;
  38.     char    *p_bbase;
  39.     long    p_blen;
  40.     char    *p_dta;
  41.     char    *p_parent;
  42.     char    *p_reserved;
  43.     char    *p_env;
  44.     long    p_undefined[20];
  45.     char    p_cmdlin[128];
  46.     }
  47.     BASEPAGE;
  48.  
  49. extern BASEPAGE *_base;
  50. #endif /* MWC */
  51.  
  52.  
  53. /*
  54.  * The environment code here is borrowed from Dale Schumacher.
  55.  */
  56.  
  57. static char *findenv(var)
  58.     register char *var;
  59. /*
  60.  *    INTERNAL FUNCTION.  This functions attempts to locate <var> in
  61.  *    the environment.  If <var> is not found, NULL is returned.  If
  62.  *    the environment is NULL, NULL is returned.  If <var> is found,
  63.  *    a pointer to the beginning of <var> in the environment is returned.
  64.  *    BOTH MS-DOS AND TOS ENVIRONMENT FORMATS ARE ACCOMODATED.
  65.  */
  66.     {
  67.     register char *p;
  68.     register int len;
  69.  
  70. #ifdef MWC
  71.     if((p = *environ) == NULL)
  72. #else
  73.     if((p = _base->p_env) == NULL)
  74. #endif /* MWC */
  75.         return(NULL);
  76.     len = strlen(var);
  77.     while(*p)
  78.         {
  79.         if(!strncmp(p, var, len) && (p[len] == '='))
  80.             return(p);
  81.         while(*p++)        /* move to next arg */
  82.             ;
  83.         }
  84.     return(NULL);
  85.     }
  86.  
  87.  
  88. char *getenv(var)
  89.     register char *var;
  90. /*
  91.  *    Search for <var> in the environment.  If <var> is found, a pointer
  92.  *    to it's value is returned.  NULL is returned if <var> is not found.
  93.  *    WARNING:  The returned pointer points into the environment and
  94.  *    must not be modified!
  95.  */
  96.     {
  97.     register char *p, *q;
  98.     register int len;
  99.  
  100.     len = strlen(var);
  101.     if(p = findenv(var))
  102.         {
  103.         p += (len + 1);
  104.         if(*p == '\0')        /* TOS env format or empty value */
  105.             {
  106.             q = p+1;
  107.             if(*q == '\0')        /* empty value + end of env */
  108.                 return(p);
  109.             while(*q && (*q != '='))
  110.                 ++q;
  111.             if(*q)            /* empty value */
  112.                 return(p);
  113.             else            /* TOS env format */
  114.                 return(p+1);
  115.             }
  116.         }
  117.     return(p);
  118.     }
  119.  
  120.  
  121. /* Spawn a command.  You can run anything from this; it prompts you for
  122.  *    the command to run.
  123.  * I check for the two most common problems with Pexec:  not finding the
  124.  *    file, and not having enough memory.  Otherwise, I assume bad status
  125.  *    codes were the fault of the program, not Pexec, and that the program
  126.  *    would have told the user what is wrong.
  127.  */
  128.  
  129. spawncli(f, n)
  130. {   register int s;
  131.     char fname[NFILEN];
  132.     char tail[NFILEN];
  133.     char *shell = getenv("SHELL");
  134.     extern VOID splitcmd();
  135.    
  136.     if (shell && *shell) {
  137.         (VOID) strcpy(fname, shell);
  138.         goto tryit;
  139.     }
  140.     else
  141.         shell = NULL;
  142.     
  143. askfor:
  144.     if ((s = ereply("Run program: ", fname, NFILEN)) != TRUE)
  145.         return (s);
  146. tryit:
  147.     ttcolor (CTEXT);
  148.     ttmove (nrow-1, 0);
  149.     tteeol ();
  150.     splitcmd (fname, tail);
  151.     ttclose ();
  152.     s = Pexec(0, fname, tail, 0L);
  153.     ttopen ();
  154.     if (s == -33) {
  155.         if (shell) {
  156.         shell = NULL;
  157.             ewprintf ("Could not find shell.");
  158.             sleep(1);
  159.             goto askfor;
  160.         }
  161.         ewprintf ("Could not find file.");
  162.         return (FALSE);
  163.     }
  164.     else if (s == -39) {
  165.         if (shell) {
  166.         shell = NULL;
  167.             ewprintf ("Not enough memory to run shell!");
  168.             sleep(1);
  169.             goto askfor;
  170.         }
  171.         ewprintf ("Not enough memory to run this program!");
  172.         return (FALSE);
  173.     }
  174.     else {
  175.         sgarbf = TRUE;          /* Force repaint */
  176.         Cconws ("Hit any key to return to MG:");
  177.         (VOID) Crawcin ();
  178.         return (TRUE);
  179.         }
  180. }
  181.  
  182.  
  183. /* Pexec wants the command tail to have a byte count as the first
  184.  *    character.  This function separates the program name from the command
  185.  *    tail and adds the byte count.
  186.  */
  187.  
  188. static VOID splitcmd (cmd, tail)
  189.     char* cmd;
  190.     char* tail;
  191. {   int i, j;
  192.     i = 0;
  193.     j = 0;
  194.     while (cmd[i] != '\0') {
  195.         if (j != 0)  { 
  196.         tail[j] = cmd[i]; 
  197.         j++;
  198.             }
  199.         else if (cmd[i] == ' ')  {
  200.             cmd[i] = '\0';
  201.             tail[1] = ' ';
  202.             j = 2;
  203.         }
  204.         i++;
  205.         }
  206.     if (j == 0)  {
  207.         tail[0] = (char) 1;
  208.         tail[1] = ' ';
  209.         tail[2] = '\0';
  210.         }
  211.     else {
  212.         tail[j+1] = '\0';
  213.         tail[0] = (char) (j-1);
  214.         }
  215.     }
  216.  
  217.  
  218.  
  219.  
  220. /*
  221.  * copy 'count' bytes from 'src' to 'dst'. (optimized)
  222.  */
  223. VOID bcopy(src, dst, count)
  224. register char *src, *dst;
  225. register count;
  226. {
  227.     register c1;
  228.  
  229.     /*
  230.     ** The magic number 8 comes from:
  231.     **   1   max. bytes before a word boundary
  232.     **   4   min. bytes in a block of long-words
  233.     **   3   max. bytes after the last long-word in the block
  234.     */
  235.     if (count >= 8) {
  236.         /*
  237.         ** Advance dst pointer to word boundary.
  238.         */
  239.         if (1 & (short)dst) {
  240.             *dst++ = *src++;
  241.                 count--;
  242.     }
  243.         /*
  244.         ** If src pointer is (also) aligned, use long-word copy.
  245.         */
  246.         if ((1 & (short)src) == 0) {
  247.             c1 = ((unsigned)count >> 2);
  248.             while (--c1 >= 0)
  249.                 *((long *)dst)++ = *((long *)src)++;
  250.             count &= 3;        /* There are 0,1,2, or 3 bytes left */
  251.         }
  252.     }
  253.     /*
  254.     ** Copy whatever is left.
  255.     */
  256.     while (--count >= 0)
  257.     *dst++ = *src++;
  258. }
  259.  
  260. /* Busy waiting to fake out sleep.  Thanks to Rich Sansom for the routine
  261.  *    to poll the system clock.
  262.  */
  263.  
  264. static long *hz_200 = (long *)0x000004ba;    /* system 200 hz clock        */
  265.  
  266. #ifdef NO_DPROMPT
  267. static long read200hz()
  268. #else
  269. long read200hz()
  270. #endif /* NO_DPROMPT */
  271. {   return(*hz_200);
  272.     }
  273.  
  274.  
  275. /* Sleep (busily) for n seconds */
  276.  
  277. sleep (n)
  278.     int n;
  279. {   register long waitfor = (n * 200) + Supexec(read200hz);
  280.  
  281.     while (Supexec(read200hz) < waitfor);
  282.     }
  283.  
  284.