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