home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume17 / shmed / part01 next >
Encoding:
Internet Message Format  |  1991-03-23  |  25.9 KB

  1. From: marty@wuphys.wustl.edu (Marty Olevitch)
  2. Newsgroups: comp.sources.misc
  3. Subject: v17i066:  shmed - shell form editor, Part01/01
  4. Message-ID: <1991Mar22.222546.18556@sparky.IMD.Sterling.COM>
  5. Date: 22 Mar 91 22:25:46 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: d84230e9 0a11fd70 1378afa5 9db8f30a
  8.  
  9. Submitted-by: Marty Olevitch <marty@wuphys.wustl.edu>
  10. Posting-number: Volume 17, Issue 66
  11. Archive-name: shmed/part01
  12.  
  13. This is shmed, version 1.0, a simple editor that gives a shell or perl
  14. program form editing capabilities for user input.  After reading in a
  15. file specifying the form, it is displayed on the screen and the user can
  16. edit it. Upon exit, shmed writes out the variable assignment statements
  17. to another file which can then be source'd (or .'d or do'd) by the
  18. shell.  See the manual page for the details.
  19.  
  20. Marty Olevitch                Internet: marty@wuphys.wustl.edu
  21. Washington University            UUCP:     uunet!wugate!wuphys!marty
  22. Physics Department, Campus Box 1105    Bitnet:   marty@wuphys.WUSTL
  23. St Louis MO 63130 USA            Tel:      (314) 889-6285
  24.  
  25. ------
  26. : This is a shar archive.  Extract with sh, not csh.
  27. : This archive ends with exit, so do not worry about trailing junk.
  28. echo 'Extracting README'
  29. sed 's/^X//' > README << '+ END-OF-FILE README'
  30. XMarch, 1991
  31. X
  32. XThis is shmed, version 1.0, a simple editor that gives a shell or perl
  33. Xprogram form editing capabilities for user input.  After reading in a
  34. Xfile specifying the form, it is displayed on the screen and the user can
  35. Xedit it. Upon exit, shmed writes out the variable assignment statements
  36. Xto another file which can then be source'd (or .'d or do'd) by the
  37. Xshell.  See the manual page for the details.
  38. X
  39. X    Copyright (c) 1991 by Marty Olevitch.
  40. X    Not derived from licensed software.
  41. X
  42. X    Permission is granted to anyone to use this software for any
  43. X    purpose on any computer system, and to redistribute it freely,
  44. X    subject to the following restrictions:
  45. X
  46. X    1. The author is not responsible for the consequences of use of
  47. X        this software, no matter how awful, even if they arise
  48. X        from defects in it.
  49. X
  50. X    2. The origin of this software must not be misrepresented, either
  51. X        by explicit claim or by omission.
  52. X
  53. X    3. Altered versions must be plainly marked as such, and must not
  54. X        be misrepresented as being the original software.
  55. X
  56. XInstallation:
  57. X
  58. X1) Edit the Makefile and change the options at the top of the file if
  59. Xyou don't like them.
  60. X
  61. X2) Run "make". This should produce the executable "shmed".
  62. X
  63. X3) Run "shmed -f testform -o outfile" to try it out.  Check the outfile to
  64. Xsee what is produced. A trivial perl example is in the file perldemo and one
  65. Xfor the shell is in shdemo. Roff is a more complex and possibly even useful
  66. Xsh program.
  67. X
  68. X4) Run "make install" to put the binary and man page in the correct place.
  69. X
  70. XShmed uses the curses library (the BSD version). It has been tested under
  71. XSunOS 4.1, BSD 4.3 (actually mt Xinu MORE/BSD), and the Next machine,
  72. Xalthough not a whole lot (this IS version 1.0).
  73. X
  74. XPlease report any bugs or improvements to me.
  75. X
  76. XMarty Olevitch                         Internet: marty@wuphys.wustl.edu
  77. XWashington University                  UUCP:     uunet!wugate!wuphys!marty
  78. XPhysics Department, Campus Box 1105    Bitnet:   marty@wuphys.WUSTL
  79. XSt Louis MO 63130 USA                  Tel:      (314) 889-6285
  80. X
  81. X
  82. XNote:  There was another shell form editor, "sf" by Paul Lew, which came out
  83. Xon the net a few years ago. I used it for a while, but found that it did
  84. Xbizarre things with reverse video mode on some of our terminals. After a
  85. Xnot-too-lengthy look at the sf code I decided that it would be easier to
  86. Xwrite my own than try to find the problem and fix it. Although, sf inspired
  87. Xthe writing of it, shmed is completely different and of course, the code and
  88. Xinternal structure are not the same.  Ditto for the format of the form
  89. Xdefintion file. If you're interested, sf can be found in the archives of
  90. Xcomp.sources.unix, volume 14 under the name "shellforms".
  91. X
  92. + END-OF-FILE README
  93. chmod 'u=rw,g=r,o=r' 'README'
  94. echo '    -rw-r--r--  1 marty        2681 Mar  7 15:23 README        (as sent)'
  95. echo -n '    '
  96. /bin/ls -l README
  97. echo 'Extracting Makefile'
  98. sed 's/^X//' > Makefile << '+ END-OF-FILE Makefile'
  99. X# shmed makefile
  100. X
  101. XDESTDIR = /usr/local
  102. XMANSUFFIX = l
  103. XMANDIR = /usr/man/man$(MANSUFFIX)
  104. XOWNER = bin
  105. XGROUP = bin
  106. X
  107. XCC = cc
  108. X# CFLAGS = -g -Bstatic
  109. XLIBS = -lcurses -ltermcap
  110. XFILES = README Makefile shmed.man shmed.c util.c formfile.doc \
  111. X    Roff perldemo shdemo testform
  112. X
  113. Xshmed:    shmed.o util.o
  114. X    $(CC) -o shmed shmed.o util.o $(LIBS)
  115. X
  116. Xclean:
  117. X    rm *.o
  118. X
  119. Xinstall:    shmed
  120. X    strip shmed
  121. X    mv shmed $(DESTDIR)
  122. X    chmod 755 $(DESTDIR)/shmed
  123. X    chown $(OWNER) $(DESTDIR)/shmed
  124. X    chown $(GROUP) $(DESTDIR)/shmed
  125. X    cp shmed.man $(MANDIR)/shmed.$(MANSUFFIX)
  126. X
  127. Xshar:    shmed.shar
  128. X
  129. Xshmed.shar: $(FILES)
  130. X    shar -o shmed.shar $(FILES)
  131. + END-OF-FILE Makefile
  132. chmod 'u=rw,g=r,o=r' 'Makefile'
  133. echo '    -rw-r--r--  1 marty         598 Mar  7 15:23 Makefile        (as sent)'
  134. echo -n '    '
  135. /bin/ls -l Makefile
  136. echo 'Extracting shmed.man'
  137. sed 's/^X//' > shmed.man << '+ END-OF-FILE shmed.man'
  138. X.TH shmed L "March 7, 1991" "WU Cosmic Ray Lab"
  139. X.SH NAME
  140. Xshmed - simple shell form editor
  141. X.SH USAGE
  142. X.nf
  143. Xshmed [-pbc] [-f formfile] -o outfile
  144. X-p            perl output    (default)
  145. X-b            Bourne shell output
  146. X-c            csh output
  147. X-f file        form template file (default stdin)
  148. X-o file        name of output file (no default)
  149. X.SH DIAGNOSTICS
  150. Xshmed returns non-zero if there are startup
  151. Xproblems or if it is interrupted, else 0.
  152. X.SH FILES
  153. XFormat of the form template file
  154. X.RS
  155. XNormal text lines are printed as they appear.
  156. XEditable lines should begin with a '.' (dot), and
  157. Xcontain 2 or 3 fields separated by a '~' (tilde).
  158. X.RS
  159. X1st field: label to be printed in the editor.
  160. X.br
  161. X2nd field: name of variable to assign the value to
  162. X.br
  163. X3rd field: (optional) default value for variable
  164. X.RE
  165. X.RE
  166. X.RS
  167. XOutput file
  168. X.RS
  169. XThe output file contains a bunch of variable assignments
  170. Xin the language you selected (perl, sh, or csh). It should
  171. Xbe do'd, .'d, or source'd after shmed is run.
  172. X.RE
  173. X.SH AUTHOR
  174. X.nf
  175. XMarty Olevitch
  176. XPhysics Dept.
  177. XWashington University
  178. XSt. Louis, MO 63130
  179. X
  180. Xmarty@wuphys.wustl.edu
  181. X
  182. XMarch, 1991
  183. + END-OF-FILE shmed.man
  184. chmod 'u=rw,g=r,o=r' 'shmed.man'
  185. echo '    -rw-r--r--  1 marty        1066 Mar  7 15:23 shmed.man        (as sent)'
  186. echo -n '    '
  187. /bin/ls -l shmed.man
  188. echo 'Extracting shmed.c'
  189. sed 's/^X//' > shmed.c << '+ END-OF-FILE shmed.c'
  190. X/* shmed - simple shell form editor
  191. X *
  192. X *    USAGE:
  193. X *        shmed [-pbc] [-f formfile] -o outfile
  194. X *            -p        perl output    (default)
  195. X *            -b        Bourne shell output
  196. X *            -c        csh output
  197. X *            -f formfile        name of file containing form (default stdin)
  198. X *            -o outfile        name of output file (no default)
  199. X *
  200. X *    DIAGNOSTICS:
  201. X *        shmed returns non-zero if there are startup
  202. X *        problems or if it is interrupted, else 0.
  203. X *
  204. X *    FILES:
  205. X *        format of the form file
  206. X *            Normal text lines are printed as they appear.
  207. X *            Editable lines should begin with a '.' (dot), and
  208. X *            contain 2 or 3 fields separated by a '~' (tilde).
  209. X *                1st field: label to be printed in the editor.
  210. X *                2nd field: name of variable to assign the value to
  211. X *                3rd field: (optional) default value for the variable
  212. X *
  213. X *        output file
  214. X *            The output file contains a bunch of variable assignments
  215. X *            in the language you selected (perl, sh, or csh). It should
  216. X *            be require'd, .'d, or source'd after shmed is run.
  217. X *
  218. X *    AUTHOR
  219. X *
  220. X *        Marty Olevitch
  221. X *        Physics Dept.
  222. X *        Washington University
  223. X *        St. Louis, MO 63130
  224. X *
  225. X *        marty@wuphys.wustl.edu
  226. X *
  227. X *        March, 1991
  228. X */
  229. X
  230. X#define VERSION "1.0"
  231. X
  232. X#include <curses.h>
  233. X#include <ctype.h>
  234. X#include <signal.h>
  235. X
  236. X#define CTL(x)    ((x) & 0x3f)
  237. X#define    ESC        0x1b
  238. X#define DEL        0x7f
  239. X
  240. X#define    MAXSTR    500        /* For sizing strings -- DON'T use BUFSIZ! */
  241. X#define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  242. X#define BEEP    putchar(CTL('G'))
  243. X
  244. X/* CHOP - replace last character of a string */
  245. X#define CHOP(s, c)    ((s)[strlen(s)-1] = (c))
  246. X
  247. X#define FIELDSEP    "~"                /* form file field separator string */
  248. X#define PERLFMT        "$%s = '%s';\n"
  249. X#define BOURNEFMT    "%s='%s'\n"
  250. X#define CSHFMT        "set %s='%s'\n"
  251. X
  252. X#define MAXFORMROWS    24                /* max. no. of rows in a form */
  253. Xchar answer[MAXFORMROWS][MAXSTR];    /* response lines */
  254. Xint    editable[MAXFORMROWS];            /* tells if form line is editable */
  255. Xchar label[MAXFORMROWS][MAXSTR];    /* labels for editable lines */
  256. Xchar variable[MAXFORMROWS][MAXSTR];    /* variable names for editable lines */
  257. Xint longval;                        /* length of longest formrow string */
  258. Xint nrows;                            /* number of rows in our form */
  259. X
  260. XWINDOW *helpwin;    /* help screen */
  261. XWINDOW *altwin;        /* for saving real screen when help is displayed */
  262. X
  263. Xchar *progname;
  264. XFILE *efopen();
  265. X
  266. X/*
  267. X -    usage - print usage message
  268. X */
  269. Xusage()
  270. X{
  271. X    fprintf(stderr,"USAGE: %s [-pbc] [-f formfile] -o outfile\n",
  272. X        progname);
  273. X}
  274. X
  275. X/*
  276. X - main
  277. X */
  278. Xmain(argc, argv)
  279. X    int argc;
  280. X    char *argv[];
  281. X{
  282. X    int bourneout = 0;            /* bourne shell output */
  283. X    int cshout = 0;                /* csh shell output */
  284. X    int done;
  285. X    char filename[MAXSTR];        /* form file */
  286. X    char fmt[MAXSTR];            /* printf format for output */
  287. X    int i;
  288. X    FILE *outfp;
  289. X    char outputfile[MAXSTR];    /* output file name */
  290. X    int outputflag = 0;            /* 1 if we have a valid -o argument */
  291. X    int perlout = 0;            /* perl output */
  292. X    int sighandle();
  293. X
  294. X    int c;
  295. X    int errflg = 0;
  296. X    extern int optind;
  297. X    extern char *optarg;
  298. X
  299. X    progname = argv[0];
  300. X    strcpy(filename, "-");
  301. X        
  302. X    while ((c = getopt(argc, argv, "pcbf:o:")) != EOF) {
  303. X        switch (c) {
  304. X        case 'p':    /* perl output */
  305. X            if(bourneout || cshout) {
  306. X                fprintf(stderr,"Use only one of -c, -b and -p flags\n");
  307. X                errflg++;
  308. X            } else 
  309. X                perlout = 1;
  310. X            break;
  311. X        case 'b':    /* bourne shell output */
  312. X            if(perlout || cshout)  {
  313. X                fprintf(stderr,"Use only one of -c, -b and -p flags\n");
  314. X                errflg++;
  315. X            } else 
  316. X                bourneout = 1;
  317. X            break;
  318. X        case 'c':    /* csh output */
  319. X            if(perlout || bourneout)  {
  320. X                fprintf(stderr,"Use only one of -c, -b and -p flags\n");
  321. X                errflg++;
  322. X            } else 
  323. X                cshout = 1;
  324. X            break;
  325. X        case 'f':    /* form file name */
  326. X            strcpy(filename, optarg);
  327. X            break;
  328. X        case 'o':    /* output file name */
  329. X            outputflag++;
  330. X            strcpy(outputfile, optarg);
  331. X            break;
  332. X        case '?':
  333. X        default:
  334. X            errflg++;
  335. X            break;
  336. X        }
  337. X    }
  338. X    
  339. X    if (errflg) {
  340. X        usage();
  341. X        exit(2);
  342. X    }
  343. X
  344. X    if(outputflag == 0) {
  345. X        fprintf(stderr,"No output file specified\n");
  346. X        usage();
  347. X        exit(2);
  348. X    }
  349. X
  350. X    if(perlout == 0 && bourneout == 0 && cshout == 0)
  351. X        perlout = 1;
  352. X
  353. X    outfp = efopen(outputfile, "w");
  354. X
  355. X    for(i=0; i<MAXFORMROWS; i++)
  356. X        answer[i][0] = '\0';
  357. X        
  358. X    /* readform fills in the editable, label, variable, and answer arrays */
  359. X    if((nrows = readform(filename)) == 0) {
  360. X        fprintf(stderr,"%s: empty form file.\n", progname);
  361. X        exit(1);
  362. X    }
  363. X    
  364. X    startcurses();
  365. X    signal(SIGQUIT, sighandle);
  366. X    signal(SIGINT, sighandle);
  367. X
  368. X    /* initial update of the editing screen */
  369. X    for(i=0; i<nrows; i++) {
  370. X        move(i,0);
  371. X        addstr(label[i]);
  372. X        if(editable[i]) {
  373. X            addch(':');
  374. X            move(i, longval);    /* longval was determined by readform() */
  375. X            addstr(answer[i]);
  376. X        }
  377. X    }
  378. X    refresh();
  379. X    
  380. X    /* edit each of the editable lines in turn */
  381. X    i = 0;
  382. X    while(1) {
  383. X        if(editable[i] == 1) {
  384. X            done = edit_line(i, longval, answer[i]);
  385. X            refresh();
  386. X            if(done == 1)        /* ESC was pressed */
  387. X                break;
  388. X        }
  389. X        if(done == 0) {            /* next line */
  390. X            if(++i == nrows)
  391. X                i = 0;
  392. X        } else if(done == -1) {    /* previous line */
  393. X            if(--i < 0)
  394. X                i = nrows - 1;
  395. X        }
  396. X    }
  397. X
  398. X    /* output time */
  399. X    if(perlout)
  400. X        strcpy(fmt, PERLFMT);
  401. X    else if(bourneout)
  402. X        strcpy(fmt, BOURNEFMT);
  403. X    else if(cshout)
  404. X        strcpy(fmt, CSHFMT);
  405. X    else {        /* can't happen */
  406. X        fprintf(stderr,"neither perl, csh, nor bourne output specified.\n");
  407. X        exit(1);
  408. X    }
  409. X
  410. X    for(i=0; i<nrows; i++) {
  411. X        if(editable[i] == 1)
  412. X            fprintf(outfp, fmt, variable[i], answer[i]);
  413. X    }
  414. X
  415. X    finish_up();
  416. X    return(0);
  417. X}
  418. X
  419. X/*
  420. X - edit_line - perform edit operations on a single line
  421. X *        The edited string is returned in the str argument.
  422. X *        returns 1 if ESC typed, else 0 if RET typed
  423. X */
  424. Xedit_line(r, startc, str)
  425. X    int r;        /* row that we're editing */
  426. X    int startc;    /* starting column for editable string */
  427. X    char *str;    /* pointer to editable string */
  428. X{
  429. X    int k;
  430. X    int c;        /* current column */
  431. X    int endc;    /* ending column */
  432. X    int slen;    /* length of editable strings */
  433. X    int retcode;
  434. X
  435. X    slen = strlen(str);
  436. X    c = endc = startc + slen;
  437. X    move(r, c);
  438. X    refresh();
  439. X    
  440. X    while(k = getch()) {
  441. X        switch(k) {
  442. X        case CTL('A'):
  443. X            move(r, startc);
  444. X            c = startc;
  445. X            break;
  446. X        case CTL('F'):
  447. X            c = ( c+1 <= endc ) ? c + 1 : c;
  448. X            move(r, c);
  449. X            break;
  450. X        case CTL('B'):
  451. X            c = ( c-1 >= startc ) ? c - 1 : c;
  452. X            move(r, c);
  453. X            break;
  454. X        case CTL('E'):
  455. X            if(endc < COLS-2)
  456. X                c = endc;
  457. X            move(r, c);
  458. X            break;
  459. X        case CTL('D'):
  460. X            delch();
  461. X            endc--;
  462. X            break;
  463. X        case CTL('G'):
  464. X            help();
  465. X            move(r, c);
  466. X            break;
  467. X        case CTL('H'):
  468. X        case DEL:
  469. X            if(c != startc) {
  470. X                c--;
  471. X                move(r, c);
  472. X                delch();
  473. X                endc--;
  474. X            }
  475. X            break;
  476. X        case CTL('K'):        /* delete to end of line */
  477. X            clrtoeol();
  478. X            endc = c;
  479. X            break;
  480. X        case CTL('L'):
  481. X            wrefresh(curscr);
  482. X            break;
  483. X        case CTL('I'):
  484. X        case CTL('N'):        /* next line */
  485. X        case '\n':
  486. X        case '\r':
  487. X            retcode = 0;
  488. X            goto finito;
  489. X            break;
  490. X        case CTL('P'):
  491. X            retcode = -1;
  492. X            goto finito;
  493. X            break;
  494. X        case ESC:            /* done with form */
  495. X            retcode = 1;
  496. X            goto finito;
  497. X            break;
  498. X        default:
  499. X            if(isprint(k)) {
  500. X                addch(k);
  501. X                if(c++ >= COLS-2) {
  502. X                    c = COLS-2;
  503. X                    move(r, c);
  504. X                }
  505. X                if(c > endc)
  506. X                    endc++;
  507. X            } else {
  508. X                BEEP;
  509. X            }
  510. X            break;
  511. X        }
  512. X        refresh();
  513. X    }
  514. Xfinito:
  515. X    instr(r, longval, endc, str);
  516. X    return(retcode);
  517. X}
  518. X
  519. X/*
  520. X - instr - get the characters between startc and endc on a line
  521. X */
  522. Xinstr(row, startc, endc, str)
  523. X    int row;
  524. X    int startc;
  525. X    int endc;
  526. X    char *str;
  527. X{
  528. X    int i;
  529. X    char *cp;
  530. X    
  531. X    if(row < 0 || row > LINES - 1)
  532. X        return(-1);
  533. X    if(startc < 0 || startc > COLS - 1)
  534. X        return(-2);
  535. X    if(endc < 0 || endc > COLS - 1)
  536. X        return(-3);
  537. X
  538. X    if(startc < endc) {
  539. X        for(cp=str,i=startc; i<endc; i++) {
  540. X            move(row, i);
  541. X            *cp++ = inch();
  542. X        }
  543. X        *cp = '\0';
  544. X    } else {        /* endc < startc */
  545. X        for(cp=str,i=startc; i>endc; i--) {
  546. X            move(row, i);
  547. X            *cp++ = inch();
  548. X        }
  549. X        *cp = '\0';
  550. X    }
  551. X    return(0);
  552. X}
  553. X
  554. X/*
  555. X - readform - read the lines from the formfile
  556. X *
  557. X * format of the form file:
  558. X *        normal text lines - printed as they appear
  559. X *        . lines - begin with a dot; editable lines
  560. X *            .<label>~variable name~default value
  561. X *
  562. X *        example:
  563. X *            .Name of Dog~dogname~Fido
  564. X *            .Date of Vaccination~vacdate~9/17/91
  565. X *
  566. X * Read only up to MAXFORMROWS rows. Return the number of rows read.
  567. X */
  568. Xreadform(file)
  569. X    char *file;
  570. X{
  571. X    char formrow[MAXFORMROWS][MAXSTR];    /* input form lines */
  572. X    FILE *formfp;    /* formfile file pointer */
  573. X    int i;
  574. X
  575. X    if(STREQ(file, "-"))
  576. X        formfp = stdin;
  577. X    else
  578. X        formfp = efopen(file, "r");
  579. X
  580. X    for(i=0; i<MAXFORMROWS; i++) {
  581. X        if(fgets(formrow[i], MAXSTR, formfp) == NULL)
  582. X            break;
  583. X        CHOP(formrow[i], '\0');
  584. X        if(formrow[i][0] == '.') {
  585. X            editable[i] = 1;
  586. X            split(formrow[i]+1, FIELDSEP, 3, label[i], variable[i], answer[i]);
  587. X            if(strlen(label[i]) + 2 > longval)    /* find longest label */
  588. X                longval = strlen(label[i]) + 2;
  589. X        } else {
  590. X            strcpy(label[i], formrow[i]);
  591. X        }
  592. X    }
  593. X    fclose(formfp);
  594. X    if(formfp == stdin) {
  595. X        if(freopen("/dev/tty", "r+", stdin) != stdin) {
  596. X            fprintf(stderr,"%s: can't reopen stdin\n", progname);
  597. X            exit(2);
  598. X        }
  599. X    }
  600. X        
  601. X    return(i);
  602. X}
  603. X
  604. X/*
  605. X - finish_up - clean up before exit
  606. X */
  607. Xfinish_up()
  608. X{
  609. X    move(nrows, 0);
  610. X    refresh();
  611. X    nocbreak();
  612. X    echo();
  613. X    endwin();
  614. X}
  615. X
  616. X/*
  617. X - sighandle - catches SIGQUIT and SIGINT
  618. X */
  619. Xsighandle()
  620. X{
  621. X    signal(SIGQUIT, SIG_IGN);
  622. X    signal(SIGINT, SIG_IGN);
  623. X    finish_up();
  624. X    exit(1);
  625. X}
  626. X
  627. Xstartcurses()
  628. X{
  629. X    if(initscr() == ERR) {
  630. X        fprintf(stderr,"%s: can't start curses!\n", progname);
  631. X        exit(1);
  632. X    }
  633. X    noecho();
  634. X    cbreak();
  635. X    clear();
  636. X
  637. X    altwin = newwin(LINES, COLS, 0, 0);
  638. X    helpwin = newwin(LINES, COLS, 0, 0);
  639. X    inithelp();
  640. X}
  641. X
  642. Xinithelp()
  643. X{
  644. X    mvwprintw(helpwin, 1, 12, "%s %s", progname, VERSION);
  645. X    mvwprintw(helpwin, 3, 0, "ctrl-N    go to next line (same as pressing RET)");
  646. X    mvwprintw(helpwin, 4, 0, "ctrl-P    go to previous line");
  647. X    mvwprintw(helpwin, 5, 0, "esc       form completed");
  648. X
  649. X    mvwprintw(helpwin, 7, 0, "ctrl-A     go to beginning of line");
  650. X    mvwprintw(helpwin, 8, 0, "ctrl-E     go to end of line");
  651. X    mvwprintw(helpwin, 9, 0, "ctrl-F     go forward one space");
  652. X    mvwprintw(helpwin, 10, 0, "ctrl-B     go back one space");
  653. X
  654. X    mvwprintw(helpwin, 12, 0, "ctrl-D     delete character at cursor");
  655. X    mvwprintw(helpwin, 13, 0, "backspace  delete character before cursor");
  656. X    mvwprintw(helpwin, 14,0, "ctrl-K     delete all characters to end of line");
  657. X
  658. X    mvwprintw(helpwin, 16, 0, "ctrl-L    redraw screen");
  659. X    mvwprintw(helpwin, 17, 0, "ctrl-G    show help screen");
  660. X    mvwprintw(helpwin, 20, 10, "Hit any key to continue...");
  661. X}
  662. X
  663. Xhelp()
  664. X{
  665. X    overwrite(stdscr, altwin);
  666. X    overwrite(helpwin, stdscr);
  667. X    move(20, 36);
  668. X    refresh();
  669. X    wgetch(helpwin);
  670. X    overwrite(altwin, stdscr);
  671. X    refresh();
  672. X}
  673. + END-OF-FILE shmed.c
  674. chmod 'u=rw,g=r,o=r' 'shmed.c'
  675. echo '    -rw-r--r--  1 marty       10327 Mar  7 15:23 shmed.c        (as sent)'
  676. echo -n '    '
  677. /bin/ls -l shmed.c
  678. echo 'Extracting util.c'
  679. sed 's/^X//' > util.c << '+ END-OF-FILE util.c'
  680. X/*
  681. X * util.c - utility routines used in shmed
  682. X *
  683. X *    (should eventually become local library routines)
  684. X *
  685. X *    Marty Olevitch, March 1991
  686. X */
  687. X#include <stdio.h>
  688. X#include <varargs.h>
  689. X#include <strings.h>
  690. X#include <errno.h>
  691. X
  692. Xextern int sys_nerr;
  693. Xextern char *sys_errlist[];
  694. Xextern int errno;
  695. X
  696. X/*
  697. X - efopen - fopen() with error handling
  698. X */
  699. XFILE *
  700. Xefopen(filename, mode)
  701. X    char *filename;
  702. X    char *mode;
  703. X{
  704. X    FILE *fp;
  705. X    if((fp = fopen(filename, mode)) == NULL) {
  706. X        fprintf(stderr,"Can't open file '%s' mode '%s' (%s)\n",
  707. X            filename, mode, sys_errlist[errno]);
  708. X        exit(1);
  709. X    }
  710. X    return(fp);
  711. X}
  712. X
  713. X/*
  714. X - split - split a string into substrings
  715. X *
  716. X *    usage is split(str, sep, n, str1, str2, ...)
  717. X *
  718. X *        split string str on separator sep into the n substrings
  719. X *        str1, str2, etc.
  720. X *
  721. X *        returns number of substrings extracted
  722. X */
  723. Xsplit(va_alist)
  724. X    va_dcl
  725. X{
  726. X    va_list ap;
  727. X    char *srcp;    /* source string */
  728. X    char *sep;    /* separator */
  729. X    int n;        /* number of strings to split into */
  730. X    int i;
  731. X    char *destp;/* destination strings */
  732. X    char *cp, *strtok();
  733. X
  734. X    va_start(ap);
  735. X    srcp = va_arg(ap, char *);
  736. X    sep = va_arg(ap, char *);
  737. X    n = va_arg(ap, int);
  738. X
  739. X    for(i=0; i<n; i++) {
  740. X        destp = va_arg(ap, char *);
  741. X        if(i == 0)
  742. X            cp = strtok(srcp, sep);
  743. X        else
  744. X            cp = strtok(NULL, sep);
  745. X            
  746. X        if(cp != NULL) {
  747. X            strcpy(destp, cp);
  748. X        } else {
  749. X            strcpy(destp, "");        /* not enough fields */
  750. X            break;
  751. X        }
  752. X    }
  753. X    return(i);
  754. X}
  755. + END-OF-FILE util.c
  756. chmod 'u=rw,g=r,o=r' 'util.c'
  757. echo '    -rw-r--r--  1 marty        1382 Mar  7 15:24 util.c        (as sent)'
  758. echo -n '    '
  759. /bin/ls -l util.c
  760. echo 'Extracting formfile.doc'
  761. sed 's/^X//' > formfile.doc << '+ END-OF-FILE formfile.doc'
  762. XThe Shmed Form Template
  763. X
  764. XA form template consists of up to 24 lines of text (actually you
  765. Xcan have more than 24 lines in the file, but anything beyond 24
  766. Xwill be ignored). Ordinary text lines will be printed on the screen
  767. Xjust as they are. However, a line which begins with a dot (.) denotes
  768. Xan editable line. This line consists of either 2 or 3 fields separated
  769. Xby a tilde (~). The first field is the label that will be printed
  770. Xon the line; the second field is the name of the variable that will
  771. Xbe assigned to; and the third field, if present, is a default string
  772. Xthat will be printed.
  773. X
  774. XFor example, the file containing
  775. X
  776. X.Your name~nombre~Albert Q. Shmurdwell
  777. X
  778. Xwill produce a line on the editor that looks like
  779. X
  780. XYour name: Albert Q. Shmurdwell
  781. X                               ^------- (cursor will be here)
  782. X
  783. XThe user can then edit the line and change it if their name is not
  784. XAlbert Q. Shmurdwell. After they have exited the editor, an assignment
  785. Xstatement such as
  786. X
  787. Xnombre='Albert Q. Shmurdwell'
  788. X
  789. Xwill be written into the output file (if you are using the -b option
  790. Xfor Bourne shell output).
  791. X
  792. XLook at the sample files provided for more elaborate examples
  793. Xof template files.
  794. + END-OF-FILE formfile.doc
  795. chmod 'u=rw,g=r,o=r' 'formfile.doc'
  796. echo '    -rw-r--r--  1 marty        1174 Mar  7 15:24 formfile.doc        (as sent)'
  797. echo -n '    '
  798. /bin/ls -l formfile.doc
  799. echo 'Extracting Roff'
  800. sed 's/^X//' > Roff << '+ END-OF-FILE Roff'
  801. X#! /bin/sh
  802. X# Roff - menu driven ditroffing
  803. X#
  804. X#    Usage: Roff [file]
  805. X#
  806. X#    Marty Olevitch, Aug 1989
  807. X#            March, 1991 - uses shmed
  808. X
  809. XVersion="Roff 1.3"
  810. X
  811. XFiles=$*        # files, if any, to print
  812. X
  813. XTMP=/usr/tmp/shmed$$.out        # shmed output file
  814. XRCfile=$HOME/.Roffrc        # user's default-set-up file
  815. X
  816. Xtrap "if [ -f $TMP ]; then /bin/rm -f $TMP; fi" 0 1 2 3 15
  817. X
  818. X# Set up defaults. Users may put their own defaults in the $RCfile file.
  819. X# Otherwise we use a set of more or less reasonable defaults.
  820. X
  821. Xif [ -r $RCfile ]; then
  822. X    . $RCfile
  823. Xelse
  824. X    do_eqn=yes
  825. X    do_tbl=yes
  826. X    do_pic=no
  827. X    do_grap=no
  828. X    do_psfig=no
  829. X    macro_pkg=ms
  830. X    additional_opts=
  831. X    output_dev=lw5
  832. X    backgnd=foreground
  833. Xfi
  834. Xnew_rc=no    # 'yes' if we want to create new RCfile
  835. X
  836. Xshmed -b -o $TMP << sfEOF
  837. X                           $Version
  838. X        INSTRUCTIONS: To move to the next field, press RET.
  839. X    When this form is completed to your satisfaction, press ESC.
  840. X        (press ctrl-G for editing help)
  841. X
  842. X.Files to print~menu_files~$Files
  843. X
  844. X.eqn?~do_eqn~$do_eqn
  845. X.tbl?~do_tbl~$do_tbl
  846. X.pic?~do_pic~$do_pic
  847. X.grap?~do_grap~$do_grap
  848. X.psfig?~do_psfig~$do_psfig
  849. X.macro pkg~macro_pkg~$macro_pkg
  850. X.other troff options~additional_opts~$additional_opts
  851. X.output to~output_dev~$output_dev
  852. X
  853. Xbackground or foreground
  854. X.execution~backgnd~$backgnd
  855. X
  856. XDon't print anything, just make a new setup
  857. Xfile so Roff will remember your choices
  858. X.next time~new_rc~$new_rc
  859. XsfEOF
  860. X
  861. Xif [ $? -ne 0 ]; then
  862. X    echo "Aborted."
  863. X    exit        # unnatural exit from sf
  864. Xfi
  865. X
  866. X. $TMP
  867. X
  868. Xif [ $new_rc = 'yes' ]; then    # just create a new rc file, don't print
  869. X    echo -n "Writing new .Roffrc file..."
  870. X    cat > $RCfile <<-RoffEOF
  871. X        do_eqn=$do_eqn
  872. X        do_tbl=$do_tbl
  873. X        do_pic=$do_pic
  874. X        do_grap=$do_grap
  875. X        do_psfig=$do_psfig
  876. X        macro_pkg=$macro_pkg
  877. X        additional_opts="$additional_opts"
  878. X        output_dev=$output_dev
  879. X        backgnd=$backgnd
  880. XRoffEOF
  881. X    echo
  882. X    exit
  883. Xfi
  884. X
  885. XEQN=
  886. XTBL=
  887. XPIC=
  888. XGRAP=
  889. XPSFIG=
  890. X
  891. XP="-P$output_dev"
  892. X
  893. Xif [ -n "$menu_files" ]; then    # files selected in menu override cmd line
  894. X    Files=$menu_files
  895. Xfi
  896. Xif [ -z "$Files" ]; then
  897. X    echo "Roff: No file to print! Quitting."
  898. X    exit
  899. Xfi
  900. X
  901. Xif [ $do_eqn = 'yes' ]; then
  902. X    EQN="deqn |"
  903. Xfi
  904. Xif [ $do_tbl = 'yes' ]; then
  905. X    TBL="dtbl |"
  906. Xfi
  907. Xif [ $do_pic = 'yes' ]; then
  908. X    PIC="pic |"
  909. Xfi
  910. Xif [ $do_grap = 'yes' ]; then
  911. X    GRAP="grap |"
  912. X    PIC="pic |"    # if grap, then pic
  913. Xfi
  914. Xif [ $do_psfig = 'yes' ]; then
  915. X    PSFIG="/usr/new/psfig |"
  916. X    DIT="rpr \"ditroff -mpsfig -Tpsc -$macro_pkg $additional_opts\" | psdit"
  917. X    ROFFLINE="$GRAP $PIC $TBL $EQN $PSFIG $DIT | lpr $P"
  918. Xelse
  919. X    if [ $output_dev = "imagen" ]; then
  920. X        DIT="iroff -$macro_pkg $additional_opts -D'pagereversal on'"
  921. X    else
  922. X        EQN=${EQN+"eqn -m2 |"}
  923. X        DIT="psroff -$macro_pkg $additional_opts $P"
  924. X    fi
  925. X    ROFFLINE="$GRAP $PIC $TBL $EQN rpr \"$DIT\""
  926. Xfi
  927. X
  928. Xecho -n "Running   " "cat $Files | $ROFFLINE   "
  929. Xif [ $backgnd = "background" ]; then
  930. X    echo " in the background"
  931. X    cat $Files | eval $ROFFLINE &
  932. Xelse
  933. X    echo -n "..."
  934. X    cat $Files | eval $ROFFLINE
  935. X    echo "done"
  936. Xfi
  937. X
  938. + END-OF-FILE Roff
  939. chmod 'u=rwx,g=rx,o=rx' 'Roff'
  940. echo '    -rwxr-xr-x  1 marty        2862 Mar  7 15:24 Roff        (as sent)'
  941. echo -n '    '
  942. /bin/ls -l Roff
  943. echo 'Extracting perldemo'
  944. sed 's/^X//' > perldemo << '+ END-OF-FILE perldemo'
  945. X#!/usr/bin/perl
  946. X
  947. Xsystem "shmed -o foo <<Eof
  948. X              Shmed Demo
  949. X
  950. X    Press RET to go to the next line.
  951. X   Press ESC when the form is complete.
  952. X           Press ^G for help.
  953. X
  954. X.Name~name~Marty Olevitch
  955. X.Address~addr
  956. X.City~city
  957. X.State~state
  958. X.Zip~zip
  959. X.Phone~phone
  960. XEof";
  961. X
  962. X
  963. Xdie "Bad system() call\n" if($? != 0);
  964. X
  965. Xdo 'foo';
  966. Xunlink 'foo';
  967. Xprint "\n";
  968. Xif($name eq "Marty Olevitch") {
  969. X    print "I doubt if your name is really Marty Olevitch.\n";
  970. X    print "Unless you are my cousin who has my same name.\n\n";
  971. X}
  972. Xprint "The information you gave me is:\n";
  973. Xprint "Name: ", $name, "\n", "Address: ", $addr, "\n",
  974. X    "City: ", $city, "\n", "State: ", $state, "\n",
  975. X    "Zip: ", $zip, "\n", "Phone: ", $phone, "\n";
  976. X    
  977. + END-OF-FILE perldemo
  978. chmod 'u=rwx,g=rx,o=rx' 'perldemo'
  979. echo '    -rwxr-xr-x  1 marty         699 Mar  7 15:24 perldemo        (as sent)'
  980. echo -n '    '
  981. /bin/ls -l perldemo
  982. echo 'Extracting shdemo'
  983. sed 's/^X//' > shdemo << '+ END-OF-FILE shdemo'
  984. X#!/bin/sh
  985. X
  986. XHOST=
  987. X
  988. Xif test -f /bin/hostname ; then
  989. X    HOST=`/bin/hostname`
  990. Xfi
  991. X
  992. Xshmed -b -o foo$$ << ShmedInput
  993. X                      Yet Another Shmed Demo
  994. X
  995. X.Host name~hostname~$HOST
  996. X.IP number~ipno~$IPNO
  997. X
  998. X.Technical Contact~tech
  999. X.Office~office
  1000. X.Telephone~phone
  1001. X
  1002. X           Press RET to go to the next field, ESC when form is done.
  1003. X                        Press ^G for help.
  1004. X
  1005. XShmedInput
  1006. X
  1007. Xif test $? -ne 0; then
  1008. X    exit
  1009. Xfi
  1010. X
  1011. X. foo$$
  1012. X
  1013. Xecho "Host machine is $hostname"
  1014. Xecho "IP address is $ipno"
  1015. Xecho "Technical contact is $tech"
  1016. Xecho "Office is $office"
  1017. Xecho "Telephone $phone"
  1018. X
  1019. Xrm foo$$
  1020. + END-OF-FILE shdemo
  1021. chmod 'u=rwx,g=rx,o=rx' 'shdemo'
  1022. echo '    -rwxr-xr-x  1 marty         580 Mar  7 15:24 shdemo        (as sent)'
  1023. echo -n '    '
  1024. /bin/ls -l shdemo
  1025. echo 'Extracting testform'
  1026. sed 's/^X//' > testform << '+ END-OF-FILE testform'
  1027. X                Shmed Form Editor Demo
  1028. X
  1029. X          Press RET to go to the next line.
  1030. X        Press ESC when the form is completed.
  1031. X
  1032. X.Name~name
  1033. X.Occupation~occupation
  1034. X.Religion~religion
  1035. X.Favorite Animal~animal~aardvark
  1036. X.Favorite Color~color~blue
  1037. X.Opinion of President~opinion
  1038. X
  1039. X                Press ctl-G for help.
  1040. X
  1041. X
  1042. + END-OF-FILE testform
  1043. chmod 'u=rw,g=r,o=r' 'testform'
  1044. echo '    -rw-r--r--  1 marty         315 Mar  7 15:24 testform        (as sent)'
  1045. echo -n '    '
  1046. /bin/ls -l testform
  1047. exit 0
  1048.  
  1049. exit 0 # Just in case...
  1050. -- 
  1051. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1052. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1053. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1054. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1055.