home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 361_01 / mso.c < prev    next >
Text File  |  1991-09-20  |  6KB  |  214 lines

  1.  
  2. /* MSO --> MOREd lists w/ Selection & Output
  3.  *
  4.  * J.Ekwall 27 November 89
  5.  *
  6.  * Copyrighted to the Public Domain.  Unlimited Distribution Authorized.
  7.  *
  8.  * User Assumes All Risks/Liabilities.
  9.  *
  10.  */
  11.  
  12. #include <ctype.h>
  13. #include <gadgets.h>
  14. #include <keys.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <stdek.h>
  19.  
  20. char *Documentation[] = {
  21.     "",
  22.     "Usage:",
  23.     "       MSO [options] [file] ---> Present a List & Output Selection(s).",
  24.     "",
  25.     "  Note: $Pipes are Legal in \"file\" Name.",
  26.     "",
  27.     "Options:",
  28.     "         /Cn ---> Specify # of Columns Displayed [n = 1-4;D:4]",
  29.     "         /N ----> Prefix Selections w/ Item Line Numbers.",
  30.     "         /R ----> Multiple Selections Permitted.",
  31.     "",
  32.     "   MSO may be Piped In/Out w/o Disrupting List Display/Selection.",
  33.     "",
  34.     "Last Update: 20 September 91/EK",
  35.     "",
  36.     NULL};
  37.  
  38. /* Declare Golbals */
  39. int CleanUp = FALSE;
  40. int Offset = 1, Bins = 4, Last_Item =  2500;
  41. char Text[32500], *Item[2502], Name[81], FootPrint[4000];
  42. FILE *fp = stdin;
  43.  
  44. /* Declare ProtoTypes */
  45. int  Choose(int);
  46. void Tload(FILE *);
  47. void Usage(void);
  48.  
  49. main (int argc, char *argv[])
  50. {
  51.     int c, i, Repeats = FALSE, Number = FALSE;
  52.     int xx, yy;
  53.     char *tp1;
  54.  
  55.  /* Set Option Flags */
  56.     while (*argv[1] IS SLASH) {
  57.        for (tp1 = argv[1] + 1; *tp1 != NULL; ) {
  58.           switch (toupper(*tp1++)) {
  59.           case 'C':
  60.              c = *tp1++; if ((c < '1') || (c > '4')) Usage();
  61.              Bins = c - 48; break;
  62.           case 'R':
  63.              Repeats = TRUE; break;
  64.           case 'N':
  65.              Number = TRUE; break;
  66.           }
  67.        }
  68.  
  69.     /* SHIFT */
  70.        for (i = 1, --argc; i < argc + 1; i++) argv[i] = argv[i+1];
  71.     }
  72.     if (argc > 2) Usage();
  73.     if (argc IS 2)
  74.        if (*argv[1] IS '$') {
  75.           strcpy(Name,"\\STD "); strcat(Name,++argv[1]);
  76.           if ((fp = fopen(Name,"r")) IS NULL) { perror(Name); exit(1); }
  77.           CleanUp = TRUE;
  78.        } else {
  79.           strcpy(Name,argv[1]);
  80.           if ((fp = fopen(Name,"r")) IS NULL) { perror(Name); Usage(); }
  81.           CleanUp = FALSE;
  82.        }
  83.  
  84.  
  85.  /* Check for Pipe on Stdin */
  86.     if (!INFLOW_EXISTS && fp IS stdin) Usage();
  87.  
  88.  /* Load Text Buffer */
  89.     Getxy(&xx, &yy); SaveBox(1, 1, 80, 25, FootPrint);
  90.     fprintf(stderr,"\nLoading List Buffer.  Please Wait.");
  91.     Tload(fp);
  92.  
  93.  /* Display Lists & Capture User Selection */
  94.     for(i = 0; (i = Choose(i)) != 0; ) {
  95.        if (i < 0) continue;
  96.        if (Number IS TRUE) printf("%d  ", i);  /* Prefix Line # */
  97.        for (tp1 = Item[i] + 2; ; ) { putchar(*tp1); if (*tp1++ IS NL) break; }
  98.        if (!Repeats) break;
  99.     }
  100.     RestoreBox(1, 1, 80, 25, FootPrint); Gotoxy(xx, yy); ShowCursor(0);
  101.     if (CleanUp IS TRUE) unlink(Name);    /* DEL $Pipe */
  102.     exit(OK);
  103. }
  104.  
  105. int Choose(int Flag)
  106. {
  107.     int c, j, Dx = 0, xx, yy;
  108.     char *tp1, Text[81];
  109.     static int i, Offset = 0, X = 1, Y = 1;
  110.  
  111.  /* Set Initial Conditions */
  112.     switch (Bins) {
  113.     case 1: Dx = 40;
  114.     case 2: Dx += 14;
  115.     case 3: Dx += 6;
  116.     case 4: Dx += 20;
  117.     }
  118.  
  119.  /* Don't RePaint on Multi-Selections */
  120.     if (Flag > 0) goto ReRun;
  121.  
  122.  /* Clear & Goto Bottom & Set White on Blue & Do Banner */
  123.     HideCursor(); Clr(0x0A); RcolorSet(1, 25, 0x1F, 80);
  124.     Dwrite(33, 25, 0x1F, "Pg Up/Dwn        ESC to Quit.");
  125.     Gotoxy(1, 1);
  126.  
  127.  /* Display/ReDisplay a Page of Text w/ Banner */
  128.     for (X = 1, i = 1; X < 75; X += Dx) {
  129.        for (Y = 1; Y < 25; Y++) {
  130.           if ((Offset + i) > Last_Item) break;
  131.           tp1 = Item[Offset + i]; Gotoxy(X, Y);
  132.           tp1 = strchr(tp1, NL); *tp1 = NULL;
  133.           Dwrite(X, Y, 0x0A, Item[Offset + i++]); *tp1 = NL;
  134.        }
  135.     }
  136.  
  137.  /* Do MORE & Set Yellow ">" on First Item */
  138.     if ((Offset + i) < Last_Item) Dwrite(1, 25, 0x1F, "  --- More --- ");
  139.     Dwrite(2, 1, 0x0E, ">");
  140.  
  141.  /* Get User's Input(s) */
  142.      X = Y = 1;
  143. ReRun:
  144.     for ( j = Offset; j IS Offset; ) {
  145.        switch (toupper(Kbq_read())) {
  146.        case UP:     if ( Y > 1) Y--; break;
  147.        case DN:     if (Y < 24) Y++; break;
  148.        case TAB:
  149.        case FWD:    if (X + Dx < 75) X += Dx; break;
  150.        case BS:
  151.        case BWD:    if (X > 1) X -= Dx; break;
  152.        case HOME:   Offset = 0;
  153.        case PGUP:   Offset -= 24 * Bins; if (Offset < 0) Offset = 0; break;
  154.        case END:    Offset = 2000;
  155.        case SPACE:
  156.        case PGDN:  
  157.           Offset += 24 * Bins;
  158.           if (Offset > Last_Item - 24 * Bins) Offset = Last_Item - 24 * Bins;
  159.           if (Offset < 0) Offset = 0; break;
  160.        case 'Q':
  161.        case ESC:  return(0);
  162.        case CR:   /* Select */
  163.           i = Offset + (X / Dx) * 24 + Y;
  164.           if (i > Last_Item) break;
  165.           Dwrite(X, Y, 0x0E, "-"); *Item[i] = '-';
  166.           return(i);
  167.        }
  168.        Getxy(&xx, &yy); Dwrite(xx-1, yy, 0x0A, " ");
  169.        Dwrite(X+1, Y, 0x0E, ">");
  170.     }
  171.     return(-1);
  172. }
  173.  
  174. void Tload(FILE *File)
  175. {
  176.     int c, i, x, Mx, Skip_Flag = FALSE;
  177.     char *tp1, *tp2;
  178.  
  179.  /* Set Max Item Length */
  180.     switch (Bins) {
  181.     case 1: { Mx = 77; break; }
  182.     case 2: { Mx = 37; break; }
  183.     case 3: { Mx = 23; break; }
  184.     case 4: { Mx = 17; break; }
  185.     }
  186.  
  187.  /* Load Text Buffer */
  188.     tp1 = Text, tp2 = Text + 32495, Item[(i = 1)] = tp1, x = 0;
  189.     for (*tp1++ = SPACE, *tp1++ = SPACE; (c = getc(File)) != EOF; ) {
  190.        if (c != NL) {
  191.           if (Skip_Flag IS TRUE) continue;
  192.           *tp1++ = c;
  193.           if (tp1 > tp2) {
  194.              *tp1++ = NL; *tp1 = NULL;
  195.              fprintf(stderr,"Buffer Overflow."); Last_Item = i - 1; return; }
  196.           if (x++ IS Mx) Skip_Flag = TRUE;
  197.           continue;
  198.        }
  199.        *tp1++ = NL; *tp1 = NULL; Skip_Flag = FALSE; x = 0; Item[++i] = tp1;
  200.        *tp1++ = SPACE, *tp1++ = SPACE;
  201.        if (i > 2500) { fprintf(stderr,"Items 2500+ Skipped."); break; }
  202.     }
  203.     if ((Last_Item = i - 1) < 1) exit(1);
  204. }
  205.  
  206. void Usage(void)
  207. {
  208.     char   **dp = Documentation;
  209.  
  210.     for ( ; *dp; dp++) fprintf(stderr,"%s\n", *dp);
  211.     exit(1);
  212. }
  213.  
  214.