/************************************************************************* *** main.c (JJB TEMPLAR) *** *** Date modifications begun: 7/8/89. *** *** Last modified: 28/8/89. *** *************************************************************************/ /*** Ahem. Here we go... *** *************************************************************************/ #include "less.h" #include "position.h" #include #include extern struct WBStartup *WBenchMsg; char *filename; struct WBArg *wbArgs; int new_file; char current_file[128]; int ac; int curr_ac; static struct Remember *RemKey; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct IconBase *IconBase; extern BPTR file; extern int nbufs; extern int quit_at_eof; extern int f_nbufs; extern int back_scroll; extern int top_scroll; extern int sc_height; extern char version[]; /* Version string. */ extern struct Window *Window; void dolibs(); BPTR OpenArg(struct WBArg *); void edit(int); void add_file(); void next_file(int); void prev_file(int); void printf(char *); char *strint(int); void sprintf(); void cleanup(char *,int); void dolibs() /*======================================================*/ { if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L))) cleanup("ERROR: failed to open intuition.library!\n",20); if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L))) cleanup("ERROR: failed to open graphics.library!\n",20); if (!(IconBase = (struct IconBase *)OpenLibrary("icon.library",0L))) printf("WARNING: failed to open icon.library!\n"); } BPTR OpenArg(wa) /*===================================================*/ struct WBArg *wa; /* All these mixed-case function names! */ { LONG olddir; BPTR file; if (wa->wa_Lock) olddir = CurrentDir(wa->wa_Lock); file = Open(wa->wa_Name, MODE_OLDFILE); if (wa->wa_Lock) CurrentDir(olddir); /* Why move back? For CLI? */ return(file); } void edit(filenum) /*=================================================*/ int filenum; /* Move to file number "filenum" in wbArgs[]. */ { long f; char message[100]; static int any_edited = 0; static int hold_scroll = 0; if (!filenum) { if (curr_ac >= ac) { error("No current file",1); return; } filenum = curr_ac; } filename = wbArgs[curr_ac].wa_Name; if (!(f = OpenArg(&wbArgs[filenum]))) { sprintf(message, "Cannot open %s!", filename); if (any_edited) error(message,0); /* Where to put error? In */ else { /* status line if a file */ puts(message); /* has already been opened, */ flush(); /* or to screen if not. */ /* Wait two seconds for him to read message */ Delay(100L); hold_scroll = 1; } return; } /* Close the current input file and set up to use the new one. */ if (file > 0) Close(file); new_file = 1; /* Flag it (for prompt.c) */ strcpy(current_file, filename); file = f; opticon(filename); /* Check icon for args */ ch_init(f_nbufs); init_mark(); /* Just clears all the marks. */ any_edited = 1; /* Flag this (for error message above) */ if (hold_scroll) { /* Before erasing screen, display filename and ask for a keystroke. */ error(filename,1); hold_scroll = 0; /* New edit, error message from previous */ } /* file still on screen (not error line). */ jump_back(1); /* Jump to line 1 of new file. */ setbar(2); /* Complete reset of scroll bar. */ } void add_file() /*====================================================*/ { if (ac >= MAXAC) error("No room in table for new file!",0); else { wbArgs[ac].wa_Name = AllocRemember(&RemKey,250,MEMF_CLEAR); if (!wbArgs[ac].wa_Name) error("No space for filename!",0); else { if (!r_string("Filename",wbArgs[ac].wa_Name,249)) return; wbArgs[ac].wa_Lock = NULL; ac++; edit(curr_ac = ac - 1); } } } void next_file(n) /*==================================================*/ int n; { if (curr_ac + n >= ac) { if (quit_at_eof) cleanup(NULL,0); error("No next file!",0); } else edit(curr_ac += n); } void prev_file(n) /*==================================================*/ int n; { if (curr_ac - n < 0) error("No previous file!",0); else edit(curr_ac -= n); } void main(argc,argv) /*===============================================*/ int argc; char **argv; { register int i,j; struct WBArg cliArgs[MAXAC]; dolibs(); /* IntuitionBase */ doopts(argc,argv); if (!argc) { /* Workbench */ wbArgs = WBenchMsg->sm_ArgList; argc = WBenchMsg->sm_NumArgs; if (argc < 2) cleanup(NULL,50); /* Removed console. Bummer. */ j = 0; argc--; while ((j < argc) && (j < MAXAC)) { cliArgs[j] = wbArgs[j + 1]; j++; } wbArgs = cliArgs; /* Copy over, so array can be added to */ } else { /* CLI */ argv++; argc--; if (argc > 10) argc = 10; for (i=j=0; i < argc; i++) { /* Only filename args. */ if ((argv[i][0] != '+') && (argv[i][0] != '-') && (argv[i][0] != '#')) { cliArgs[j].wa_Lock = 0; /* So OpenArg checks for !Lock */ cliArgs[j].wa_Name = argv[i]; j++; } } wbArgs = cliArgs; argc = j; /* ac set to argc, also used by WB stuff */ } /* Set up list of files to be examined. */ ac = argc; /* Filename count */ curr_ac = 0; /* Current arg to use */ ttopen(); /* Opens window, and console */ initbell(); /* Set up bell */ if (back_scroll < 0) { back_scroll = sc_height-1; if (top_scroll) back_scroll--; } /* Select the first file to examine. */ if (ac < 1) cleanup("ERROR: no file specified\n",50); else { do { edit(0); if (file > 0) /* We can open this file. */ break; putc('\n'); flush(); } while (++curr_ac < ac); /* Keeping trying. */ } if (file > 0) commands(); /* Managed to open a file */ cleanup(NULL,0); } void printf(cp) /*====================================================*/ register char *cp; { if (!WBenchMsg) Write(Output(),cp,strlen(cp)); } char *strint(i) /*====================================================*/ register int i; /* Simple integer to decimal string routine */ { register char *ret; static char buf[10]; ret = &buf[9]; *ret = 0; while (i > 0) { *(--ret) = (i % 10) + '0'; i /= 10; } if (!*ret) *(--ret) = '0'; return(ret); } void sprintf(dst,cp,pnt) /*===========================================*/ register char *dst,*cp; ULONG pnt; { ULONG *arg; arg = &pnt; while (*cp) { if (*cp == '%') switch (*(++cp)) { case ('d'): strcpy(dst,strint((int)*arg++)); while (*dst) dst++; /* On to zero */ break; case ('s'): strcpy(dst,(char *)*arg++); while (*dst) dst++; break; case ('c'): *dst++ = (char)*arg++; break; default: *dst++ = *cp; } else *dst++ = *cp; cp++; /* Inc it here, so in just once place */ } *dst = 0; } void cleanup(cp,err) /*===============================================*/ char *cp; /* No bra required. Just a simple exit. */ int err; /* I don't like doing all this if (x) Close(x) */ { /* stuff, but leave it in for the mo... */ if (cp) printf(cp); if (file > 0) Close(file); freebell(); /* Drop bell stuff. OK if not there, so no need to check */ ttclose(); /* OKAY if tty not open, so no need to check. */ ch_memdump(); /* FreeMem bufs in ch.c */ if (RemKey) FreeRemember(&RemKey,TRUE); if (IconBase) CloseLibrary(IconBase); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); XCEXIT(err); }