/************************************************************************* *** suppcom.c (JJB TEMPLAR) *** *** Date begun: 11/8/89 - copied from hardcopy of old prim.c *** *** Last modified: 27/8/89. *** *************************************************************************/ /*** The pattern matching algorithm used is the Knuth-Morris-Pratt one *** *** as detailed in:- *** *** "Computer Algorithms: Introduction to Design and Analysis" *** *** by Sara Baase. *** *************************************************************************/ #include "less.h" #include "position.h" #include "screen.h" #include #include "iconify.h" extern struct Window *Window; extern struct NewWindow NewWindow; extern UWORD far image10[420]; extern int fast_line,twiddle,back_scroll,top_scroll,quit_at_eof, squeeze,scroll_bar; extern int has_resized; extern BPTR file; extern char *line; char *modedata[] = { "\n Ty 1.3 User Changeable Modes:\n\n", " (0) Cancel ........ don't change any modes.\n\n", " (1) Fast line ..... check for ~` or control characters.\n", " (2) Twiddle ....... output a ~ for lines beyond EOF.\n", " (3) Back scroll ... allow backwards scrolling.\n", " (4) Top scroll .... draw from top of screen.\n", " (5) Quit at EOF ... quit after two attempts to pass EOF.\n", " (6) Squeeze ....... squeeze multiple blank lines together.\n", " (7) Scroll bar .... activate vertical scroll bar.\n\n\n\n\n\n\n\n", " Sorry about the cruddy numbered menu system, but this'll be made a\n", " requester... eventually.\n", " (SELECT NUMBER)", NULL}; static LONG marks[10]; /* The table of marks. */ struct Image iconimg = {0,0,70,42,2,image10,3,0,NULL}; #define PATLEN 20 char pat[PATLEN + 3]; /* Two characters extra */ char tup[PATLEN + 3]; /* Copy of pat, but all upper case */ int flink[PATLEN + 3]; int pat_opt; /* Should be set by option reader whenever a * new pattern is specified. */ int toupp(ch) /*=====================================================*/ register int ch; { if ((ch >= 'a') && (ch <= 'z')) ch += 'A' - 'a'; return(ch); } static void doflink() /*=================================================*/ { /* Set up flink[], using pat[] as pattern. */ register int i,j; register char *cp = pat,*tp = tup; while (*cp) *tp++ = toupp(*cp++); *tp = 0; /* Terminate string! */ flink[0] = -1; i = 1; while (tup[i]) { j = flink[i-1]; while ((j != -1) && (tup[j] != tup[i-1]) && (tup[j] != '?')) j = flink[j]; flink[i] = j + 1; i++; } pat_opt = 0; /* Turn off pattern option flag */ } static int match(buf) /*================================================*/ register char *buf; { register char *p = tup; register int j; j = 0; while (*buf) { while ((j != -1) && (p[j] != toupp(*buf)) && (p[j] != '?')) j = flink[j]; if (!p[j+1]) return(1); else { buf++; j++; } } return(0); } void search_forw(f) /*================================================*/ int f; { LONG pos,lpos; if ((f || !pat[0]) && (!(f = r_string("Forward Search",pat,PATLEN+1)) || !pat[0])) return; if (position(TOP) == NULL_POSITION) pos = 0; else pos = position(TOP_PLUS_ONE); if (pos == NULL_POSITION) { error("Nothing to search!",0); return; } if (f || pat_opt) doflink(); while (1) { lpos = pos; pos = forw_raw_line(pos); if (pos == NULL_POSITION) { error("Pattern not found",0); return; } if (match(line)) break; } jump_loc(lpos); } void search_back(f) /*================================================*/ int f; { LONG pos,lpos; if ((f || !pat[0]) && (!(f = r_string("Backward Search",pat,PATLEN+1)) || !pat[0])) return; /* The above sets f to 1 if user entered pattern, if f was zero */ if (position(TOP) == NULL_POSITION) pos = 0; else pos = position(TOP); if (pos == NULL_POSITION) { error("Nothing to search!",0); return; } if (f || pat_opt) doflink(); while (1) { pos = back_raw_line(pos); lpos = pos; if (pos == NULL_POSITION) { error("Pattern not found",0); return; } if (match(line)) break; } jump_loc(lpos); } void doiconify() /*===================================================*/ { static int success = 1; static UWORD x,y; /* Initialised to zero */ register int temp; if (success) { NewWindow.LeftEdge = Window->LeftEdge; /* Save window dimensions */ NewWindow.TopEdge = Window->TopEdge; NewWindow.Height = Window->Height; NewWindow.Width = Window->Width; NewWindow.Title = Window->Title; ttclose(); /* Close Window and console */ success = iconify(&x,&y,iconimg.Width,iconimg.Height,NULL,(APTR)&iconimg,ICON_IMAGE); ttopen(); /* Get back window and console */ temp = top_scroll; top_scroll = 1; repaint(); top_scroll = temp; if (!success) error("Iconify failed!",0); } else { error("Iconify disabled.",0); } } void print() /*=======================================================*/ { UBYTE buf[512]; /* Buffer on the fly, as it were... */ register ULONG oldpos; /* Seek back to initial file pos? */ register BPTR prt; register int size; if (!file || !r_bool("Really print file?")) return; if (!(prt = Open("PRT:",MODE_NEWFILE))) { error("Failed to open printer!",0); return; } oldpos = Seek(file,0,OFFSET_BEGINNING); while ((size = Read(file,buf,512)) > 0) { if (Write(prt,buf,size) != size) { error("Printing error!",0); break; } } Close(prt); Seek(file,oldpos,OFFSET_BEGINNING); } void init_mark() /*===================================================*/ { /* Clear all marks. */ register int i; for (i = 0; i < 10; i++) marks[i] = NULL_POSITION; } static int badmark(c) /*================================================*/ register int c; /* See if c is a valid mark char (a - z). */ { if ((c < 0x01) || (c > 0x0a)) { /* RAWKEY */ error("Must be a digit in [0,9]!",0); return(1); } return(0); } static int getmark(cp) /*===============================================*/ register char *cp; { register int c; SetWindowTitles(Window,cp,(char *)-1L); c = getc(); return((badmark(c))? -1: c - 1); /* mark '0' actually pos 9 in table, * since RAWKEY goes 1,2,...,9,0 instead of 0,1,...,8,9. */ } void setmark() /*=====================================================*/ { register int c; if ((c = getmark("Mark: set mark [0-9] ")) >= 0) marks[c] = position(TOP); } void gomark() /*======================================================*/ { register int c; if ((c = getmark("Mark: go to mark [0-9] ")) < 0) return; /* Failed */ if (marks[c] == NULL_POSITION) error("Mark not set",0); else jump_loc(marks[c]); } void domode(on) /*====================================================*/ register int on; { register char **ch = modedata; SetWindowTitles(Window,(on)?"Mode ON":"Mode OFF",(char *)-1L); clear(); while (*ch) puts(*ch++); flush(); switch (getc()) { case (0x01): fast_line = on; break; case (0x02): twiddle = on; break; case (0x03): back_scroll = on * 30; break; case (0x04): top_scroll = on; break; case (0x05): quit_at_eof = on; break; case (0x06): squeeze = on; break; case (0x07): scroll_bar = on; setbar(2); break; } if (has_resized) { resize(); has_resized = 0; } }