home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
most423.zip
/
buffer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-28
|
10KB
|
455 lines
#include <stdio.h>
#ifndef VMS
/* #include <malloc.h> */
#endif
#include <stdlib.h>
#include "buffer.h"
#include "externs.h"
#include "display.h"
#include "line.h"
#include "file.h"
int MOST_W_OPT = 0;
unsigned char *BEG; /* beginning of current buffer */
unsigned char *EOB; /* end of current buffer */
unsigned char MINI_BUF[132];
Buffer *BUF;
extern int SQUEEZE_LINES;
int NUM_LINES;
int ACTUAL_LINES;
unsigned char *C_POS;
int C_LINE;
unsigned char *beg_of_line1()
{
unsigned char *pos;
if (C_POS == BEG) return BEG;
pos = C_POS;
if (pos == EOB) pos--;
if ((*pos != '\n') && (*(pos-1) == '\n')) return(pos);
if ((*pos == '\n') && (pos == BEG)) return(BEG);
/* suppose BEG[] is "....\nabcde\n\n\n\n\n..." and we are somwhere in
the middle of the \n's. Then we want to return the 2nd \n if the
SQUEEZE is on otherwise just return where we are. */
if ((*pos-- == '\n') && (*pos == '\n'))
{
if (SQUEEZE_LINES)
{
/* if we are between '\n's then skip past all of them. */
while ((pos > BEG) && (*pos == '\n')) pos--;
if ((pos == BEG) && (*pos == '\n')) return (BEG);
pos++;
}
return (++pos);
}
while((pos > BEG) && (*pos != '\n')) pos--;
if (pos != BEG) pos++;
else if ((pos == BEG) && (*pos == '\n')) pos++;
return pos;
}
unsigned char *beg_of_line()
{
unsigned char *b;
int d,n;
if (!MOST_W_OPT) return beg_of_line1();
b = beg_of_line1();
d = C_POS - b;
n = d / (SCREEN_WIDTH - 1);
return(b + (int) (n * (SCREEN_WIDTH - 1)));
}
/* does not move point */
unsigned char *end_of_line1()
{
register unsigned char *pos, *pmax = EOB;
int n, n2;
pos = C_POS;
if (pos >= EOB) return(EOB);
/* if ((pos == BEG) && (*pos == '\n')) return (BEG); */
/* find the first '\n' */
if (*pos != '\n')
{
n = pmax - pos;
n2 = n % 8;
pmax = pos + (n - 8);
while(pos <= pmax)
{
if ((*pos++ == '\n')
|| (*pos++ == '\n')
|| (*pos++ == '\n')
|| (*pos++ == '\n')
|| (*pos++ == '\n')
|| (*pos++ == '\n')
|| (*pos++ == '\n')
|| (*pos++ == '\n'))
{
return(pos - 1);
}
}
pmax = pos + n2;
while ((pos < pmax) && (*pos != '\n')) pos++;
return(pos);
}
if (!SQUEEZE_LINES) return (pos);
/* if BEG = "....abc\n\n\n\n\ndef..." then we are at some first \n. We
want to return the last '\n' unless we wre at the first '\n'. */
if ((pos > BEG) && ( pos--, *pos++ != '\n')) return (pos);
while ((pos < EOB) && (*pos == '\n')) pos++;
if (pos-- == EOB) return (pos);
if (pos < BEG) pos = BEG;
return pos;
}
unsigned char *end_of_line()
{
unsigned char *b, *e;
int n;
if (!MOST_W_OPT) return end_of_line1();
b = beg_of_line();
e = end_of_line1();
n = (e - b) / (SCREEN_WIDTH - 1);
if (n) return(b + (SCREEN_WIDTH - 1));
return (e);
}
int forward_line(int save)
{
int m, ok;
register int n = save;
unsigned char *p;
unsigned char *pmax;
pmax = EOB - 1;
if (n > 0)
{
if (MOST_B_OPT)
{
m = (EOB - C_POS)/16;
if (n > m) n = m;
C_POS += n * 16;
C_LINE += n;
return n;
}
else while (n--)
{
C_POS = end_of_line();
/* next step handles newline at the EOB */
if (C_POS >= pmax)
{
if ((C_POS > pmax) || (*C_POS == '\n')) return (save - n - 1);
}
C_LINE++;
C_POS++;
if (MOST_S_OPT)
{
p = C_POS;
ok = 1;
while ((*p <= ' ') && ok)
{
if (*p != '\n') p++;
if (p > pmax) break;
if ((*p == '\n') || (apparant_distance(p) >= MOST_S_OPT))
{
ok = 0;
C_LINE--;
n++;
}
}
} /* MOST_S_OPT */
}
}
else
{
if (MOST_B_OPT)
{
m = (BEG - C_POS)/16;
if (n < m) n = m;
C_POS += n * 16;
C_LINE += n;
return n;
}
else while (n++)
{
C_POS = beg_of_line();
if (C_POS == BEG) return (n - save - 1);
C_POS--;
C_LINE--;
if (MOST_S_OPT)
{
C_POS = beg_of_line();
p = C_POS;
ok = 1;
while ((*p <= ' ') && ok)
{
if (*p != '\n') p++;
if (p >= EOB) break;
if ((*p == '\n') || (apparant_distance(p) >= MOST_S_OPT))
{
ok = 0;
C_LINE++;
n--;
}
}
} /* MOST_S_OPT */
}
}
return(save);
}
int count_lines(unsigned char *beg, unsigned char *end)
{
int save_line = C_LINE, n;
unsigned char *save_beg = beg, *save_eob = EOB, *save_pos = C_POS;
int dn = 1000;
if (MOST_B_OPT) return(1 + (int)(end - beg) / 16);
BEG = C_POS = beg;
EOB = end;
n = 1;
while((dn = forward_line(dn)) != 0) n += dn;
if (*end == '\n') n--;
if (!n) n = 1;
C_POS = save_pos;
EOB = save_eob;
BEG = save_beg;
C_LINE = save_line;
return(n);
}
void goto_line(int line)
{
int dif_c, dif_b,dif_t;
if (line < 1) line = 1;
read_to_line(line);
if (line > NUM_LINES) line = NUM_LINES;
if (MOST_B_OPT)
{
C_POS = BEG + (16 * (line - 1));
C_LINE = line;
return;
}
dif_c = line - C_LINE;
dif_b = line - NUM_LINES;
dif_t = line - 1;
/* 4 possibilites */
if (dif_c <= 0)
{
if (dif_t < -dif_c) /* go from top */
{
C_LINE = 1;
C_POS = BEG;
(void) forward_line(dif_t);
}
else /* from curr back */
{
(void) forward_line(dif_c);
}
}
else if (dif_c > 0)
{
if ((dif_c + dif_b) < 0) /* go from curr */
{
(void) forward_line(dif_c);
}
else
{
C_LINE = NUM_LINES;
C_POS = EOB;
(void) forward_line(dif_b);
}
}
}
/* return line the point is on without the final '\n's
unless beg = end in which case we take care of it later ...
returns 1 if the line should be wrapped */
int extract_line(unsigned char **beg, unsigned char **end)
{
*beg = beg_of_line();
*end = end_of_line();
if (**end != '\n') return(1);
while ((*end > BEG) && (**end == '\n')) *end = *end - 1;
return(0);
}
int what_line(unsigned char *pos)
{
unsigned char *save_pos;
int save_line, dir;
register int dif_c, dif_b,dif_t;
int ret;
if (MOST_B_OPT)
{
return (1 + (pos - BEG)/16);
}
save_pos = C_POS;
save_line = C_LINE;
dif_c = pos - C_POS;
dif_b = pos - EOB;
dif_t = pos - BEG;
/* 4 possibilites */
if (dif_c <= 0)
{
if (dif_t < -dif_c) /* go from top */
{
C_LINE = 1;
C_POS = BEG;
dir = 1;
}
else /* from curr back */
{
dir = -1;
}
}
else if (dif_c > 0)
{
if ((dif_c + dif_b) < 0) /* go from curr */
{
dir = 1;
}
else
{
C_LINE = NUM_LINES;
C_POS = EOB;
dir = -1;
}
}
if (dir == 1)
{
while(C_POS = end_of_line(), C_POS < pos)
{
C_POS++;
C_LINE++;
}
}
else
{
while(C_POS = beg_of_line(), pos < C_POS)
{
C_LINE--;
C_POS--;
}
}
ret = C_LINE;
C_POS = save_pos;
C_LINE = save_line;
return(ret);
}
/* given a buffer position, find the line and column */
void find_row_column(unsigned char *pos, int *r, int *c)
{
unsigned char *beg, *save_pos;
int save_line;
if (pos <= BEG)
{
*r = 1;
*c = 1;
return;
}
save_line = C_LINE;
save_pos = C_POS;
*r = what_line(pos);
if (MOST_B_OPT)
{
*c = (int) (pos - BEG) - *r * 16 + 1;
return;
}
C_LINE = *r;
C_POS = pos;
/* Now we have found the line it is on so.... */
beg = beg_of_line();
*c = 1;
while (beg++ < pos) *c = *c + 1;
C_LINE = save_line;
C_POS = save_pos;
}
Buffer *switch_to_buffer(Buffer *new)
{
Buffer *old;
old = BUF;
BUF = new;
BEG = BUF->beg;
EOB = BUF->end;
return(old);
}
/*
void delete_buffer(Buffer *old)
{
if (BUF->fd != -1) close(BUF->fd);
(void) free(BUF);
BUF = old;
BEG = BUF->beg;
EOB = BUF->end;
}
*/
Buffer *create_buffer(char *file)
{
Buffer *buf;
buf = (Buffer *) MALLOC(sizeof(Buffer));
strcpy(buf->file,file);
return(buf);
}
unsigned char *most_malloc(unsigned int n)
{
unsigned char *b = (unsigned char *) malloc(n);
if (b == NULL)
{
exit_error("malloc: Memory Allocation Error.");
}
return b;
}
unsigned char *most_realloc(unsigned char *p, unsigned int n)
{
unsigned char *b = (unsigned char *) realloc(p, n);
if (b == NULL)
{
exit_error("malloc: Memory Allocation Error.");
}
return b;
}