file reorg, pathnames.h, paths.h
[unix-history] / usr / src / old / dbx / source.c
index 5566360..462ebe1 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.
+ */
 
 
-static char sccsid[] = "@(#)source.c 1.8 %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.
 
 /*
  * Source file management.
@@ -11,6 +19,15 @@ static char sccsid[] = "@(#)source.c 1.8 %G%";
 #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"
+#ifdef IRIS
+#   define R_OK 04     /* read access */
+#   define L_SET 01    /* absolute offset for seek */
+#else
+#   include <sys/file.h>
+#endif
 
 #ifndef public
 typedef int Lineno;
 
 #ifndef public
 typedef int Lineno;
@@ -26,6 +43,13 @@ Lineno cursrcline;
 List sourcepath;
 #endif
 
 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;
 
 private Lineno lastlinenum;
 private String prevsource = nil;
 
@@ -47,7 +71,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 +82,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 +123,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");
@@ -116,28 +159,47 @@ Lineno l1, l2;
 }
 
 /*
 }
 
 /*
- * Open a source file looking in the appropriate places.
+ * Search the sourcepath for a file.
  */
 
  */
 
-public File opensource(filename)
+static char fileNameBuf[1024];
+
+public String findsource(filename)
 String filename;
 {
 String filename;
 {
-    register String dir;
-    char buf[256];
-    File f;
+    register String src, dir;
 
 
-    f = nil;
     if (filename[0] == '/') {
     if (filename[0] == '/') {
-       f = fopen(filename, "r");
+       src = filename;
     } else {
     } else {
+       src = nil;
        foreach (String, dir, sourcepath)
        foreach (String, dir, sourcepath)
-           sprintf(buf, "%s/%s", dir, filename);
-           f = fopen(buf, "r");
-           if (f != nil) {
+           sprintf(fileNameBuf, "%s/%s", dir, filename);
+           if (access(fileNameBuf, R_OK) == 0) {
+               src = fileNameBuf;
                break;
                break;
-       }
+           }
        endfor
     }
        endfor
     }
+    return src;
+}
+
+/*
+ * Open a source file looking in the appropriate places.
+ */
+
+public File opensource(filename)
+String filename;
+{
+    String s;
+    File f;
+
+    s = findsource(filename);
+    if (s == nil) {
+       f = nil;
+    } else {
+       f = fopen(s, "r");
+    }
     return f;
 }
 
     return f;
 }
 
@@ -246,3 +308,180 @@ public printsrcpos()
        printf(" in file \"%s\"", cursource);
     }
 }
        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;
+    }
+}