X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/bb516de54f1a5dd712c04141956b371b6ca9311a..dc0e9d5051968b633dbad1c43b90e583b0784799:/usr/src/old/dbx/source.c diff --git a/usr/src/old/dbx/source.c b/usr/src/old/dbx/source.c index 1e760eb636..462ebe1652 100644 --- a/usr/src/old/dbx/source.c +++ b/usr/src/old/dbx/source.c @@ -1,6 +1,14 @@ -/* Copyright (c) 1982 Regents of the University of California */ +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ -static char sccsid[] = "@(#)source.c 1.4 %G%"; +#ifndef lint +static char sccsid[] = "@(#)source.c 5.2 (Berkeley) %G%"; +#endif not lint + +static char rcsid[] = "$Header: source.c,v 1.3 87/08/19 15:19:40 mike Exp $"; /* * Source file management. @@ -11,6 +19,15 @@ static char sccsid[] = "@(#)source.c 1.4 %G%"; #include "object.h" #include "mappings.h" #include "machine.h" +#include "keywords.h" +#include "tree.h" +#include "eval.h" +#ifdef IRIS +# define R_OK 04 /* read access */ +# define L_SET 01 /* absolute offset for seek */ +#else +# include +#endif #ifndef public typedef int Lineno; @@ -26,6 +43,13 @@ Lineno cursrcline; List sourcepath; #endif +#ifdef IRIS +# define re_comp regcmp +# define re_exec(buf) (regex(buf) != NULL) +#endif + +extern char *re_comp(); + private Lineno lastlinenum; private String prevsource = nil; @@ -47,7 +71,7 @@ private String prevsource = nil; typedef long Seekaddr; -#define NSLOTS 20 +#define NSLOTS 40 #define NLINESPERSLOT 500 #define slotno(line) ((line) div NLINESPERSLOT) @@ -58,6 +82,25 @@ typedef long Seekaddr; private File srcfp; private Seekaddr *seektab[NSLOTS]; +/* + * Determine if the current source file is available. + */ + +public boolean canReadSource () +{ + boolean b; + + if (cursource == nil) { + b = false; + } else if (cursource != prevsource) { + skimsource(); + b = (boolean) (lastlinenum != 0); + } else { + b = true; + } + return b; +} + /* * Print out the given lines from the source. */ @@ -80,8 +123,8 @@ Lineno l1, l2; beginerrmsg(); fprintf(stderr, "couldn't read \"%s\"\n", cursource); } else { - lb = (l1 == 0) ? lastlinenum : l1; - ub = (l2 == 0) ? lastlinenum : l2; + lb = (l1 == LASTLINE) ? lastlinenum : l1; + ub = (l2 == LASTLINE) ? lastlinenum : l2; if (lb < 1) { beginerrmsg(); fprintf(stderr, "line number must be positive\n"); @@ -115,6 +158,32 @@ Lineno l1, l2; } } +/* + * Search the sourcepath for a file. + */ + +static char fileNameBuf[1024]; + +public String findsource(filename) +String filename; +{ + register String src, dir; + + if (filename[0] == '/') { + src = filename; + } else { + src = nil; + foreach (String, dir, sourcepath) + sprintf(fileNameBuf, "%s/%s", dir, filename); + if (access(fileNameBuf, R_OK) == 0) { + src = fileNameBuf; + break; + } + endfor + } + return src; +} + /* * Open a source file looking in the appropriate places. */ @@ -122,18 +191,15 @@ Lineno l1, l2; public File opensource(filename) String filename; { - register String dir; - char buf[256]; + String s; File f; - f = nil; - foreach (String, dir, sourcepath) - sprintf(buf, "%s/%s", dir, filename); - f = fopen(buf, "r"); - if (f != nil) { - break; - } - endfor + s = findsource(filename); + if (s == nil) { + f = nil; + } else { + f = fopen(s, "r"); + } return f; } @@ -217,18 +283,18 @@ private free_seektab() /* * Figure out current source position. - * Have to use "pc - 1" because pc is the address of the next instruction - * rather than the current one. */ public getsrcpos() { String filename; - curline = srcline(pc - 1); - filename = srcfilename(pc - 1); + curline = srcline(pc); + filename = srcfilename(pc); setsource(filename); - cursrcline = curline; + if (curline != 0) { + cursrcline = curline; + } } /* @@ -242,3 +308,180 @@ public printsrcpos() printf(" in file \"%s\"", cursource); } } + +#define DEF_EDITOR "vi" + +/* + * Invoke an editor on the given file. Which editor to use might change + * installation to installation. For now, we use "vi". In any event, + * the environment variable "EDITOR" overrides any default. + */ + +public edit(filename) +String filename; +{ + extern String getenv(); + String ed, src, s; + Symbol f; + Address addr; + char lineno[10]; + + ed = getenv("EDITOR"); + if (ed == nil) { + ed = DEF_EDITOR; + } + src = findsource((filename != nil) ? filename : cursource); + if (src == nil) { + f = which(identname(filename, true)); + if (not isblock(f)) { + error("can't read \"%s\"", filename); + } + addr = firstline(f); + if (addr == NOADDR) { + error("no source for \"%s\"", filename); + } + src = srcfilename(addr); + s = findsource(src); + if (s != nil) { + src = s; + } + sprintf(lineno, "+%d", srcline(addr)); + } else { + sprintf(lineno, "+1"); + } + if (streq(ed, "vi") or streq(ed, "ex")) { + call(ed, stdin, stdout, lineno, src, nil); + } else { + call(ed, stdin, stdout, src, nil); + } +} + +/* + * Strip away portions of a given pattern not part of the regular expression. + */ + +private String getpattern (pattern) +String pattern; +{ + register char *p, *r; + + p = pattern; + while (*p == ' ' or *p == '\t') { + ++p; + } + r = p; + while (*p != '\0') { + ++p; + } + --p; + if (*p == '\n') { + *p = '\0'; + --p; + } + if (*p == *r) { + *p = '\0'; + --p; + } + return r + 1; +} + +/* + * Search the current file for a regular expression. + */ + +public search (direction, pattern) +char direction; +String pattern; +{ + register String p; + register File f; + String re, err; + Lineno line; + boolean matched; + char buf[512]; + + if (cursource == nil) { + beginerrmsg(); + fprintf(stderr, "no source file\n"); + } else { + if (cursource != prevsource) { + skimsource(); + } + if (lastlinenum == 0) { + beginerrmsg(); + fprintf(stderr, "couldn't read \"%s\"\n", cursource); + } else { + re = getpattern(pattern); + /* circf = 0; */ + if (re != nil and *re != '\0') { + err = re_comp(re); + if (err != nil) { + error(err); + } + } + matched = false; + f = srcfp; + line = cursrcline; + do { + if (direction == '/') { + ++line; + if (line > lastlinenum) { + line = 1; + } + } else { + --line; + if (line < 1) { + line = lastlinenum; + } + } + fseek(f, srcaddr(line), L_SET); + p = buf; + *p = getc(f); + while ((*p != '\n') and (*p != EOF)) { + ++p; + *p = getc(f); + } + *p = '\0'; + matched = (boolean) re_exec(buf); + } while (not matched and line != cursrcline); + if (not matched) { + beginerrmsg(); + fprintf(stderr, "no match\n"); + } else { + printlines(line, line); + cursrcline = line; + } + } + } +} + +public integer srcwindowlen () +{ + Node s; + + s = findvar(identname("$listwindow", true)); + if (s == nil) + return 10; + eval(s); + return pop(integer); +} + +/* + * Compute a small window around the given line. + */ + +public getsrcwindow (line, l1, l2) +Lineno line, *l1, *l2; +{ + integer size; + + size = srcwindowlen(); + *l1 = line - (size div 2); + if (*l1 < 1) { + *l1 = 1; + } + *l2 = *l1 + size; + if (lastlinenum != LASTLINE and *l2 > lastlinenum) { + *l2 = lastlinenum; + } +}