home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / most423.zip / line.c < prev    next >
C/C++ Source or Header  |  1994-01-28  |  11KB  |  399 lines

  1. #include <stdio.h>
  2. #include "buffer.h"
  3. #include "externs.h"
  4. #include "display.h"
  5. #include "line.h"
  6.   
  7. extern int COLUMN;
  8. int TAB_LENGTH = 8;
  9.  
  10. #define MAX_LINE_LEN 500
  11. int MOST_S_OPT = 0;
  12. /* take 16 binary characters and put them in displayable form */
  13. int ascii_format_line(char *buff, char *str, int max)
  14. {
  15.     int i,ii,j,k,ch,di,flag;
  16.     char num_str[4];
  17.    register char *s, *smax;
  18.    
  19.     ii = 0;
  20.     di = 40;
  21.     flag = 1;
  22.  
  23.    s = str;
  24.    smax = s + 80; while (s < smax) 
  25.      {
  26.     *s++ = ' '; *s++ = ' '; *s++ = ' '; *s++ = ' ';
  27.      }
  28.    
  29.     
  30.     for (j = 0; j < 4; j++)
  31.       {
  32.           
  33.           for (k = 0; k < 4; k++)
  34.             {
  35.                 i = 4 * j + k;
  36.            if (i >= max) break;
  37.            
  38.                 ch = buff[i];
  39.                 if (MOST_V_OPT)
  40.                   {
  41.                       if (((ch < 32) && (ch >= 0)) || (ch == 127))
  42.                         {
  43.                             str[ii++] = '^';
  44.                             if (ch == 127)
  45.                               str[ii++] = '?';
  46.                             else
  47.                               str[ii++] = ch + 'A' - 1;
  48.                             str[i + di] = '.';
  49.                         }
  50.                       else if (ch < 0)
  51.                         {
  52.                             ch = ch + 256; 
  53.                             sprintf(num_str,"%02X", ch);
  54.                             str[ii++] = num_str[0];
  55.                             str[ii++] = num_str[1];
  56.                             str[i + di] = '.';
  57.                         }
  58.                       else
  59.                         {
  60.                             str[ii++] = ' ';
  61.                             str[ii++] = ch;
  62.                             str[i + di] = ch;
  63.                         }
  64.                   }
  65.                 else
  66.                   {
  67.                       if (ch < 32)
  68.                         {
  69.                             if (ch < 0) ch = ch + 256;
  70.                             str[i + di] = '.';
  71.                         }
  72.                       else str[i+di] = ch;
  73.                       
  74.                       sprintf(num_str,"%02X", ch);
  75.                       str[ii++] = num_str[0];
  76.                       str[ii++] = num_str[1];
  77.                   }
  78.                 
  79.             } /* k */
  80.           str[ii++] = ' ';
  81.       }
  82.     di += 16;
  83.     str[di] = '\0';
  84.     return(di);
  85. }
  86.     
  87.  
  88. int analyse_line(unsigned char *begg, unsigned char *endd, char *out, char *attributes)
  89. {
  90.    register unsigned char *beg = begg, *end = endd, ch;
  91.    register int ii;
  92.    int test, fold, ii_max, j, ok;
  93.    char attr;
  94.  
  95.     test = 0;
  96.     ii = 0;
  97.     ii_max = 0;
  98.     fold = 0;
  99.     while(ch = *beg, (beg <= end) && (ch != '\n') && (ch != '\0'))
  100.       {
  101.           beg++;
  102.           if (ii > ii_max) fold = 0;  /* beyond previous high */
  103.           attr = ' ';
  104.      
  105.           /*
  106.           **  set up bolding of line if ^M
  107.           */
  108.           if (!MOST_V_OPT && ch == '\015')                   /* ^M */
  109.             {
  110.                 if (beg <= end)
  111.                   {
  112.                       fold = 1;
  113.                       if (ii > ii_max) ii_max = ii - 1; /* ^M contributes nil */
  114.                       ii = 0;
  115.                   }
  116.             }
  117.  
  118.           /*
  119.           **  set up bolding or underlining of character if '\b' (^H)
  120.           */
  121.           else if (!MOST_V_OPT && (ch == '\b') && (ii != 0))
  122.             {
  123.                 test = 1;
  124.                 ii--;
  125.             }
  126.           /*
  127.           **  assign bolding or underlining attributes
  128.           */
  129.           else if (test || fold)
  130.             {
  131.                 test = 0;
  132.                 if (ch == (unsigned char) out[ii])
  133.                   attr = 'b';
  134.                 else if (out[ii] == '_')
  135.                   attr = 'u';
  136.  
  137.                 if (fold && ch == ' ')
  138.                   ii++;
  139.                 else
  140.                   {
  141.                       attributes[ii] = attr;
  142.                       out[ii++] = ch;
  143.                   }
  144.                 
  145.             }
  146.           else if (!MOST_T_OPT && ch == '\t')
  147.             {
  148.                 j = TAB_LENGTH * (ii/TAB_LENGTH + 1) - ii;  /* TAB_LENGTH column tabs */
  149.                 while(j--)
  150.                   {
  151.                       out[ii] = ' ';
  152.                       attributes[ii++] = attr;
  153.                   }
  154.             }
  155.           else
  156.             {
  157.                 out[ii] = ch;
  158.                 attributes[ii++] = attr;
  159.             }
  160.       }
  161.     if (fold) ii = ii_max + 1;
  162.     if ((beg > end) && MOST_S_OPT && !MOST_W_OPT)
  163.       {
  164.           ok = 1;
  165.           if (*beg == '\n') beg++;
  166.           while ((*beg <= ' ') && ok)
  167.             {
  168.                 if (*beg != '\n') beg++;
  169.                 if (beg >= EOB) break;
  170.                 if ((*beg == '\n') || (apparant_distance(beg) >= MOST_S_OPT))
  171.                   {
  172.                       ok = 0;
  173.                   }
  174.             }
  175.           if (!ok)
  176.             {
  177.                 ok = 3;
  178.                 while(ok--)
  179.                   {
  180.                       out[ii] = '.'; 
  181.                       attributes[ii++] = ' ';
  182.                   }
  183.             }
  184.           
  185.       } /* MOST_S_OPT */
  186.     out[ii] = '\0';
  187.     return(ii);
  188. }
  189.  
  190.  
  191. void output(char *line, int len, char *attr, char d_char)
  192. {
  193.    register int i, ii;
  194.    register char ch;
  195.     int
  196.       k, bold,b_len,n_len, s_len, u_len, work_len, j, mark, ok, quit,
  197.       count, max_col, save, dollar;
  198.     char at, out[500], *n_str, *b_str, *s_str, *u_str, work[20];
  199.  
  200.    b_str = TT_BOLD_STR; 
  201.    n_str = TT_NORM_STR;
  202.    u_str = TT_ULIN_STR;
  203.    s_str = CURS_F_STR;
  204.    b_len = (b_str == NULL) ? 0 : strlen(b_str);
  205.    n_len = (n_str == NULL) ? 0 : strlen(n_str);
  206.    u_len = (u_str == NULL) ? 0 : strlen(u_str);
  207.    s_len = (s_str == NULL) ? 0x7FFF : strlen(s_str);
  208.     i = 0;
  209.     ii = 0;
  210.     bold = 0;
  211.     quit = 0;
  212.     ok = 0;  /* 1 if ok to start filling the out line */
  213.     max_col = COLUMN + SCREEN_WIDTH - 1;
  214.     count = 0;
  215.     dollar = 0;
  216.     while (ch = line[i], (i <= len) && ch != '\0' && ch != '\n' && !quit)
  217.       {
  218.           count++;
  219.      if (MOST_V_OPT && ((ch < ' ') || (ch > 126))) count++;
  220.      else if (ch == 19) count++; /* ^S */
  221.           
  222.           if (count >= COLUMN) ok = 1;
  223.           if (count > max_col) break;
  224.           
  225.           if (!MOST_V_OPT)
  226.             {
  227.                 at = attr[i];
  228.                 if ((at != ' ') && !bold)
  229.                   {
  230.                       bold = 1;
  231.                       /* u and b have same length */
  232.                       if (ok) for (j = 0; j < b_len; j++)
  233.                         {
  234.                             if (at == 'b') out[ii++] = b_str[j];
  235.                             else out[ii++] = u_str[j];
  236.                         }
  237.                       
  238.                   }
  239.                 else if ((at == ' ') && bold)
  240.                   {
  241.                       bold = 0;
  242.                       if (ok) for (j = 0; j < n_len; j++) out[ii++] = n_str[j];
  243.                   }
  244.             }
  245.           
  246.           if (ch == ' ')
  247.             {
  248.                 j = 0;
  249.                 mark = ii;
  250.                 /* we always make this loop once */
  251.                 while ((i <= len) && (line[i++] == ' '))
  252.                   {
  253.                       j++;
  254.                       if (ok) out[ii++] = ' ';
  255.                   }
  256.                 if (i > len) quit = 1;
  257.                 i = i - 2;
  258.                 save = count;
  259.                 count += j - 1;  /* counted one at top of while */
  260.  
  261.                 if (!ok)
  262.                   {
  263.                       if (count >= COLUMN)
  264.                         {
  265.                             ok = 1;
  266.                             j = count - COLUMN + 1;
  267.                             k = j;
  268.                             while (k--) out[ii++] = ' ';
  269.                         }
  270.                   }
  271.                 
  272.                 if (count >= max_col)
  273.                   {
  274.                       quit = 1;
  275.                       j = max_col - save;
  276.                   }
  277.                 
  278.                 if (ok && (j > s_len)) 
  279.                   {
  280.                       ii = mark;
  281.              tt_sprintf(work,s_str,j, 0);
  282.                       work_len = strlen(work);
  283.                       for (j = 0; j < work_len; j++) out[ii++] = work[j];
  284.                       if (count >= max_col) dollar = ii++;
  285.                   }
  286.                 else if (count >= max_col)
  287.                   {
  288.                       dollar = mark + j;
  289.                   }
  290.                 
  291.             }
  292.           else if (ok && ((ch == '\014') || (ch == 19)
  293.               || ((ch < ' ') && MOST_V_OPT)))
  294.             {
  295.                 out[ii++] = '^';
  296.                 out[ii++] = ch + 'A' - 1;
  297.             }
  298.           else if (ok) 
  299.             {
  300.                 out[ii++] = ch;
  301.             }
  302.           
  303.           i++;
  304.       }
  305.     if (dollar) out[ii = dollar, ii++] = d_char;
  306.     else if (ok && count >= max_col) out[ii - 1] = d_char;
  307.     out[ii] = '\0';
  308.     if (ii) send_string_to_term(out);
  309.     
  310.     if (ok && bold) send_string_to_term(n_str);
  311. }
  312.  
  313.  
  314. void display_line()
  315. {
  316.     unsigned char *beg, *end;
  317.     int i, len, v = 0, t = 0;
  318.     char buff[16];
  319.     char the_line[MAX_LINE_LEN],  the_attr[MAX_LINE_LEN], *line,*attr, ch;
  320.     line = the_line;
  321.     attr = the_attr;
  322.     /* This needs fixed for files with really big lines */
  323.     if (!MOST_B_OPT)
  324.       {
  325.           if(extract_line(&beg, &end) && MOST_W_OPT) ch = '\\'; else ch = '$';
  326.           
  327.           len = end - beg + 1;
  328.           if (len > MAX_LINE_LEN)
  329.             {
  330.                 v = MOST_V_OPT;
  331.                 t = MOST_T_OPT;
  332.                 MOST_V_OPT = 1;
  333.                 MOST_T_OPT = 1;
  334.                 line = (char *) beg;
  335.             }
  336.           else len = analyse_line(beg, end, line, attr);
  337.       }
  338.     else
  339.       {
  340.           ch = '$';
  341.           i = 0;
  342.           beg = C_POS;
  343.           end = C_POS + 16;
  344.           if (end > EOB) end = EOB;
  345.           while(beg < end) buff[i++] = (char) *beg++;
  346.           /* while(i < 15) buff[i++] = 0; */
  347.           len = ascii_format_line(buff,the_line, i);
  348.           i = 0; while(i<80) attr[i++] = ' ';
  349.       }
  350.     
  351.     
  352.     output(line,len,attr, ch);
  353.     if (len > MAX_LINE_LEN)
  354.       {
  355.           MOST_V_OPT = v;
  356.           MOST_T_OPT = t;
  357.       }
  358. }
  359.  
  360.  
  361. /* given a position in a line, return apparant distance from bol
  362.    expanding tabs, etc... up to pos */
  363. int apparant_distance(unsigned char *pos)
  364. {
  365.     int i;
  366.     unsigned char *cur_pos, *save_pos, ch;
  367.     cur_pos = C_POS;
  368.     save_pos = pos;
  369.     C_POS = pos;
  370.     pos = beg_of_line();
  371.     C_POS = cur_pos;
  372.  
  373.     i = 1;
  374.     while(ch = *pos, pos++ < save_pos)
  375.       {
  376.           if (!MOST_V_OPT && ch == '\b')
  377.             {
  378.                 if (i > 1) i--;
  379.             }
  380.           else if (!MOST_V_OPT && ch == '\015') /* ^M */
  381.             {
  382.                 if (i != 1) i = 1;
  383.             }
  384.           else if (!MOST_T_OPT && ch == '\t')
  385.             {
  386.                 i = TAB_LENGTH * ((i - 1)/TAB_LENGTH + 1) + 1;  /* TAB_LENGTH column tabs */
  387.             }
  388.           else if (ch < ' ' || ch > 126)
  389.             {
  390.                 if (ch == '\012' || MOST_V_OPT)  /* ^L */
  391.                   {
  392.                       i += 2;
  393.                   }             /* otherwise they have no width */
  394.             }
  395.           else i++;
  396.       }
  397.     return (i);
  398. }
  399.