home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / reader.c < prev    next >
C/C++ Source or Header  |  1998-08-01  |  10KB  |  443 lines

  1.  
  2. // LoraBBS Version 2.41 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <stdio.h>
  20. #include <conio.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include <alloc.h>
  24. #include <io.h>
  25. #include <fcntl.h>
  26.  
  27. #include <cxl\cxlvid.h>
  28. #include <cxl\cxlwin.h>
  29. #include <cxl\cxlstr.h>
  30. #include <cxl\cxlkey.h>
  31.  
  32. #include "lsetup.h"
  33. #include "sched.h"
  34. #include "msgapi.h"
  35. #include "externs.h"
  36. #include "prototyp.h"
  37.  
  38. void VioUpdate (void);
  39.  
  40. #define MAX_COLS  128
  41.  
  42. typedef unsigned bit;
  43.  
  44. typedef struct _ptrch {
  45.    char *row;
  46.    void *next;
  47.    void *prev;
  48.    int   len;
  49.    bit   wrapped :1;
  50. } CHAIN;
  51.  
  52. int ccol, ofsrow, crow, normcolor = LGREY|_BLACK;
  53. char editrow[MAX_COLS], headline[MAX_COLS];
  54. CHAIN *ptr, *top;
  55.  
  56. int isok (char c)
  57. {
  58.    return (isalnum (c) || c == '_');
  59. }
  60.  
  61. char *my_strtok (char *s1, char *s2)
  62. {
  63.     static char *Ss;
  64.     char *tok, *sp;
  65.  
  66.     if (s1 != NULL)
  67.        Ss = s1;
  68.  
  69.     while (*Ss) {
  70.         for (sp = s2; *sp; sp++)
  71.             if (*sp == *Ss)
  72.                 break;
  73.         if (*sp == 0)
  74.             break;
  75.         Ss++;
  76.     }
  77.     if (*Ss == 0)
  78.         return (NULL);
  79.     tok = Ss;
  80.     while (*Ss) {
  81.         for (sp = s2; *sp; sp++)
  82.             if (*sp == *Ss) {
  83.                 Ss++;
  84.                 return (tok);
  85.             }
  86.         Ss++;
  87.     }
  88.     return (tok);
  89. }
  90.  
  91. void display_screen_viewer (CHAIN *start, int rows, int startcol)
  92. {
  93.    int i;
  94.    CHAIN *tmp;
  95.    char tmpstr[MAX_COLS], *p;
  96.  
  97.    i = 0;
  98.    tmp = ptr;
  99.    while (tmp != start) {
  100.       i++;
  101.       tmp = tmp->next;
  102.    }
  103.  
  104.    wgotoxy (0, 0);
  105.    wclreol ();
  106.    if (strlen (headline) > startcol)
  107.       wprints (0, 0, RED|_LGREY, &headline[startcol]);
  108.  
  109.    wgotoxy (i + ofsrow, 0);
  110.    wclreos ();
  111.  
  112.    for (; i < rows; i++) {
  113.       strncpy (tmpstr, (char *)tmp->row, tmp->len);
  114.       tmpstr[tmp->len] = '\0';
  115.       if ((p = strchr (tmpstr, '\r')) != NULL)
  116.          *p = '\0';
  117.       if (strlen (tmpstr) >= startcol)
  118.          wprints (i + ofsrow, 0, normcolor, &tmpstr[startcol]);
  119.       if (tmp->next == NULL)
  120.          break;
  121.       tmp = (CHAIN *)tmp->next;
  122.    }
  123. }
  124.  
  125. int rowcount (CHAIN *start)
  126. {
  127.    int i;
  128.    CHAIN *tmp;
  129.  
  130.    tmp = start;
  131.  
  132.    for (i = 0; i < 26; i++) {
  133.       if (tmp->next == NULL)
  134.          break;
  135.       tmp = (CHAIN *)tmp->next;
  136.    }
  137.  
  138.    return (i + 1);
  139. }
  140.  
  141. char *strtrim(char *str)
  142. {
  143.    register int i;
  144.  
  145.    for (i = strlen (str) - 1; str[i] == ' ' && i >= 0; i--)
  146.       ;
  147.    str[i + 1] = '\0';
  148.  
  149.    return (str);
  150. }
  151.  
  152. void build_ptr_list (CHAIN *ptr)
  153. {
  154.    char *p, *txtptr;
  155.    CHAIN *tmp, *cpos;
  156.  
  157.    txtptr = ptr->row;
  158.    if (*txtptr == '\r') {
  159.       ptr->row = txtptr;
  160.       ptr->len = 2;
  161.    }
  162.    else
  163.       ptr->row = NULL;
  164.  
  165.    if ((p = my_strtok (txtptr, "\r")) == NULL) {
  166.       ptr->row = txtptr;
  167.       ptr->len = strlen (ptr->row);
  168.  
  169.       if (ptr->next != NULL) {
  170.          cpos = ptr->next;
  171.          ptr->next = NULL;
  172.          do {
  173.             tmp = cpos->next;
  174.             free (cpos);
  175.             cpos = tmp;
  176.          } while (cpos != NULL);
  177.       }
  178.  
  179.       return;
  180.    }
  181.  
  182.    do {
  183.       if (*p == '\0')
  184.          break;
  185.       if (*p == '\n')
  186.          p++;
  187.  
  188.       if (ptr->row == NULL)
  189.          ptr->row = p;
  190.       else if (ptr->next != NULL) {
  191.          tmp = ptr->next;
  192.          tmp->prev = ptr;
  193.          tmp->row = p;
  194.          ptr->next = tmp;
  195.          ptr->len = (int)(p - ptr->row);
  196.          ptr = tmp;
  197.       }
  198.       else {
  199.          if ((tmp = (CHAIN *)malloc (sizeof (CHAIN))) == NULL)
  200.             break;
  201.          tmp->wrapped = 0;
  202.          tmp->next = NULL;
  203.          tmp->prev = ptr;
  204.          tmp->row = p;
  205.          ptr->next = tmp;
  206.          ptr->len = (int)(p - ptr->row);
  207.          ptr = tmp;
  208.       }
  209.    } while ((p = my_strtok (NULL, "\r")) != NULL);
  210.  
  211.    ptr->len = strlen (ptr->row);
  212.  
  213.    if (ptr->next != NULL) {
  214.       cpos = ptr->next;
  215.       ptr->next = NULL;
  216.       do {
  217.          tmp = cpos->next;
  218.          free (cpos);
  219.          cpos = tmp;
  220.       } while (cpos != NULL);
  221.    }
  222. }
  223.  
  224. void view_file (char *file, int rows, int cols)
  225. {
  226.    int fd, i, startcol, endcol;
  227.    char *txtptr;
  228.    unsigned int maxsize;
  229.    CHAIN *tmp, *cpos;
  230.  
  231.    hidecur ();
  232.  
  233.    if ((fd = open (file, O_RDONLY|O_BINARY)) != -1) {
  234.       maxsize = (unsigned int)filelength (fd);
  235.       if ((txtptr = malloc (maxsize)) == NULL)
  236.          return;
  237.       memset (txtptr, 0, maxsize);
  238.       read (fd, txtptr, maxsize);
  239.       close (fd);
  240.    }
  241.  
  242.    txtptr[maxsize] = '\0';
  243.  
  244.    top = (CHAIN *)malloc (sizeof (CHAIN));
  245.    top->wrapped = 0;
  246.    ptr = top;
  247.    top->next = top->prev = NULL;
  248.    top->row = txtptr;
  249.    build_ptr_list (top);
  250.    ptr = top;
  251.  
  252.    strncpy (headline, top->row, top->len);
  253.    if (top->len > 2)
  254.       headline[top->len - 2] = '\0';
  255.    else
  256.       headline[0] = '\0';
  257.    top = top->next;
  258.    free (ptr);
  259.    top->prev = NULL;
  260.    cpos = tmp = ptr = top;
  261.  
  262.    endcol = startcol = crow = ccol = 0;
  263.    while (tmp != NULL) {
  264.       if ((tmp->len - 2) > endcol)
  265.          endcol = tmp->len - 2;
  266.       tmp = tmp->next;
  267.    }
  268.    tmp = top;
  269.    display_screen_viewer (ptr, rows, startcol);
  270.  
  271.    for (;;) {
  272.       VioUpdate ();
  273.       while (!kbmhit ())
  274.          release_timeslice ();
  275.  
  276.       i = getxch ();
  277.       if ((i & 0xFF) == 0x1B)
  278.          break;
  279.  
  280.       switch (i) {
  281.          // Home
  282.          case 0x4700:
  283.             if (startcol) {
  284.                startcol = 0;
  285.                display_screen_viewer (ptr, rows, startcol);
  286.             }
  287.             break;
  288.  
  289.          // ^PgUp
  290.          case 0x8400:
  291.             if (ptr != top) {
  292.                ptr = top;
  293.                startcol = 0;
  294.                display_screen_viewer (ptr, rows, startcol);
  295.             }
  296.             break;
  297.  
  298.          // PgUp
  299.          case 0x4900:
  300.             tmp = ptr;
  301.             for (i = 0; i < rows; i++) {
  302.                if (tmp->prev == NULL)
  303.                   break;
  304.                tmp = tmp->prev;
  305.             }
  306.             if (i >= rows) {
  307.                ptr = tmp;
  308.                display_screen_viewer (ptr, rows, startcol);
  309.             }
  310.             else if (ptr != top) {
  311.                ptr = top;
  312.                display_screen_viewer (ptr, rows, startcol);
  313.             }
  314.             break;
  315.  
  316.          // Up
  317.          case 0x4800:
  318.             if (ptr->prev != NULL) {
  319.                ptr = ptr->prev;
  320.                display_screen_viewer (ptr, rows, startcol);
  321.             }
  322.             break;
  323.  
  324.          // Down
  325.          case 0x5000:
  326.             if (rowcount (ptr) > rows && ptr->next != NULL) {
  327.                ptr = ptr->next;
  328.                display_screen_viewer (ptr, rows, startcol);
  329.             }
  330.             break;
  331.  
  332.          // PgDn
  333.          case 0x5100:
  334.             tmp = ptr;
  335.             for (i = 0; i < rows; i++) {
  336.                if (tmp->next == NULL)
  337.                   break;
  338.                tmp = tmp->next;
  339.             }
  340.             if (i >= rows) {
  341.                ptr = tmp;
  342.                display_screen_viewer (ptr, rows, startcol);
  343.             }
  344.             break;
  345.  
  346.          // End
  347.          case 0x4F00:
  348.             if (endcol > cols) {
  349.                startcol = endcol - cols;
  350.                display_screen_viewer (ptr, rows, startcol);
  351.             }
  352.             break;
  353.  
  354.          // ^PgDn
  355.          case 0x7600:
  356.             if (rowcount (ptr) > rows) {
  357.                while (rowcount (ptr) > rows) {
  358.                   ptr = ptr->next;
  359.                   if (cpos->next != NULL)
  360.                      cpos = cpos->next;
  361.                }
  362.  
  363.                while (cpos->next != NULL) {
  364.                   cpos = cpos->next;
  365.                   crow++;
  366.                }
  367.  
  368.                cpos = cpos->prev;
  369.                crow--;
  370.  
  371.                ccol = cpos->len - 2;
  372.                if (ccol > cols - 1)
  373.                   startcol = ccol - cols + 1;
  374.                else if (ccol < startcol)
  375.                   startcol = ccol;
  376.  
  377.                display_screen_viewer (ptr, rows, startcol);
  378.             }
  379.             break;
  380.  
  381.          // ->
  382.          case 0x4D00:
  383.             if (startcol + cols < endcol) {
  384.                startcol++;
  385.                display_screen_viewer (ptr, rows, startcol);
  386.             }
  387.             break;
  388.  
  389.          // <-
  390.          case 0x4B00:
  391.             if (startcol) {
  392.                startcol--;
  393.                display_screen_viewer (ptr, rows, startcol);
  394.             }
  395.             break;
  396.  
  397.          default:
  398.             break;
  399.       }
  400.    }
  401.  
  402.    ptr = tmp = top;
  403.  
  404.    for (;;) {
  405.       tmp = tmp->next;
  406.       free (ptr);
  407.       if ((ptr = tmp) == NULL)
  408.          break;
  409.    }
  410.  
  411.    free (txtptr);
  412. }
  413.  
  414. void display_history (int in)
  415. {
  416.    char string[88];
  417.  
  418.    if (in)
  419.       sprintf (string, "%sINBOUND.HIS", config->sys_path);
  420.    else
  421.       sprintf (string, "%sOUTBOUND.HIS", config->sys_path);
  422.  
  423.    if (!dexists (string)) {
  424.       wopen (11, 20, 15, 58, 0, BLACK|_LGREY, BLACK|_LGREY);
  425.       wshadow (DGREY|_BLACK);
  426.       wcenters (1, BLACK|_LGREY, "Unable to read history file");
  427.       timer (20);
  428.       wclose ();
  429.       return;
  430.    }
  431.  
  432.    normcolor = BLUE|_LGREY;
  433.    wopen (7, 2, 22, 76, 0, RED|_LGREY, normcolor);
  434.    wtitle (in ? "INBOUND HISTORY" : "OUTBOUND HISTORY", TLEFT, RED|_LGREY);
  435.    wshadow (DGREY|_BLACK);
  436.  
  437.    ofsrow = 1;
  438.    view_file (string, 14, 73);
  439.  
  440.    wclose ();
  441. }
  442.  
  443.