-/* 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)source.c 5.1 (Berkeley) 5/31/85";
+#endif not lint
-static char sccsid[] = "@(#)source.c 1.9 8/5/83";
+static char rcsid[] = "$Header: source.c,v 1.4 84/06/07 16:29:38 linton Exp $";
/*
* Source file management.
#include "object.h"
#include "mappings.h"
#include "machine.h"
+#include "keywords.h"
+#include "tree.h"
+#include "eval.h"
+#include <sys/file.h>
#ifndef public
typedef int Lineno;
List sourcepath;
#endif
+extern char *re_comp();
+
private Lineno lastlinenum;
private String prevsource = nil;
typedef long Seekaddr;
-#define NSLOTS 20
+#define NSLOTS 40
#define NLINESPERSLOT 500
#define slotno(line) ((line) div NLINESPERSLOT)
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.
*/
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");
public String findsource(filename)
String filename;
{
- register File f;
register String src, dir;
if (filename[0] == '/') {
src = nil;
foreach (String, dir, sourcepath)
sprintf(fileNameBuf, "%s/%s", dir, filename);
- f = fopen(fileNameBuf, "r");
- if (f != nil) {
- fclose(f);
+ if (access(fileNameBuf, R_OK) == 0) {
src = fileNameBuf;
break;
}
} else {
sprintf(lineno, "+1");
}
- call(ed, stdin, stdout, lineno, src, nil);
+ 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;
+ }
+ }
+ }
+}
+
+/*
+ * Compute a small window around the given line.
+ */
+
+public getsrcwindow (line, l1, l2)
+Lineno line, *l1, *l2;
+{
+ Node s;
+ integer size;
+
+ s = findvar(identname("$listwindow", true));
+ if (s == nil) {
+ size = 10;
+ } else {
+ eval(s);
+ size = pop(integer);
+ }
+ *l1 = line - (size div 2);
+ if (*l1 < 1) {
+ *l1 = 1;
+ }
+ *l2 = *l1 + size;
+ if (lastlinenum != LASTLINE and *l2 > lastlinenum) {
+ *l2 = lastlinenum;
+ }
}