home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 318_01 / redmain.c < prev    next >
C/C++ Source or Header  |  1990-06-18  |  13KB  |  693 lines

  1. /*
  2.     RED main program -- Full C version
  3.  
  4.     Source:  redmain.c
  5.     Version: see SIGNON constant below.
  6.  
  7.     Written by
  8.     
  9.         Edward K. Ream
  10.         166 N. Prospect
  11.         Madison WI 53705
  12.         (608) 257-0802
  13.  
  14.  
  15.     PUBLIC DOMAIN SOFTWARE
  16.  
  17.     This software is in the public domain.
  18.  
  19.     See red.h for a disclaimer of warranties and other information.
  20. */
  21. #include "red.h"
  22.  
  23. #undef SL_SETJMP
  24. #ifdef SHERLOCK
  25. #define SL_SETJMP(n) sl_setjmp(n)
  26. #else
  27. #define SL_SETJMP(n)
  28. #endif
  29.  
  30. /*
  31.     Define the standard signon messages.
  32. */
  33. #define SIGNON      "RED v7.0 January 18, 1990."
  34. #define COPYRIGHT "Written by Edward K. Ream, 1983-1990."
  35. #define RESERVED  "This is public domain software."
  36.  
  37. /*
  38.     Declare local routines.
  39. */
  40. static int    command(void);
  41. static int    control    (char c);
  42. static int    lookup    (char *line, char *cmnd);
  43.  
  44. /*
  45.     Define the possible values of mode and lastmode.
  46. */
  47. #define CMNDMODE 1    /* command mode        */
  48. #define INSMODE  2    /* insert mode        */
  49. #define EDITMODE 3    /* edit mode        */
  50. #define OVERMODE 4    /* overtype mode     */
  51. #define ESCAPEMODE 5    /* escape mode        */
  52. #define EXITMODE 6    /* exit the editor    */
  53.  
  54. /*
  55.     Define internal function numbers.
  56. */
  57. #define BOL    129
  58. #define EOL    130
  59. #define MIDDLE    133
  60. #define KILL    134
  61. #define SEARCH    135
  62. #define GOTO    136
  63. #define XCHNG    137
  64.  
  65. int def0mode;    /* initial mode and mode after commands. */
  66. int def1mode;    /* mode after UP_INS, DOWN_INS.    */
  67. int def2mode;    /* mode after UP, DOWN        */
  68.  
  69. void
  70. main(int  argc, char **argv)
  71. {
  72.     int mode;    /* current mode.            */
  73.     int lastmode;    /* last mode (used by ESCAPEMODE).    */
  74.     int lastc;    /* last command    (used by AGAIN).    */
  75.     int holdc;    /* queued input character.        */
  76.     int c;        /* current input character.        */
  77.     char args [MAXLEN];
  78.     char buffer [SCRNW1];
  79.     int v;
  80.     int x,y,topline;
  81.  
  82.  
  83.     SL_INIT();
  84.     SL_PARSE(argc, argv, "++", "--");
  85.  
  86.     TRACEPB("main",  sl_lpout();
  87.         sl_iout(argc); sl_csout(); sl_pout(argv); sl_rpout());
  88.  
  89.     /* Ready the system module. */
  90.     sysinit();
  91.  
  92.     /* Output from fmt module goes to screen. */
  93.     fmtassn(FALSE);
  94.  
  95.     /* Clear filename [] for save(), resave(). */
  96.     g_file [0] = '\0';
  97.  
  98.     /* Ready the work file if it exists. */
  99.     if (setjmp(DISK_ERR) == ERROR) {
  100.         /* Error in bufinit(). */
  101.         RETURN_VOID("main");
  102.     }
  103.     else {
  104.         bufinit();
  105.     }
  106.  
  107.     /* Start off in the default mode. */
  108.     lastmode = mode = DEFIMODE;
  109.     def0mode = mode;
  110.     def1mode = DEF1MODE;
  111.     def2mode = DEF2MODE;
  112.  
  113.     /* Set tabs, clear the screen and sign on. */
  114.     fmtset(8);
  115.     outinit();
  116.     outclr();
  117.     pmtclr();
  118.     edclr();
  119.     edgetln();        /* Initialize window module. */
  120.     outxy(0,SCRNL1);
  121.  
  122.     pmthold(TRUE);
  123.     message(SIGNON);
  124.     message(COPYRIGHT);
  125.     message(RESERVED);
  126.     message("");
  127.     message("Type ^c help to print a help message.");
  128.     message("");
  129.     message("");
  130.     pmthold(FALSE);
  131.  
  132.     /* Set error recovery point for auto-load code. */
  133.     if (setjmp(DISK_ERR) == ERROR) {
  134.         /* Error in load() in argc >= 2 case below. */
  135.         argc = 0;
  136.     }
  137.  
  138.     /* Never auto-load a file if a previous session was resumed. */
  139.     if (bufchng() == TRUE) {
  140.         /* Draw the first part of the resumed file. */
  141.         bufgo(1);
  142.         edclr();
  143.         edgo(1,0);
  144.     }
  145.     else if (argc >= 2) {
  146.         /* Auto-load a file from the command line. */
  147.         pmtmode("-- loading --");
  148.         strcpy(args, "load ");
  149.         strcat(args, argv [1]);
  150.         if (load(args) == TRUE) {
  151.             syswait();
  152.         }
  153.         else {
  154.             /* Preserve the signon message. */
  155.             bufout(1,1,2);
  156.             outxy(0,1);
  157.         }
  158.     }
  159.     else {
  160.         /* No file was loaded. Preserve the signon message. */
  161.         bufout(1,1,2);
  162.         outxy(0,1);
  163.     }
  164.  
  165.     /* Set the disk error recovery point. */
  166.     setjmp(DISK_ERR);
  167.     SL_SETJMP("main");
  168.  
  169.     /* Disable the again command. */
  170.     again_flag = FALSE;
  171.  
  172.     lastc = NULL;
  173.     holdc = NULL;
  174.     for (;;) {
  175.  
  176.         /* Update the mode on the prompt line. */
  177.         switch(mode) {
  178.         case EDITMODE:        pmtmode("edit:");    break;
  179.         case INSMODE:        pmtmode("insert:");    break;
  180.         case OVERMODE:        pmtmode("overtype:");    break;
  181.         case ESCAPEMODE:    pmtmode("escape:");    break;
  182.         case EXITMODE:        pmtmode("");
  183.                     outxy(0, SCRNL1);
  184.                     fmtcrlf();
  185.  
  186.                     TRACE("dump", sl_dump());
  187.                     RETURN_VOID("main");
  188.         }
  189.  
  190.         /* Get the next character. */
  191.         if (holdc != NULL) {
  192.             c = holdc;
  193.             holdc = NULL;
  194.         }
  195.         else {
  196.             c = syscin();
  197.         }
  198.  
  199.         /* Substitute the last command for the AGAIN key. */
  200.         if (c == AGAIN) {
  201.             c = lastc;
  202.         }
  203.  
  204.         /* Translate escapes and edit mode commands. */
  205.         if (mode == EDITMODE || mode == ESCAPEMODE) {
  206.             c = tolower(c);
  207.             switch(c) {
  208.             case ' ':    c = RIGHT;    break;
  209.             case 'b':    c = BOL;    break;
  210.             case 'd':    c = SCRN_DN;    break;
  211.             case 'e':    c = EOL;    break;
  212.             case 'h':    c = HOME_KEY;    break;
  213.             case 'g':    c = GOTO;    break;
  214.             case 'k':    c = KILL;    break;
  215.             case 'm':    c = MIDDLE;    break;
  216.             case 'p':    c = PAGE_DN;    break;
  217.             case 'q':    c = PAGE_UP;    break;
  218.             case 's':    c = SEARCH;    break;
  219.             case 'u':    c = SCRN_UP;    break;
  220.             case 'x':    c = XCHNG;    break;
  221.             case 'z':    c = END_KEY;    break;
  222.             case '-':
  223.                 /* Move up a half page. */
  224.                 edgo(max(0,bufln()-(SCRNL2/2)),0);
  225.                 break;
  226.             case '+':
  227.                 /* Move down a half page. */
  228.                 edgo(min(bufmax(),bufln()+(SCRNL2/2)),0);
  229.                 break;
  230.             default:
  231.                 break;
  232.             }
  233.         }
  234.  
  235.         /* Remember the what the last function was. */
  236.         lastc = c;
  237.  
  238.         /* Restore previous mode in escape mode. */
  239.         if (mode == ESCAPEMODE) {
  240.             mode = lastmode;
  241.         }
  242.  
  243.         /* Do the requested function. */
  244.         switch(c) {
  245.  
  246.         case NULL:    break;
  247.  
  248.         case CMND:    mode = command();
  249.                 break;
  250.  
  251.         case EDIT:    lastmode = mode = EDITMODE;
  252.                 break;
  253.  
  254.         case INS:    lastmode = mode = INSMODE;
  255.                 break;
  256.  
  257.         case OVER:    lastmode = mode = OVERMODE;
  258.                 break;
  259.  
  260.  
  261.         case ESCAPE:    lastmode = mode;
  262.                 mode = ESCAPEMODE;
  263.                 break;
  264.  
  265.         case UP_INS:    ednewup();
  266.                 lastmode = mode = def1mode;
  267.                 break;
  268.  
  269.         case DOWN_INS:    ednewdn();
  270.                 lastmode = mode = def1mode;
  271.                 break;
  272.  
  273.         case UP:    edup();
  274.                 mode = def2mode;
  275.                 break;
  276.  
  277.         case DOWN:    eddn();
  278.                 mode = def2mode;
  279.                 break;
  280.  
  281.         case LEFT:    edleft();    break;
  282.         case RIGHT:    edright();    break;
  283.         case WORD_F:    edfword();    break;
  284.         case WORD_B:    edbword();    break;
  285.  
  286.         case JOIN:    edjoin();    break;
  287.         case SPLIT:    edsplit();    break;
  288.         case UNDO:    edabt();    break;
  289.         case DEL1:    eddel();    break;
  290.         case DEL2:    ed2del();    break;
  291.         case ZAP:    edzap();    break;
  292.  
  293.         case VERBATIM:
  294.             pmtmode("verbatim:");
  295.             edins(syscin());
  296.             break;
  297.  
  298.         case SCRN_DN:
  299.             syswait();
  300.             while (chkkey() == FALSE) {
  301.                 eddn();
  302.                 if (bufnrbot()) {
  303.                     eddn();
  304.                     break;
  305.                 }
  306.             }
  307.             break;
  308.  
  309.         case PAGE_DN:
  310.             edgo(min(bufmax(),bufln()+(SCRNL1-outy)+SCRNL/2),0);
  311.             break;
  312.  
  313.         case PAGE_UP:
  314.             edgo(max(0,bufln()-outy-SCRNL/2+3),
  315.                  0);
  316.             break;
  317.  
  318.         case SCRN_UP:
  319.             syswait();
  320.             while (bufattop() == FALSE && chkkey() == FALSE) {
  321.                 edup();
  322.             }
  323.             break;
  324.  
  325.         case HOME_KEY:
  326.             edgo(max(0,bufln()-outy+1),0);
  327.             lastc = PAGE_UP;
  328.             break;
  329.  
  330.         case END_KEY:
  331.             edgo(min(bufmax(),bufln()+SCRNL1-outy),0);
  332.             lastc = PAGE_DN;
  333.             break;
  334.  
  335.         case MIDDLE:
  336.             edgo(min(bufmax(),bufln()+SCRNL1/2-outy+1),0);
  337.             break;
  338.  
  339.         case BOL:
  340.             edbegin();
  341.             lastc = HOME_KEY;
  342.             break;
  343.  
  344.         case EOL:
  345.             edend();
  346.             lastc = END_KEY;
  347.             break;
  348.  
  349.         case GOTO:
  350.             pmtmode("goto: ");
  351.             getcmnd(buffer);
  352.             if(number(buffer,&v)) {
  353.                 edgo(v, 0);
  354.             }
  355.             break;
  356.  
  357.         case KILL:
  358.             pmtmode("kill:");
  359.             c = syscin();
  360.             if (control(c)) {
  361.                 holdc = c;
  362.             }
  363.             else {
  364.                 edkill(c);
  365.             }
  366.             break;
  367.  
  368.         case SEARCH:
  369.             pmtmode("search:");
  370.             c = syscin();
  371.             if (control(c)) {
  372.                 holdc = c;
  373.             }
  374.             else {
  375.                 edsrch(c);
  376.             }
  377.             break;
  378.  
  379.         case XCHNG:
  380.             pmtmode("eXchange:");
  381.             edchng(syscin());
  382.             break;
  383.             
  384.         default:
  385.  
  386.             if (control(c)) {
  387.                 break;
  388.             }
  389.  
  390.             if (mode == INSMODE) {
  391.                 edins(c);
  392.             }
  393.             else if (mode == OVERMODE) {
  394.                 edchng(c);
  395.             }
  396.         }
  397.     }
  398. }
  399.  
  400. /*
  401.     Return TRUE if c is a control char.
  402. */
  403. static int
  404. control(char c)
  405. {
  406.     SL_DISABLE();
  407.  
  408.     return c != '\t' && (c >= 127 || c < 32);
  409. }
  410.  
  411. /*
  412.     Handle command mode.
  413. */
  414. static int
  415. command(void)
  416. {
  417.     int  k, v, junk;
  418.     char c;
  419.     char args [SCRNW1];
  420.     char *argp, *skipbl();
  421.     char tail[256];
  422.  
  423.     TICKB("command");
  424.  
  425.     /* Make sure the current line is saved. */
  426.     edrepl();
  427.  
  428.     pmtmode("command: ");
  429.     getcmnd(args);
  430.     c = args [0];
  431.  
  432.     switch(c) {
  433.     case EDIT:    RETURN_INT("command", EDITMODE);
  434.     case INS:    RETURN_INT("command", INSMODE);
  435.     case OVER:    RETURN_INT("command", OVERMODE);
  436.     }
  437.  
  438.     if (c == '!') {
  439.         outclr();        /* Clear the screen. */
  440.         outxy(0, 0);        /* Home cursor. */
  441.         sysexec(args+1);
  442.         pmtzap();
  443.         edclr();
  444.         edgo(bufln(), 0);
  445.     }
  446.     else if (lookup(args, "g")) {
  447.         args[0] = ' ';        /* quick fix for g<num> (no spaces) */
  448.         if (get3args(args, &v, -1, &junk, -1, &junk, -1) == OK) {
  449.             edgo(v, 0);
  450.         }
  451.     }
  452.     else if (lookup(args,"again") || lookup(args,"a")) {
  453.         again();
  454.     }
  455.     else if (lookup(args,"change") || lookup(args,"c")) {
  456.         change(args);
  457.     }
  458.     else if (lookup(args,"clear")) {
  459.         /* clear() conflicts with AZTEC func. */
  460.         clear1();
  461.         pmtfn();
  462.     }
  463.     else if (lookup(args,"copy")) {
  464.         copy(args);
  465.     }
  466.     else if (lookup(args,"def0ins")) {
  467.         def0mode = INSMODE;
  468.     }
  469.     else if (lookup(args,"def0over")) {
  470.         def0mode = OVERMODE;
  471.     }
  472.     else if (lookup(args,"def0edit")) {
  473.         def0mode = EDITMODE;
  474.     }
  475.     else if (lookup(args,"def1ins")) {
  476.         def1mode = INSMODE;
  477.     }
  478.     else if (lookup(args,"def1over")) {
  479.         def1mode = OVERMODE;
  480.     }
  481.     else if (lookup(args,"def1edit")) {
  482.         def1mode = EDITMODE;
  483.     }
  484.     else if (lookup(args,"def2ins")) {
  485.         def2mode = INSMODE;
  486.     }
  487.     else if (lookup(args,"def2over")) {
  488.         def2mode = OVERMODE;
  489.     }
  490.     else if (lookup(args,"def2edit")) {
  491.         def2mode = EDITMODE;
  492.     }
  493.     else if (lookup(args,"delete")) {
  494.         delete(args);
  495.     }
  496.     else if (lookup(args, "exit") || lookup(args, "x")) {
  497.         if (chkbuf() == TRUE) {
  498.             bufend();
  499.             RETURN_INT("command", EXITMODE);
  500.         }
  501.     }
  502.  
  503. #if 1 /* for debugging only */
  504.     else if (lookup(args,"dump")) {
  505.         bufdump();
  506.     }
  507. #endif
  508.  
  509.     else if (lookup(args,"extract")) {
  510.         extract(args);
  511.     }
  512.     else if (lookup(args, "findr") || lookup(args, "fr")) {
  513.         findr(args);
  514.     }
  515.     else if (lookup(args,"find") || lookup(args, "f")) {
  516.         find(args);
  517.     }
  518.     else if (lookup(args, "help")) {
  519.         help();
  520.     }
  521.     else if (lookup(args,"inject")) {
  522.         inject(args);
  523.     }
  524.     else if (lookup(args,"list")) {
  525.         list(args);
  526.     }
  527.     else if (lookup(args,"load") ||
  528.          lookup(args, "red") ||
  529.          lookup(args, "l")
  530.         ) {
  531.         load(args);
  532.         pmtfn();
  533.     }
  534.     else if (lookup(args,"move")) {
  535.         move(args);
  536.     }
  537.     else if (lookup(args,"name")) {
  538.         name(args);
  539.         pmtfn();
  540.     }
  541.     else if (lookup(args, "noword")) {
  542.         hasword = FALSE;
  543.     }
  544.     else if (lookup(args, "nowrap")) {
  545.         haswrap = FALSE;
  546.     }
  547.     else if (lookup(args,"resave") || lookup(args,"r")) {
  548.         resave();
  549.     }
  550.     else if (lookup(args,"rx")) {        /* RD 11/12/85 */
  551.         if (resave()) {
  552.             if (chkbuf() == TRUE) {
  553.                 bufend();
  554.                 RETURN_INT("command", EXITMODE);
  555.             }
  556.         }
  557.     }
  558.     else if (lookup(args,"save") || lookup(args,"sv")) {
  559.         save();
  560.     }
  561.     else if (lookup(args,"svx")) {
  562.         if (save()) {
  563.             if (chkbuf() == TRUE) {
  564.                 bufend();
  565.                 RETURN_INT("command", EXITMODE);
  566.             }
  567.         }
  568.     }
  569.     else if (lookup(args,"search") || lookup(args, "s")) {
  570.         search(args);
  571.     }
  572.  
  573. #ifdef SUSPEND
  574.     else if (lookup(args,"quit") || lookup(args, "q")) {
  575.         /* Make sure the file is named. */
  576.         if (g_file [0] == '\0') {
  577.             cmndmess("File not named.");
  578.         }
  579.         else {
  580.             bufsusp();
  581.             RETURN_INT("command", EXITMODE);
  582.         }
  583.     }
  584. #endif
  585.     else if (lookup(args,"tabs")) {
  586.         tabs(args);
  587.     }
  588.     else if (lookup(args, "word")) {
  589.         hasword = TRUE;
  590.     }
  591.     else if (lookup(args, "wrap")) {
  592.         haswrap = TRUE;
  593.     }
  594.     else if (lookup(args,"")) {
  595.         ;
  596.     }
  597.  
  598.     /* Do not exit. */
  599.     RETURN_INT("command", def0mode);
  600. }
  601.  
  602. /*
  603.     Return TRUE if line starts with command.
  604. */
  605. static int
  606. lookup(char *line, char *cmnd)
  607. {
  608.     SL_DISABLE();
  609.  
  610.     while(*cmnd) {
  611.         /* Watch out:  tolower may be a macro. */
  612.         if (tolower(*line) != *cmnd) {
  613.             return FALSE;
  614.         }
  615.         else {
  616.             line++;
  617.             cmnd++;
  618.         }
  619.     }
  620.     return    (*line == '\0' || *line == ' ' ||
  621.         *line == '\t' || isdigit(*line));
  622. }
  623.  
  624. /*
  625.     Get next command into argument buffer.
  626. */
  627. void
  628. getcmnd(char *args)
  629. {
  630.     int i, xpos, x, y;
  631.     int length;
  632.     char c;
  633.  
  634.     TRACEPB("getcmnd", sl_lpout(); sl_pout(args); sl_rpout());
  635.  
  636.     /* Remember the cursor position. */
  637.     x      = outx;
  638.     y      = outy;
  639.     xpos   = pmtlast();
  640.     outxy(xpos, 0);
  641.  
  642.     length = 0;
  643.     while ((c = syscin()) != '\r') {
  644.         pmtupd();
  645.  
  646.         if (c == EDIT || c == INS || c == OVER) {
  647.             args [0] = c;
  648.             length = 1;
  649.             break;
  650.         }
  651.  
  652.         if ( (c == DEL1 || c == LEFT) && length > 0) {
  653.             outxy(xpos, 0);
  654.             outdeol();
  655.             length--;
  656.             /* Redraw the field. */
  657.             for (i = 0; i < length; i++) {
  658.                 if (args [i] == '\t') {
  659.                     outchar(' ');
  660.                 }
  661.                 else {
  662.                     outchar(args [i]);
  663.                 }
  664.             }
  665.         }
  666.         else if (c == UNDO) {
  667.             outxy(xpos, 0);
  668.             outdeol();
  669.             length = 0;
  670.         }
  671.         else if (c == '\t' && length + xpos < SCRNW1) {
  672.             args [length++] = '\t';
  673.             outchar(' ');
  674.         }
  675.         else if (c < 32 || c == 127) {
  676.             /* Ignore control characters. */
  677.             continue;
  678.         }
  679.         else {
  680.             if (length + xpos < SCRNW1) {
  681.                 args [length++] = c;
  682.                 outchar(c);
  683.             }
  684.         }
  685.     }
  686.     args [length] = '\0';
  687.  
  688.     /* Restore the cursor. */
  689.     outxy(x, y);
  690.  
  691.     TICKX("getcmnd");
  692. }
  693.