BSD 4_3 release
[unix-history] / usr / src / ucb / dbx / source.c
index ab99709..65f20ea 100644 (file)
@@ -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.
+ */
+
+#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.
 
 /*
  * Source file management.
@@ -11,6 +19,10 @@ static char sccsid[] = "@(#)source.c 1.9 8/5/83";
 #include "object.h"
 #include "mappings.h"
 #include "machine.h"
 #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;
 
 #ifndef public
 typedef int Lineno;
@@ -26,6 +38,8 @@ Lineno cursrcline;
 List sourcepath;
 #endif
 
 List sourcepath;
 #endif
 
+extern char *re_comp();
+
 private Lineno lastlinenum;
 private String prevsource = nil;
 
 private Lineno lastlinenum;
 private String prevsource = nil;
 
@@ -47,7 +61,7 @@ private String prevsource = nil;
 
 typedef long Seekaddr;
 
 
 typedef long Seekaddr;
 
-#define NSLOTS 20
+#define NSLOTS 40
 #define NLINESPERSLOT 500
 
 #define slotno(line)    ((line) div NLINESPERSLOT)
 #define NLINESPERSLOT 500
 
 #define slotno(line)    ((line) div NLINESPERSLOT)
@@ -58,6 +72,25 @@ typedef long Seekaddr;
 private File srcfp;
 private Seekaddr *seektab[NSLOTS];
 
 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.
  */
 /*
  * Print out the given lines from the source.
  */
@@ -80,8 +113,8 @@ Lineno l1, l2;
            beginerrmsg();
            fprintf(stderr, "couldn't read \"%s\"\n", cursource);
        } else {
            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");
            if (lb < 1) {
                beginerrmsg();
                fprintf(stderr, "line number must be positive\n");
@@ -124,7 +157,6 @@ static char fileNameBuf[1024];
 public String findsource(filename)
 String filename;
 {
 public String findsource(filename)
 String filename;
 {
-    register File f;
     register String src, dir;
 
     if (filename[0] == '/') {
     register String src, dir;
 
     if (filename[0] == '/') {
@@ -133,9 +165,7 @@ String filename;
        src = nil;
        foreach (String, dir, sourcepath)
            sprintf(fileNameBuf, "%s/%s", dir, filename);
        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;
            }
                src = fileNameBuf;
                break;
            }
@@ -309,5 +339,135 @@ String filename;
     } else {
        sprintf(lineno, "+1");
     }
     } 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;
+    }
 }
 }