home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "buffer.h"
- #include "externs.h"
- #include "display.h"
- #include "line.h"
-
- extern int COLUMN;
-
- #define MAX_LINE_LEN 500
- int MOST_S_OPT = 0;
- /* take 16 binary characters and put them in displayable form */
- int ascii_format_line(char *buff, char *str)
- {
- int i,ii,j,k,ch,di,flag;
- char num_str[4];
-
- ii = 0;
- di = 40;
- flag = 1;
-
- for (i = 35;i<=di;i++) str[i] = ' '; /* a gap */
-
- for (j = 0; j < 4; j++)
- {
-
- for (k = 0; k < 4; k++)
- {
- i = 4 * j + k;
- ch = buff[i];
- if (MOST_V_OPT)
- {
- if (((ch < 32) && (ch >= 0)) || (ch == 127))
- {
- str[ii++] = '^';
- if (ch == 127)
- str[ii++] = '?';
- else
- str[ii++] = ch + 'A' - 1;
- str[i + di] = '.';
- }
- else if (ch < 0)
- {
- ch = ch + 256;
- sprintf(num_str,"%02X", ch);
- str[ii++] = num_str[0];
- str[ii++] = num_str[1];
- str[i + di] = '.';
- }
- else
- {
- str[ii++] = ' ';
- str[ii++] = ch;
- str[i + di] = ch;
- }
- }
- else
- {
- if (ch < 32)
- {
- if (ch < 0) ch = ch + 256;
- str[i + di] = '.';
- }
- else str[i+di] = ch;
-
- sprintf(num_str,"%02X", ch);
- str[ii++] = num_str[0];
- str[ii++] = num_str[1];
- }
-
- } /* k */
- str[ii++] = ' ';
- }
- di += 16;
- str[di] = '\0';
- return(di);
- }
-
-
- int analyse_line(unsigned char *beg, unsigned char *end, char *out, char *attributes)
- {
- int test, ii, fold, ii_max, j, ok;
- unsigned char ch,attr;
-
- test = 0;
- ii = 0;
- ii_max = 0;
- fold = 0;
- while(ch = *beg, (beg <= end) && (ch != '\n') && (ch != '\0'))
- {
- beg++;
- if (ii > ii_max) fold = 0; /* beyond previous high */
- attr = ' ';
- if (!MOST_V_OPT && ch == '\015') /* ^M */
- {
- if (beg <= end)
- {
- fold = 1;
- if (ii > ii_max) ii_max = ii - 1; /* ^M contributes nil */
- ii = 0;
- }
- }
- else if (!MOST_V_OPT && ch == '\b')
- {
- test = 1;
- ii--;
- }
- else if (test || fold)
- {
- test = 0;
- if (ch == out[ii])
- attr = 'b';
- else if (out[ii] == '_')
- attr = 'u';
-
- if (fold && ch == ' ')
- ii++;
- else
- {
- attributes[ii] = attr;
- out[ii++] = ch;
- }
-
- }
- else if (!MOST_T_OPT && ch == '\t')
- {
- j = 8 * (ii/8 + 1) - ii; /* 8 column tabs */
- while(j--)
- {
- out[ii] = ' ';
- attributes[ii++] = attr;
- }
- }
- else
- {
- out[ii] = ch;
- attributes[ii++] = attr;
- }
- }
- if (fold) ii = ii_max + 1;
- if ((beg > end) && MOST_S_OPT && !MOST_W_OPT)
- {
- ok = 1;
- if (*beg == '\n') beg++;
- while ((*beg <= ' ') && ok)
- {
- if (*beg != '\n') beg++;
- if (beg >= EOB) break;
- if ((*beg == '\n') || (apparant_distance(beg) >= MOST_S_OPT))
- {
- ok = 0;
- }
- }
- if (!ok)
- {
- ok = 3;
- while(ok--)
- {
- out[ii] = '.';
- attributes[ii++] = ' ';
- }
- }
-
- } /* MOST_S_OPT */
- out[ii] = '\0';
- return(ii);
- }
-
-
- void output(char *line, int len, char *attr, char d_char)
- {
- int
- i,ii,k, bold,b_len,n_len, s_len, u_len, work_len, j, mark, ok, quit,
- count, max_col, save, dollar;
- char ch, at, out[500], *n_str, *b_str, *s_str, *u_str, work[20];
-
- b_str = "\033[1m"; n_str = "\033[0m"; s_str = "\033[%dC"; u_str = "\033[4m";
- b_len = strlen(b_str);
- n_len = strlen(n_str);
- u_len = strlen(u_str);
- s_len = strlen(s_str);
- i = 0;
- ii = 0;
- bold = 0;
- quit = 0;
- ok = 0; /* 1 if ok to start filling the out line */
- max_col = COLUMN + SCREEN_WIDTH - 1;
- count = 0;
- dollar = 0;
- while (ch = line[i], (i <= len) && ch != '\0' && ch != '\n' && !quit)
- {
- count++;
- if (MOST_V_OPT && ((ch < ' ') || (ch > 126))) count++;
-
- if (count >= COLUMN) ok = 1;
- if (count > max_col) break;
-
- if (!MOST_V_OPT)
- {
- at = attr[i];
- if ((at != ' ') && !bold)
- {
- bold = 1;
- /* u and b have same length */
- if (ok) for (j = 0; j < b_len; j++)
- {
- if (at == 'b') out[ii++] = b_str[j];
- else out[ii++] = u_str[j];
- }
-
- }
- else if ((at == ' ') && bold)
- {
- bold = 0;
- if (ok) for (j = 0; j < n_len; j++) out[ii++] = n_str[j];
- }
- }
-
- if (ch == ' ')
- {
- j = 0;
- mark = ii;
- /* we always make this loop once */
- while ((i <= len) && (line[i++] == ' '))
- {
- j++;
- if (ok) out[ii++] = ' ';
- }
- if (i > len) quit = 1;
- i = i - 2;
- save = count;
- count += j - 1; /* counted one at top of while */
-
- if (!ok)
- {
- if (count >= COLUMN)
- {
- ok = 1;
- j = count - COLUMN + 1;
- k = j;
- while (k--) out[ii++] = ' ';
- }
- }
-
- if (count >= max_col)
- {
- quit = 1;
- j = max_col - save;
- }
-
- if (ok && (j > s_len))
- {
- ii = mark;
- sprintf(work,s_str,j);
- work_len = strlen(work);
- for (j = 0; j < work_len; j++) out[ii++] = work[j];
- if (count >= max_col) dollar = ii++;
- }
- else if (count >= max_col)
- {
- dollar = mark + j;
- }
-
- }
- else if (ok && ((ch == '\014') || ((ch < ' ') && MOST_V_OPT)))
- {
- out[ii++] = '^';
- out[ii++] = ch + 'A' - 1;
- }
- else if (ok)
- {
- out[ii++] = ch;
- }
-
- i++;
- }
- if (dollar) out[ii = dollar, ii++] = d_char;
- else if (ok && count >= max_col) out[ii - 1] = d_char;
- out[ii] = '\0';
- if (ii) fputs(out,stdout);
-
- if (ok && bold) fputs(n_str,stdout);
- }
-
-
- void display_line()
- {
- unsigned char *beg, *end;
- int i, len, v, t;
- char buff[16];
- char the_line[MAX_LINE_LEN], *p, the_attr[MAX_LINE_LEN], *line,*attr, ch;
- line = the_line;
- attr = the_attr;
- /* This needs fixed for files with really big lines */
- if (!MOST_B_OPT)
- {
- if(extract_line(&beg, &end) && MOST_W_OPT) ch = '\\'; else ch = '$';
-
- len = end - beg + 1;
- if (len > MAX_LINE_LEN)
- {
- v = MOST_V_OPT;
- t = MOST_T_OPT;
- MOST_V_OPT = 1;
- MOST_T_OPT = 1;
- line = (char *) beg;
- }
- else len = analyse_line(beg, end, line, attr);
- }
- else
- {
- ch = '$';
- i = 0;
- beg = C_POS;
- end = C_POS + 16;
- if (end > EOB) end = EOB;
- while(beg < end) buff[i++] = (char) *beg++;
- while(i < 15) buff[i++] = 0;
- len = ascii_format_line(buff,the_line);
- i = 0; while(i<80) attr[i++] = ' ';
- }
-
-
- output(line,len,attr, ch);
- if (len > MAX_LINE_LEN)
- {
- MOST_V_OPT = v;
- MOST_T_OPT = t;
- }
- }
-
-
- /* given a position in a line, return apparant distance from bol
- expanding tabs, etc... up to pos */
- int apparant_distance(unsigned char *pos)
- {
- int i;
- unsigned char *cur_pos, *save_pos, ch;
- cur_pos = C_POS;
- save_pos = pos;
- C_POS = pos;
- pos = beg_of_line();
- C_POS = cur_pos;
-
- i = 1;
- while(ch = *pos, pos++ < save_pos)
- {
- if (!MOST_V_OPT && ch == '\b')
- {
- if (i > 1) i--;
- }
- else if (!MOST_V_OPT && ch == '\015') /* ^M */
- {
- if (i != 1) i = 1;
- }
- else if (!MOST_T_OPT && ch == '\t')
- {
- i = 8 * ((i - 1)/8 + 1) + 1; /* 8 column tabs */
- }
- else if (ch < ' ' || ch > 126)
- {
- if (ch == '\012' || MOST_V_OPT) /* ^L */
- {
- i += 2;
- } /* otherwise they have no width */
- }
- else i++;
- }
- return (i);
- }
-
-
-
-