home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume21
/
mced
/
part01
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-09
|
7KB
|
385 lines
/*
* This software is Copyright (c) 1991 by Andy Knight
*
* Permission is hereby granted to copy, distribute or otherwise
* use any part of this package as long as you do not try to make
* money from it or pretend that you wrote it. This copyright
* notice must be maintained in any copy made.
*
* Use of this software constitutes acceptance for use in an AS IS
* condition. There are NO warranties with regard to this software.
* In no event shall the author be liable for any damages whatsoever
* arising out of or in connection with the use or performance of this
* software. Any use of this software is at the user's own risk.
*
* If you make modifications to this software that you feel
* increases it usefulness for the rest of the community, please
* email the changes, enhancements, bug fixes as well as any and
* all ideas to me. This software is going to be maintained and
* enhanced as deemed necessary by the community.
*
* Andy Knight
* aknight@ourgang.prime.com
*/
#include "config.h"
char hfile[20], cfile[20];
char vern[] = "#";
char spc[] = " ";
char prompt[] = "%McEd% ";
char *hist[MAX_H_READ], cstr[MAX_CH], sstr[30];
int edit_mode, x_pos, savex_pos, xend, cur_cmd, last_hline, xbeg = 7;
int index_cmd();
FILE *fptr;
SIGTYPE die_curses(), die_normal();
WINDOW *win;
void my_wmove(), eat_white(), add_hline(), cmd_to_win(), win_to_cmd();
void my_waddstr(), my_winsch(), my_wdelch(), case_lower(), case_upper();
void edit_line(), openrd(), openwr();
#ifdef SYSVcurses
struct termio tio, tin;
#else
struct tchars tco, tcn;
#endif
main(argc, argv)
int argc;
char *argv[];
{
register i;
int slen, pid;
unsigned msize;
signal(SIGINT,die_normal); /* die cleanly */
/*
* get the shell process id (pid) to match $$ in the = alias
*/
pid = getppid();
sprintf(hfile,"/tmp/eh%d",pid);
sprintf(cfile,"/tmp/ec%d",pid);
openrd(hfile);
/*
* read the history lines into the hist[] array,
* previous mced invocation commands (ie. "=")are not copied, once
* the command is read into cstr the newline is replaced with '\0'
* and then it is copied into hist[last_hline]
*/
for (last_hline = 0; fgets(cstr, (MAX_CH), fptr) != NULL;)
{
if (cstr[0] != '=') /* "=" must be used in the alias for this to work*/
{
slen = strlen(cstr);
if (slen > MIN_CMD_LEN)
{
msize = (unsigned) (slen * sizeof(char));
cstr[slen - 1] = '\0';
hist[last_hline] = (char *) malloc(msize);
strcpy(hist[last_hline], cstr);
++last_hline;
}
}
}
--last_hline;
cur_cmd = last_hline;
/*
* close and delete history temp file
*/
fclose(fptr);
unlink(hfile);
/*
* check for existence of history before going on
*/
if (last_hline < 0)
{
fprintf(stderr,"No valid history\n");
die_normal();
}
/*
* copy search string from command line
*/
if (argc > 1)
{
strcpy(sstr, argv[1]);
if (argc > 2)
{
for (i = 3; i <= argc; i++)
{
strcat(sstr, spc);
strcat(sstr, argv[i - 1]);
}
}
cur_cmd = index_cmd(cur_cmd,-1);
}
strcpy(cstr, hist[cur_cmd]);
/*
* edit command and execute
*/
edit_cmd();
openwr(cfile);
fprintf(fptr, "%s\n", vern);
fprintf(fptr, "%s\n", cstr);
fclose(fptr);
printf("\n");
}
int index_cmd(tcur_cmd,direc)
int tcur_cmd, direc;
{
register i, slen;
slen = strlen(sstr);
for (i = 0; i <= last_hline; i++)
{
if (tcur_cmd < 0) tcur_cmd = last_hline;
if (tcur_cmd > last_hline) tcur_cmd = 0;
if (strncmp(hist[tcur_cmd], sstr, slen) == 0)
return(tcur_cmd);
tcur_cmd += direc;
}
return(cur_cmd);
}
void openrd(fname)
char fname[];
{
int fd;
fd = open(fname, 0);
if (fd == (int) -1)
{
perror(fname);
fprintf(stderr,"To execute mced use \"=\" with the following alias:\n");
fprintf(stderr,"alias = \"history -h 50 >\\! /tmp/eh$$;mced \\!*;");
fprintf(stderr,"source -h /tmp/ec$$;source /tmp/ec$$;/bin/rm /tmp/ec$$\"\n");
die_normal();
}
else
{
close(fd);
fptr = fopen(fname, "r");
}
}
void openwr(fname)
char fname[];
{
if ((fptr = fopen(fname, "w")) == NULL)
{
perror(fname);
exit(0);
}
}
SIGTYPE die_normal()
{
signal(SIGINT,SIG_IGN);
signal(SIGINT,die_normal);
openwr(cfile);
fprintf(fptr, "%s\n", vern);
fclose(fptr);
exit(0);
}
void add_hline() /*add next hist line on delete at EOL*/
{
if(cur_cmd < last_hline)
{
++cur_cmd;
savex_pos = x_pos;
my_waddstr(hist[cur_cmd]);
x_pos = savex_pos;
my_wmove(x_pos);
}
else
beep();
}
void my_wmove(i)
int i;
{
int which_line;
which_line = ((i < COLS) ? 0 : 1);
wmove(win,which_line,(i - which_line * COLS));
}
void my_winsch(in_char)
int in_char;
{
int wrap_char;
if ((xend + 1) >= (COLS * 2))
{
beep();
}
else if(xend > COLS && x_pos < COLS) /* wraparound */
{
++xend;
wmove(win,0,COLS-1);
wrap_char = winch(win);
wmove(win,1,0);
winsch(win,wrap_char);
my_wmove(x_pos);
winsch(win,in_char);
my_wmove(++x_pos);
}
else
{
++xend;
winsch(win,in_char);
my_wmove(++x_pos);
}
}
void my_wdelch()
{
int wrap_char;
--xend;
if(xend >= COLS && x_pos < COLS) /* wraparound */
{
wmove(win,1,0);
wrap_char = winch(win);
wdelch(win);
my_wmove(x_pos);
wdelch(win);
wmove(win,0,COLS-1);
winsch(win,wrap_char);
my_wmove(x_pos);
}
else
{
wdelch(win);
}
}
void my_waddstr(strng)
char strng[];
{
register i, len;
len = strlen(strng);
for(i=0;i < len;i++)
{
my_winsch((int)strng[i]);
}
}
void cmd_to_win() /*write prompt and command to window*/
{
my_wmove(0);
wclear(win);
waddstr(win,prompt);
xend = x_pos = xbeg;
my_waddstr(cstr);
}
void win_to_cmd() /*get the edited line from the window*/
{
int i;
my_wmove(xbeg);
for(i=0;i <= (xend - xbeg);i++)
{
my_wmove(xbeg+i);
cstr[i] = winch(win);
}
cstr[xend - xbeg] = '\0';
}
void case_upper()
{
int i;
for(i=0;i <= (xend - xbeg);i++)
{
if(islower(cstr[i]))
cstr[i] = toupper(cstr[i]);
}
}
void case_lower()
{
int i;
for(i=0;i <= (xend - xbeg);i++)
{
if(isupper(cstr[i]))
cstr[i] = tolower(cstr[i]);
}
}
SIGTYPE die_curses() /* interrupt signal */
{
signal(SIGINT,SIG_IGN);
signal(SIGINT,die_curses);
#ifdef SYSVcurses
if(ioctl(0, TCSETA, &tio) != 0)
perror("ioctl");
#else
if(ioctl(0, TIOCSETC, &tco) != 0)
perror("ioctl");
#endif
nocbreak();
echo();
endwin();
openwr(cfile);
fprintf(fptr, "%s\n", vern);
fclose(fptr);
printf("\n");
exit(0);
}
void eat_white(direc,destruc) /*eat up initial whitespace*/
int direc,destruc;
{
int lim;
if(direc == -1)
lim = xbeg;
else
lim = xend;
if(destruc == NO)
{
for(;isspace(winch(win));)
{
if(x_pos != lim)
{
x_pos += direc;
my_wmove(x_pos);
}
else
return;
}
return;
}
else /* actually delete */
{
for(;isspace(winch(win));)
{
if(x_pos != lim)
{
my_wdelch();
x_pos += direc;
my_wmove(x_pos);
if(!(isspace(winch(win))) && direc == 1)
my_wmove(--x_pos);
}
else
return;
}
return;
}
}