home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / xc-4.1 / part01 / xcsubs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-13  |  7.0 KB  |  426 lines

  1. /*    xcsubs.c -- subroutines for XC
  2.     This file uses 4-character tabstops
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <sys/types.h>
  8. #include <sys/times.h>
  9. #include <sys/param.h>
  10. #include <sys/stat.h>
  11. #include <ctype.h>
  12. #include <signal.h>
  13. #include <termio.h>
  14. #ifdef T6000
  15. #include <sys/ioctl.h>
  16. #endif
  17. #include <setjmp.h>
  18. #include "xc.h"
  19.  
  20. extern jmp_buf erret;
  21.  
  22. char line[SM_BUFF],    /* Input line */
  23.      word[SM_BUFF],    /* Parsed word */
  24.      *wptr, *lptr,    /* Word and line pointers */
  25.      *tgetstr(), *tgoto();
  26. int    LI,    /* One less than screen length in termcap entry */
  27.     CO;    /* Screen width */
  28. short ospeed;
  29. static char tc[LG_BUFF],    /* termcap buffer */
  30.             tbuf[LG_BUFF], PC, *CD, *CE, *CF, *CL, *CM, *CN, *SO, *SE;
  31.  
  32. void show();
  33.  
  34. #define Tgetstr(code) ((s = tgetstr(code,&p)) ? s : "")
  35.  
  36. #if    !STRSTR        /* For those that do not have strstr() */
  37. /*    Find first occurence of str2 in str1 and return a pointer to it */
  38. char *
  39. strstr(str1, str2)
  40. char *str1, *str2;
  41. {
  42.     register char *Sptr, *Tptr;
  43.     int len = strlen(str1) -strlen(str2) + 1;
  44.  
  45.     if (*str2)
  46.         for (; len > 0; len--, str1++){
  47.             if (*str1 != *str2)
  48.                 continue;
  49.  
  50.             for (Sptr = str1, Tptr = str2; *Tptr != '\0'; Sptr++, Tptr++)
  51.                 if (*Sptr != *Tptr)
  52.                     break;
  53.  
  54.             if (*Tptr == '\0')
  55.                 return str1;
  56.         }
  57.  
  58.     return NIL(char);
  59. }
  60. #endif
  61.  
  62. #if !DUP2        /* For those that do not have dup2() */
  63. #include <fcntl.h>
  64. dup2(oldfd, newfd)
  65. int oldfd, newfd;
  66. {
  67.     if (fcntl(oldfd, F_GETFL, 0) == -1)        /* Valid file descriptor? */
  68.         return (-1);                        /* No, return an error */
  69.     close(newfd);                            /* Ensure newfd is closed */
  70.     return (fcntl(oldfd, F_DUPFD, newfd));    /* Dup oldfd into newfd */
  71. }
  72. #endif /* !DUP2    Thanks to Bill Allie CIS: 76703,2061 */
  73.  
  74. #if !STRDUP    /* For those that do not have strdup() */
  75. char *
  76. strdup(s)
  77. char *s;
  78. { return strcpy((char *)malloc(strlen(s)+1), s); }
  79. #endif
  80.  
  81. #if !MEMSET        /* For those that do not have memset() */
  82. char *
  83. memset(dst, chr, len)
  84. char *dst;
  85. register chr, len;
  86. {
  87.     char *d;
  88.     for (d = dst; --len >= 0; *d++ = chr)
  89.         ;
  90.     return dst;
  91. }
  92. #endif
  93.  
  94. void
  95. msecs(t)
  96. long t;
  97. {
  98.     long start;
  99.     struct tms Tbuf;
  100.  
  101.     start = times(&Tbuf);
  102.     while ((times(&Tbuf)-start) < (t*HZ)/1000)
  103.         ;
  104. }
  105.  
  106. /*    Do the fork call, packaging the error return so that the caller
  107.     need not have code for it.
  108. */
  109. forkem()
  110. {
  111.     int i;
  112.  
  113.     if ((i = fork()) < 0){
  114.         S1("XC: Fork failed");
  115.         longjmp(erret,1);
  116.     }
  117.     return i;
  118. }
  119.  
  120. /*    Throw away all input characters until no more are sent. */
  121. void 
  122. purge(void) { while (readbyte(1) != -1) ; }
  123.  
  124. /*    Line input routine to be used when the raw terminal mode is in effect. */
  125. void 
  126. getline()
  127. {
  128.     int c, i = 0;
  129.     char *ptr;
  130.  
  131.     lptr = line;
  132.     memset(line, 0, SM_BUFF);
  133.  
  134.     while ((c = getchar()) != '\r' && c != '\n'){
  135.         if (c == BS){
  136.             if (i > 0){
  137.                 ptr = unctrl(line[--i]);
  138.                 line[i] = '\0';
  139.                 while (*ptr++ != '\0')
  140.                     fputs("\b \b",tfp);
  141.             } else
  142.                 beep();
  143.             continue;
  144.         }
  145.         if (c == LK){
  146.             while (i > 0){
  147.                 ptr = unctrl(line[--i]);
  148.                 while (*ptr++ != '\0')
  149.                     fputs("\b \b",tfp);
  150.             }
  151.             memset(line, 0, SM_BUFF);
  152.             continue;
  153.         }
  154.         if (c == ('v' & 0x1f))
  155.             c = getchar();
  156.  
  157.         line[i++] = c;
  158.         fputs(unctrl(c), tfp);
  159.     }
  160. }
  161.  
  162. /*    Parse the "line" array for a word */
  163. void 
  164. getword()
  165. {
  166.     char quote, *ptr = word;
  167.     short carat = FALSE, backslash = FALSE;
  168.  
  169.     wptr = lptr;
  170.     memset(word, 0, SM_BUFF);
  171.  
  172.     while (isspace(*lptr))
  173.         lptr++;
  174.  
  175.     if (*lptr == '\0')
  176.         return;
  177.  
  178.     if (*lptr == '\'' || *lptr == '\"')
  179.         quote = *lptr++;
  180.     else
  181.         quote = '\0';
  182.  
  183.     for (; *lptr != '\0'; lptr++){
  184.         if (quote){
  185.             if (*lptr == '\0'){
  186.                 word[0] = '\0';
  187.                 sprintf(Msg,"Unmatched quote: %s", line);
  188.                 S;
  189.                 s_exit();
  190.             }
  191.             if (*lptr == quote)
  192.                 break;
  193.         } else if (!backslash && isspace(*lptr))
  194.             break;
  195.  
  196.         if (carat)
  197.             *ptr++ = *lptr & 0x1f,
  198.             carat = FALSE;
  199.         else if (backslash)
  200.             *ptr++ = *lptr,
  201.             backslash = FALSE;
  202.         else if (*lptr == '^')
  203.             carat = TRUE;
  204.         else if (*lptr == '\\')
  205.             backslash = TRUE;
  206.         else
  207.             *ptr++ = *lptr;
  208.     }
  209.  
  210.     lptr++;
  211. }
  212.  
  213. /*    Make the specified word all lower case */
  214. void 
  215. lc_word(ptr)
  216. char *ptr;
  217. {
  218.     while (*ptr){
  219.         *ptr = tolower(*ptr);
  220.         ptr++;
  221.     }
  222. }
  223.  
  224. /*    Make the specified word all upper case */
  225. void uc_word(ptr)
  226. char *ptr;
  227. {
  228.     while (*ptr){
  229.         *ptr = toupper(*ptr);
  230.         ptr++;
  231.     }
  232. }
  233.  
  234. void 
  235. mode(flag)
  236. int flag;
  237. {
  238.     if (flag == NEWMODE)
  239.         ioctl(0, TCSETAF, &newmode);
  240.     else if (flag == SIGMODE)
  241.         ioctl(0, TCSETAF, &sigmode);
  242.     else if (flag == OLDMODE)
  243.         ioctl(0, TCSETAF, &oldmode);
  244. }
  245.  
  246. beep()
  247. {
  248.     putc(7,tfp);
  249.     return SUCCESS;
  250. }
  251.  
  252. /*    initialize termcap stuff */
  253. void 
  254. get_ttype()
  255. {
  256.     char *ttytype;
  257.     char *p = tbuf;
  258.     char *s;
  259.  
  260.     if (!(ttytype = getenv("TERM"))){
  261.         S1("TERM not set");
  262.         exit(6);
  263.     }
  264.     if (tgetent(tc, ttytype) != 1){
  265.         sprintf(Msg,"Can't load %s", ttytype);
  266.         S;
  267.         exit(7);
  268.     }
  269.     ospeed = newmode.c_cflag & CBAUD;
  270.     LI = tgetnum("li") - 1;
  271.     CO = tgetnum("co");
  272.     if (!(s=Tgetstr("pc")))
  273.         PC = '\0';
  274.     else
  275.         PC = *s;
  276.     
  277.     CD = Tgetstr("cd");
  278.     CE = Tgetstr("ce");
  279.     CL = Tgetstr("cl");
  280.     CM = Tgetstr("cm");
  281.     SE = Tgetstr("se");
  282.     SO = Tgetstr("so");
  283.     CF = Tgetstr("CF");
  284.     CN = Tgetstr("CN");
  285.     if (CF && ! CN)
  286.         CN = Tgetstr("CO");
  287. }
  288.  
  289. /*    putchr() is a routine to pass to tputs() */
  290. void
  291. putchr(int c) { putc(c,tfp); }
  292.  
  293. void
  294. cls(void) { tputs(CL,LI,putchr); }
  295.  
  296. void
  297. cur_on(void) { tputs(CN,1,putchr); }
  298.  
  299. void
  300. cur_off(void) { tputs(CF,1,putchr); }
  301.  
  302. void
  303. cl_line(void) { tputs(CE,1,putchr); }
  304.  
  305. void
  306. cl_end(void) { tputs(CD,LI,putchr); }
  307.  
  308. void 
  309. ttgoto(int row, int col) { tputs(tgoto(CM, col, row),1,putchr); }
  310.  
  311. void 
  312. drawline(row, col, len)
  313. int row, col, len;
  314. {
  315.  
  316.     ttgoto(row, col);
  317.     while (len--)
  318.         fputc('-', tfp);
  319. }
  320.  
  321. void 
  322. show(flag, str)
  323. short flag;
  324. char *str;
  325. {
  326.     if (!flag){
  327.         beep();
  328.         ttgoto(LI,0),
  329.         cl_line(),
  330.         ttgoto(LI,(CO-strlen(str))/2 -1);
  331.     }
  332.     if (flag == 2)
  333.         putc('\n',tfp),
  334.         putc('\r',tfp);
  335.     tputs(SO,1,putchr);
  336.     putc(' ',tfp);
  337.     fputs(str, tfp);
  338.     putc(' ',tfp);
  339.     tputs(SE,1,putchr);
  340.     if (flag > 0)
  341.         putc('\n',tfp),
  342.         putc('\r',tfp);
  343. }
  344.  
  345. void 
  346. show_abort(void) { S2("USER ABORT"); }
  347.  
  348. FILE *
  349. isregfile(pathname)
  350. char *pathname;
  351. {
  352.     struct stat statbuf;
  353.  
  354.     if (stat(pathname,&statbuf) || (statbuf.st_mode & S_IFMT) != S_IFREG)
  355.         return NIL(FILE);
  356.     return fopen(pathname, "r");
  357. }
  358.  
  359.  
  360. FILE *
  361. openfile(name)
  362. char *name;
  363. {
  364.     FILE *fp = NIL(FILE);
  365.     char *home, fullname[SM_BUFF], *path, *pathend;
  366.     int pathlen;
  367.  
  368.     if ((path = getenv("XC_PATH"))){
  369.         while (!fp){
  370.             if (!(pathend = strchr(path, ':')))
  371.                 pathlen = strlen(path);
  372.             else
  373.                 pathlen = pathend - path;
  374.  
  375.             sprintf(fullname, "%.*s/%s", pathlen, path, name);
  376.             fp = isregfile(fullname);
  377.  
  378.             path += pathlen;
  379.             if (*path == '\0')
  380.                 break;
  381.             path++;
  382.         }
  383.     }
  384.  
  385.     if (!fp)
  386.         fp = isregfile(name);
  387.     
  388.     if (!fp){
  389.         if ((home = getenv("HOME")))
  390.             sprintf(fullname, "%s/%s", home, name);
  391.         fp = isregfile(fullname);
  392.     }
  393.  
  394.     if (!fp){
  395.         sprintf(fullname, "%s/%s", LIBDIR, name);
  396.         fp = isregfile(fullname);
  397.     }
  398.  
  399.     return fp;
  400. }
  401.  
  402. /*    Translate the character specified by 'c' to its ASCII display name.
  403.     Note:    This routine is specific to the ASCII character set.
  404. */
  405. char *
  406. unctrl(c)
  407. int c;
  408. {
  409.     static char buffer[3], buf1[2];
  410.  
  411.     memset(buffer, 0, 3);
  412.     memset(buf1, 0, 2);
  413.  
  414.     if (c == 0x7f)
  415.         strcpy(buffer, "^?");
  416.     else {
  417.         if (iscntrl(c))
  418.             strcpy(buffer, "^"),
  419.             c += '@';
  420.         buf1[0] = c;
  421.         strcat(buffer, buf1);
  422.     }
  423.  
  424.     return buffer;
  425. }
  426.