home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume21 / mced / part01 / main.c < prev    next >
C/C++ Source or Header  |  1991-08-09  |  7KB  |  385 lines

  1. /* 
  2.  * This software is Copyright (c) 1991 by Andy Knight
  3.  *
  4.  * Permission is hereby granted to copy, distribute or otherwise
  5.  * use any part of this package as long as you do not try to make 
  6.  * money from it or pretend that you wrote it.  This copyright 
  7.  * notice must be maintained in any copy made. 
  8.  * 
  9.  * Use of this software constitutes acceptance for use in an AS IS 
  10.  * condition. There are NO warranties with regard to this software. 
  11.  * In no event shall the author be liable for any damages whatsoever 
  12.  * arising out of or in connection with the use or performance of this 
  13.  * software.  Any use of this software is at the user's own risk. 
  14.  * 
  15.  * If you make modifications to this software that you feel 
  16.  * increases it usefulness for the rest of the community, please 
  17.  * email the changes, enhancements, bug fixes as well as any and 
  18.  * all ideas to me. This software is going to be maintained and 
  19.  * enhanced as deemed necessary by the community.   
  20.  * 
  21.  *              Andy Knight 
  22.  *              aknight@ourgang.prime.com 
  23.  */
  24.  
  25. #include "config.h"
  26.  
  27. char hfile[20], cfile[20];
  28. char vern[] = "#";
  29. char spc[] = " ";
  30. char prompt[] = "%McEd% ";
  31. char *hist[MAX_H_READ], cstr[MAX_CH], sstr[30];
  32. int edit_mode, x_pos, savex_pos, xend, cur_cmd, last_hline, xbeg = 7;
  33. int index_cmd();
  34. FILE *fptr;
  35. SIGTYPE die_curses(), die_normal();
  36. WINDOW *win;
  37. void my_wmove(), eat_white(), add_hline(), cmd_to_win(), win_to_cmd();
  38. void my_waddstr(), my_winsch(), my_wdelch(), case_lower(), case_upper();
  39. void edit_line(), openrd(), openwr();
  40.  
  41. #ifdef SYSVcurses
  42.     struct termio tio, tin;
  43. #else
  44.     struct tchars tco, tcn;
  45. #endif
  46.  
  47.  
  48. main(argc, argv)
  49. int argc;
  50. char *argv[];
  51. {
  52.     register i;
  53.     int slen, pid;
  54.     unsigned msize;
  55.  
  56.     signal(SIGINT,die_normal);      /* die cleanly */
  57. /*
  58.  * get the shell process id (pid) to match $$ in the = alias
  59.  */
  60.  
  61.     pid = getppid();
  62.     sprintf(hfile,"/tmp/eh%d",pid);
  63.     sprintf(cfile,"/tmp/ec%d",pid);
  64.     openrd(hfile);
  65. /*
  66.  * read the history lines into the hist[] array,
  67.  * previous mced invocation commands (ie. "=")are not copied, once
  68.  * the command is read into cstr the newline is replaced with '\0'
  69.  * and then it is copied into hist[last_hline]
  70.  */
  71.     for (last_hline = 0; fgets(cstr, (MAX_CH), fptr) != NULL;)
  72.     {
  73.         if (cstr[0] != '=') /* "=" must be used in the alias for this to work*/
  74.     {
  75.         slen = strlen(cstr);
  76.         if (slen > MIN_CMD_LEN)
  77.         {
  78.             msize = (unsigned) (slen * sizeof(char));
  79.             cstr[slen - 1] = '\0';
  80.         hist[last_hline] = (char *) malloc(msize);
  81.         strcpy(hist[last_hline], cstr);
  82.         ++last_hline;
  83.         }
  84.     }
  85.     }
  86.     --last_hline;
  87.     cur_cmd = last_hline;
  88. /*
  89.  * close and delete history temp file
  90.  */
  91.     fclose(fptr);
  92.     unlink(hfile);
  93.  
  94. /*
  95.  * check for existence of history before going on
  96.  */
  97.     if (last_hline < 0)
  98.     {
  99.     fprintf(stderr,"No valid history\n");
  100.     die_normal();
  101.     }
  102.  
  103. /*
  104.  * copy search string from command line
  105.  */
  106.     if (argc > 1)
  107.     {
  108.     strcpy(sstr, argv[1]);
  109.     if (argc > 2)
  110.     {
  111.         for (i = 3; i <= argc; i++)
  112.         {
  113.         strcat(sstr, spc);
  114.         strcat(sstr, argv[i - 1]);
  115.         }
  116.     }
  117.     cur_cmd = index_cmd(cur_cmd,-1);
  118.     }
  119.     strcpy(cstr, hist[cur_cmd]);
  120. /*
  121.  * edit command and execute
  122.  */
  123.     edit_cmd();
  124.     openwr(cfile);
  125.     fprintf(fptr, "%s\n", vern);
  126.     fprintf(fptr, "%s\n", cstr);
  127.     fclose(fptr);
  128.     printf("\n");
  129. }
  130.  
  131.  
  132. int index_cmd(tcur_cmd,direc)
  133. int tcur_cmd, direc;
  134. {
  135.     register i, slen;
  136.     slen = strlen(sstr);
  137.     for (i = 0; i <= last_hline; i++)
  138.     {
  139.     if (tcur_cmd < 0) tcur_cmd = last_hline;
  140.     if (tcur_cmd > last_hline) tcur_cmd = 0;
  141.     if (strncmp(hist[tcur_cmd], sstr, slen) == 0)
  142.         return(tcur_cmd);
  143.     tcur_cmd += direc;
  144.     }
  145.     return(cur_cmd);
  146. }
  147.  
  148.  
  149. void openrd(fname)
  150. char fname[];
  151. {
  152.     int fd;
  153.     fd = open(fname, 0);
  154.     if (fd == (int) -1)
  155.     {
  156.     perror(fname);
  157.     fprintf(stderr,"To execute mced use \"=\" with the following alias:\n");
  158.     fprintf(stderr,"alias = \"history -h 50 >\\! /tmp/eh$$;mced \\!*;");
  159.     fprintf(stderr,"source -h /tmp/ec$$;source /tmp/ec$$;/bin/rm /tmp/ec$$\"\n");
  160.     die_normal();
  161.     }
  162.     else
  163.     {
  164.     close(fd);
  165.     fptr = fopen(fname, "r");
  166.     }
  167. }
  168.  
  169.  
  170. void openwr(fname)
  171. char fname[];
  172. {
  173.     if ((fptr = fopen(fname, "w")) == NULL)
  174.     {
  175.     perror(fname);
  176.     exit(0);
  177.     }
  178. }
  179.  
  180.  
  181. SIGTYPE die_normal()
  182. {
  183.     signal(SIGINT,SIG_IGN);
  184.     signal(SIGINT,die_normal);
  185.     openwr(cfile);
  186.     fprintf(fptr, "%s\n", vern);
  187.     fclose(fptr);
  188.     exit(0);
  189. }
  190.  
  191.  
  192. void add_hline()    /*add next hist line on delete at EOL*/
  193. {
  194.     if(cur_cmd < last_hline)
  195.     {
  196.     ++cur_cmd;
  197.     savex_pos = x_pos;
  198.     my_waddstr(hist[cur_cmd]);    
  199.     x_pos = savex_pos;
  200.     my_wmove(x_pos);
  201.     }
  202.     else
  203.     beep();
  204. }
  205.  
  206.  
  207. void my_wmove(i)
  208. int i;
  209. {
  210.     int which_line;
  211.     which_line = ((i < COLS) ? 0 : 1);
  212.     wmove(win,which_line,(i - which_line * COLS));
  213. }
  214.  
  215.  
  216. void my_winsch(in_char)
  217. int in_char;
  218. {
  219.     int wrap_char;
  220.     if ((xend + 1) >= (COLS * 2))
  221.     {
  222.     beep();
  223.     }
  224.     else if(xend > COLS && x_pos < COLS)    /* wraparound */
  225.     {
  226.     ++xend;
  227.     wmove(win,0,COLS-1);
  228.     wrap_char = winch(win);
  229.     wmove(win,1,0);
  230.     winsch(win,wrap_char);
  231.     my_wmove(x_pos);
  232.     winsch(win,in_char);
  233.     my_wmove(++x_pos);
  234.     }
  235.     else
  236.     {
  237.     ++xend;
  238.     winsch(win,in_char);
  239.     my_wmove(++x_pos);
  240.     }
  241. }
  242.  
  243.  
  244. void my_wdelch()
  245. {
  246.     int wrap_char;
  247.     --xend;
  248.     if(xend >= COLS && x_pos < COLS)    /* wraparound */
  249.     {
  250.     wmove(win,1,0);
  251.     wrap_char = winch(win);
  252.     wdelch(win);
  253.     my_wmove(x_pos);
  254.     wdelch(win);
  255.     wmove(win,0,COLS-1);
  256.     winsch(win,wrap_char);
  257.     my_wmove(x_pos);
  258.     }
  259.     else
  260.     {
  261.     wdelch(win);
  262.     }
  263. }
  264.  
  265.  
  266. void my_waddstr(strng)
  267. char strng[];
  268. {
  269.     register i, len;
  270.     len = strlen(strng);
  271.     for(i=0;i < len;i++)
  272.     {
  273.     my_winsch((int)strng[i]);
  274.     }
  275. }
  276.  
  277.  
  278. void cmd_to_win()    /*write prompt and command to window*/
  279. {
  280.     my_wmove(0);
  281.     wclear(win);
  282.     waddstr(win,prompt);
  283.     xend = x_pos = xbeg;
  284.     my_waddstr(cstr);
  285. }
  286.  
  287.  
  288. void win_to_cmd()    /*get the edited line from the window*/
  289. {
  290.     int i;
  291.     my_wmove(xbeg);
  292.     for(i=0;i <= (xend - xbeg);i++)
  293.     {
  294.     my_wmove(xbeg+i);
  295.     cstr[i] = winch(win);
  296.     }
  297.     cstr[xend - xbeg] = '\0';
  298. }
  299.  
  300.  
  301. void case_upper()
  302. {
  303.     int i;
  304.     for(i=0;i <= (xend - xbeg);i++)
  305.     {
  306.     if(islower(cstr[i]))
  307.         cstr[i] = toupper(cstr[i]);
  308.     }
  309. }
  310.  
  311.  
  312. void case_lower()
  313. {
  314.     int i;
  315.     for(i=0;i <= (xend - xbeg);i++)
  316.     {
  317.     if(isupper(cstr[i]))
  318.         cstr[i] = tolower(cstr[i]);
  319.     }
  320. }
  321.  
  322.  
  323. SIGTYPE die_curses()    /* interrupt signal */
  324. {
  325.     signal(SIGINT,SIG_IGN);
  326.     signal(SIGINT,die_curses);
  327. #ifdef SYSVcurses 
  328.     if(ioctl(0, TCSETA, &tio) != 0)
  329.     perror("ioctl");
  330. #else 
  331.     if(ioctl(0, TIOCSETC, &tco) != 0)
  332.     perror("ioctl");
  333. #endif
  334.     nocbreak();
  335.     echo();
  336.     endwin();
  337.     openwr(cfile);
  338.     fprintf(fptr, "%s\n", vern);
  339.     fclose(fptr);
  340.     printf("\n");
  341.     exit(0);
  342. }
  343.  
  344.  
  345. void eat_white(direc,destruc)    /*eat up initial whitespace*/
  346. int direc,destruc;
  347. {
  348.     int lim;
  349.     if(direc == -1) 
  350.     lim = xbeg;
  351.     else
  352.     lim = xend;
  353.     if(destruc == NO)
  354.     {
  355.     for(;isspace(winch(win));)
  356.     {
  357.         if(x_pos != lim)
  358.         {
  359.         x_pos += direc;
  360.         my_wmove(x_pos);
  361.         }
  362.         else
  363.         return;
  364.     }
  365.     return;
  366.     }
  367.     else    /* actually delete */
  368.     {
  369.     for(;isspace(winch(win));)
  370.     {
  371.         if(x_pos != lim)
  372.         {
  373.         my_wdelch();
  374.         x_pos += direc;
  375.         my_wmove(x_pos);
  376.         if(!(isspace(winch(win))) && direc == 1)
  377.             my_wmove(--x_pos);
  378.         }
  379.         else
  380.         return;
  381.     }
  382.     return;
  383.     }
  384. }
  385.