BSD 4_4 release
[unix-history] / usr / src / old / dbx / eval.c
index 7ea279c..8f6dfad 100644 (file)
@@ -1,8 +1,39 @@
-/* Copyright (c) 1982 Regents of the University of California */
-
-static char sccsid[] = "@(#)eval.c 1.10 8/17/83";
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 
-static char rcsid[] = "$Header: eval.c,v 1.3 84/03/27 10:20:23 linton Exp $";
+#ifndef lint
+static char sccsid[] = "@(#)eval.c     5.7 (Berkeley) 6/1/90";
+#endif /* not lint */
 
 /*
  * Tree evaluation.
 
 /*
  * Tree evaluation.
@@ -11,6 +42,7 @@ static char rcsid[] = "$Header: eval.c,v 1.3 84/03/27 10:20:23 linton Exp $";
 #include "defs.h"
 #include "tree.h"
 #include "operators.h"
 #include "defs.h"
 #include "tree.h"
 #include "operators.h"
+#include "debug.h"
 #include "eval.h"
 #include "events.h"
 #include "symbols.h"
 #include "eval.h"
 #include "events.h"
 #include "symbols.h"
@@ -76,6 +108,25 @@ public Boolean useInstLoc = false;
 
 #define Boolrep char   /* underlying representation type for booleans */
 
 
 #define Boolrep char   /* underlying representation type for booleans */
 
+/*
+ * Command-level evaluation.
+ */
+
+public Node topnode;
+
+public topeval (p)
+Node p;
+{
+    if (traceeval) {
+       fprintf(stderr, "topeval(");
+       prtree(stderr, p);
+       fprintf(stderr, ")\n");
+       fflush(stderr);
+    }
+    topnode = p;
+    eval(p);
+}
+
 /*
  * Evaluate a parse tree leaving the value on the top of the stack.
  */
 /*
  * Evaluate a parse tree leaving the value on the top of the stack.
  */
@@ -88,14 +139,15 @@ register Node p;
     Address addr;
     long i, n;
     int len;
     Address addr;
     long i, n;
     int len;
-    Symbol s, f;
+    Symbol s;
     Node n1, n2;
     Node n1, n2;
-    Boolean b;
+    boolean b;
     File file;
     File file;
+    String str;
 
     checkref(p);
 
     checkref(p);
-    if (debug_flag[2]) {
-       fprintf(stderr," evaluating %s \n",showoperator(p->op));
+    if (traceeval) {
+       fprintf(stderr, "begin eval %s\n", opname(p->op));
     }
     switch (degree(p->op)) {
        case BINARY:
     }
     switch (degree(p->op)) {
        case BINARY:
@@ -115,21 +167,26 @@ register Node p;
            s = p->value.sym;
            if (s == retaddrsym) {
                push(long, return_addr());
            s = p->value.sym;
            if (s == retaddrsym) {
                push(long, return_addr());
-           } else {
-               if (isvariable(s)) {
-                   if (s != program and not isactive(container(s))) {
-                       error("\"%s\" is not active", symname(s));
-                   }
-                   push(long, address(s, nil));
-               } else if (isblock(s)) {
-                   push(Symbol, s);
+           } else if (isvariable(s)) {
+               if (s != program and not isactive(container(s))) {
+                   error("\"%s\" is not active", symname(s));
+               }
+               if (isvarparam(s) and not isopenarray(s)) {
+                   rpush(address(s, nil), sizeof(Address));
                } else {
                } else {
-                   error("can't evaluate a %s", classname(s));
+                   push(Address, address(s, nil));
                }
                }
+           } else if (isblock(s)) {
+               push(Symbol, s);
+           } else if (isconst(s)) {
+               eval(constval(s));
+           } else {
+               error("can't evaluate a %s", classname(s));
            }
            break;
 
        case O_LCON:
            }
            break;
 
        case O_LCON:
+       case O_CCON:
            r0 = p->value.lcon;
            pushsmall(p->nodetype, r0);
            break;
            r0 = p->value.lcon;
            pushsmall(p->nodetype, r0);
            break;
@@ -145,15 +202,19 @@ register Node p;
            break;
 
        case O_INDEX:
            break;
 
        case O_INDEX:
-           n = pop(long);
-           i = evalindex(p->value.arg[0]->nodetype,
-               popsmall(p->value.arg[1]->nodetype));
-           push(long, n + i*size(p->nodetype));
+           s = p->value.arg[0]->nodetype;
+           p->value.arg[0]->nodetype = t_addr;
+           eval(p->value.arg[0]);
+           p->value.arg[0]->nodetype = s;
+           n = pop(Address);
+           eval(p->value.arg[1]);
+           evalindex(s, n, popsmall(p->value.arg[1]->nodetype));
            break;
 
        case O_DOT:
            s = p->value.arg[1]->value.sym;
            break;
 
        case O_DOT:
            s = p->value.arg[1]->value.sym;
-           n = lval(p->value.arg[0]);
+           eval(p->value.arg[0]);
+           n = pop(long);
            push(long, n + (s->symvalue.field.offset div 8));
            break;
 
            push(long, n + (s->symvalue.field.offset div 8));
            break;
 
@@ -168,25 +229,19 @@ register Node p;
            if (addr == 0) {
                error("reference through nil pointer");
            }
            if (addr == 0) {
                error("reference through nil pointer");
            }
-           if (p->op == O_INDIR) {
-               len = sizeof(long);
-           } else {
-               len = size(p->nodetype);
-           }
+           len = size(p->nodetype);
            rpush(addr, len);
            break;
 
            rpush(addr, len);
            break;
 
-       /*
-        * Effectively, we want to pop n bytes off for the evaluated subtree
-        * and push len bytes on for the new type of the same tree.
-        */
        case O_TYPERENAME:
        case O_TYPERENAME:
-           n = size(p->value.arg[0]->nodetype);
-           len = size(p->nodetype);
-           sp = sp - n + len;
+           loophole(size(p->value.arg[0]->nodetype), size(p->nodetype));
            break;
 
        case O_COMMA:
            break;
 
        case O_COMMA:
+           eval(p->value.arg[0]);
+           if (p->value.arg[1] != nil) {
+               eval(p->value.arg[1]);
+           }
            break;
 
        case O_ITOF:
            break;
 
        case O_ITOF:
@@ -318,51 +373,11 @@ register Node p;
            break;
 
        case O_LIST:
            break;
 
        case O_LIST:
-           if (p->value.arg[0]->op == O_SYM) {
-               f = p->value.arg[0]->value.sym;
-               addr = firstline(f);
-               if (addr == NOADDR) {
-                   error("no source lines for \"%s\"", symname(f));
-               }
-               setsource(srcfilename(addr));
-               r0 = srcline(addr) - 5;
-               r1 = r0 + 10;
-               if (r0 < 1) {
-                   r0 = 1;
-               }
-           } else {
-               eval(p->value.arg[0]);
-               r0 = pop(long);
-               eval(p->value.arg[1]);
-               r1 = pop(long);
-           }
-           printlines((Lineno) r0, (Lineno) r1);
+           list(p);
            break;
 
        case O_FUNC:
            break;
 
        case O_FUNC:
-           if (p->value.arg[0] == nil) {
-               printname(stdout, curfunc);
-               putchar('\n');
-           } else {
-               s = p->value.arg[0]->value.sym;
-               if (isroutine(s)) {
-                   setcurfunc(s);
-               } else {
-                   find(f, s->name) where isroutine(f) endfind(f);
-                   if (f == nil) {
-                       error("%s is not a procedure or function", symname(s));
-                   }
-                   setcurfunc(f);
-               }
-               addr = codeloc(curfunc);
-               if (addr != NOADDR) {
-                   setsource(srcfilename(addr));
-                   cursrcline = srcline(addr) - 5;
-                   if (cursrcline < 1) {
-                       cursrcline = 1;
-                   }
-               }
-           }
+           func(p->value.arg[0]);
            break;
 
        case O_EXAMINE:
            break;
 
        case O_EXAMINE:
@@ -436,17 +451,17 @@ register Node p;
 
        case O_WHEREIS:
            if (p->value.arg[0]->op == O_SYM) {
 
        case O_WHEREIS:
            if (p->value.arg[0]->op == O_SYM) {
-               printwhereis(stdout,p->value.arg[0]->value.sym);
+               printwhereis(stdout, p->value.arg[0]->value.sym);
            } else {
            } else {
-               printwhereis(stdout,p->value.arg[0]->nodetype);
+               printwhereis(stdout, p->value.arg[0]->nodetype);
            }
            break;
 
        case O_WHICH:
            if (p->value.arg[0]->op == O_SYM) {
            }
            break;
 
        case O_WHICH:
            if (p->value.arg[0]->op == O_SYM) {
-               printwhich(stdout,p->value.arg[0]->value.sym);
+               printwhich(stdout, p->value.arg[0]->value.sym);
            } else {
            } else {
-               printwhich(stdout,p->value.arg[0]->nodetype);
+               printwhich(stdout, p->value.arg[0]->nodetype);
            }
            putchar('\n');
            break;
            }
            putchar('\n');
            break;
@@ -454,21 +469,46 @@ register Node p;
        case O_ALIAS:
            n1 = p->value.arg[0];
            n2 = p->value.arg[1];
        case O_ALIAS:
            n1 = p->value.arg[0];
            n2 = p->value.arg[1];
-           if (n1 == nil) {
-               print_alias(nil);
-           } else if (n2 == nil) {
-               print_alias(n1->value.name);
+           if (n2 == nil) {
+               if (n1 == nil) {
+                   alias(nil, nil, nil);
+               } else {
+                   alias(n1->value.name, nil, nil);
+               }
+           } else if (n2->op == O_NAME) {
+               str = ident(n2->value.name);
+               alias(n1->value.name, nil, strdup(str));
            } else {
            } else {
-               enter_alias(n1->value.name, n2->value.name);
+               if (n1->op == O_COMMA) {
+                   alias(
+                       n1->value.arg[0]->value.name,
+                       (List) n1->value.arg[1],
+                       n2->value.scon
+                   );
+               } else {
+                   alias(n1->value.name, nil, n2->value.scon);
+               }
            }
            break;
 
            }
            break;
 
+       case O_UNALIAS:
+           unalias(p->value.arg[0]->value.name);
+           break;
+
+       case O_CALLPROC:
+           callproc(p, false);
+           break;
+
        case O_CALL:
        case O_CALL:
-           callproc(p->value.arg[0], p->value.arg[1]);
+           callproc(p, true);
            break;
 
        case O_CATCH:
            break;
 
        case O_CATCH:
-           psigtrace(process, p->value.lcon, true);
+           if (p->value.lcon == 0) {
+               printsigscaught(process);
+           } else {
+               psigtrace(process, p->value.lcon, true);
+           }
            break;
 
        case O_EDIT:
            break;
 
        case O_EDIT:
@@ -486,7 +526,16 @@ register Node p;
            break;
 
        case O_DUMP:
            break;
 
        case O_DUMP:
-           dump();
+           if (p->value.arg[0] == nil) {
+               dumpall();
+           } else {
+               s = p->value.arg[0]->value.sym;
+               if (s == curfunc) {
+                   dump(nil);
+               } else {
+                   dump(s);
+               }
+           }
            break;
 
        case O_GRIPE:
            break;
 
        case O_GRIPE:
@@ -498,7 +547,11 @@ register Node p;
            break;
 
        case O_IGNORE:
            break;
 
        case O_IGNORE:
-           psigtrace(process, p->value.lcon, false);
+           if (p->value.lcon == 0) {
+               printsigsignored(process);
+           } else {
+               psigtrace(process, p->value.lcon, false);
+           }
            break;
 
        case O_RETURN:
            break;
 
        case O_RETURN:
@@ -514,6 +567,14 @@ register Node p;
            run();
            break;
 
            run();
            break;
 
+       case O_SET:
+           set(p->value.arg[0], p->value.arg[1]);
+           break;
+
+       case O_SEARCH:
+           search(p->value.arg[0]->value.lcon, p->value.arg[1]->value.scon);
+           break;
+
        case O_SOURCE:
            setinput(p->value.scon);
            break;
        case O_SOURCE:
            setinput(p->value.scon);
            break;
@@ -532,6 +593,10 @@ register Node p;
            stop(p);
            break;
 
            stop(p);
            break;
 
+       case O_UNSET:
+           undefvar(p->value.arg[0]->value.name);
+           break;
+
        case O_UP:
            checkref(p->value.arg[0]);
            assert(p->value.arg[0]->op == O_LCON);
        case O_UP:
            checkref(p->value.arg[0]);
            assert(p->value.arg[0]->op == O_LCON);
@@ -595,8 +660,10 @@ register Node p;
                    printf("tracei: ");
                    printinst(pc, pc);
                } else {
                    printf("tracei: ");
                    printinst(pc, pc);
                } else {
-                   printf("trace:  ");
-                   printlines(curline, curline);
+                   if (canReadSource()) {
+                       printf("trace:  ");
+                       printlines(curline, curline);
+                   }
                }
            } else {
                printsrcpos();
                }
            } else {
                printsrcpos();
@@ -633,10 +700,9 @@ register Node p;
        default:
            panic("eval: bad op %d", p->op);
     }
        default:
            panic("eval: bad op %d", p->op);
     }
- if(debug_flag[2]) { 
-       fprintf(stderr," evaluated %s \n",showoperator(p->op));
- }
-           
+    if (traceeval) { 
+       fprintf(stderr, "end eval %s\n", opname(p->op));
+    }
 }
 
 /*
 }
 
 /*
@@ -718,23 +784,26 @@ long v;
 public long popsmall(t)
 Symbol t;
 {
 public long popsmall(t)
 Symbol t;
 {
+    register integer n;
     long r;
 
     long r;
 
-    switch (size(t)) {
-       case sizeof(char):
+    n = size(t);
+    if (n == sizeof(char)) {
+       if (t->class == RANGE and t->symvalue.rangev.lower >= 0) {
+           r = (long) pop(unsigned char);
+       } else {
            r = (long) pop(char);
            r = (long) pop(char);
-           break;
-
-       case sizeof(short):
+       }
+    } else if (n == sizeof(short)) {
+       if (t->class == RANGE and t->symvalue.rangev.lower >= 0) {
+           r = (long) pop(unsigned short);
+       } else {
            r = (long) pop(short);
            r = (long) pop(short);
-           break;
-
-       case sizeof(long):
-           r = pop(long);
-           break;
-
-       default:
-           panic("popsmall: size is %d", size(t));
+       }
+    } else if (n == sizeof(long)) {
+       r = pop(long);
+    } else {
+       error("[internal error: size %d in popsmall]", n);
     }
     return r;
 }
     }
     return r;
 }
@@ -746,13 +815,15 @@ Symbol t;
 public Boolean cond(p)
 Node p;
 {
 public Boolean cond(p)
 Node p;
 {
-    register Boolean b;
+    Boolean b;
+    int i;
 
     if (p == nil) {
        b = true;
     } else {
        eval(p);
 
     if (p == nil) {
        b = true;
     } else {
        eval(p);
-       b = (Boolean) pop(Boolrep);
+       i = pop(Boolrep);
+       b = (Boolean) i;
     }
     return b;
 }
     }
     return b;
 }
@@ -850,7 +921,7 @@ Node cond;
     Event e;
 
     if (exp->op == O_LCON) {
     Event e;
 
     if (exp->op == O_LCON) {
-       wh = build(O_QLINE, build(O_SCON, cursource), exp);
+       wh = build(O_QLINE, build(O_SCON, strdup(cursource)), exp);
     } else {
        wh = exp;
     }
     } else {
        wh = exp;
     }
@@ -957,6 +1028,9 @@ Node cond;
     Node event;
     Command action;
 
     Node event;
     Command action;
 
+    if (size(exp->nodetype) > MAXTRSIZE) {
+       error("expression too large to trace (limit is %d bytes)", MAXTRSIZE);
+    }
     p = (place == nil) ? tcontainer(exp) : place->value.sym;
     if (p == nil) {
        p = program;
     p = (place == nil) ? tcontainer(exp) : place->value.sym;
     if (p == nil) {
        p = program;
@@ -1054,6 +1128,9 @@ Node cond;
     Node event;
     Command action;
 
     Node event;
     Command action;
 
+    if (size(exp->nodetype) > MAXTRSIZE) {
+       error("expression too large to trace (limit is %d bytes)", MAXTRSIZE);
+    }
     if (place == nil) {
        if (exp->op == O_LCON) {
            p = program;
     if (place == nil) {
        if (exp->op == O_LCON) {
            p = program;
@@ -1093,48 +1170,131 @@ Node exp;
     long lvalue;
     float fvalue;
 
     long lvalue;
     float fvalue;
 
-    if (not compatible(var->nodetype, exp->nodetype)) {
-       error("incompatible types");
-    }
-    addr = lval(var);
-    varsize = size(var->nodetype);
-    expsize = size(exp->nodetype);
-    eval(exp);
-    if (varsize == sizeof(float) and expsize == sizeof(double)) {
-       fvalue = (float) pop(double);
-       dwrite(&fvalue, addr, sizeof(fvalue));
+    if (var->op == O_SYM and regnum(var->value.sym) != -1) {
+       eval(exp);
+       setreg(regnum(var->value.sym), pop(Address));
     } else {
     } else {
-       if (varsize < sizeof(long)) {
-           lvalue = 0;
-           popn(expsize, &lvalue);
-           switch (varsize) {
-               case sizeof(char):
+       addr = lval(var);
+       varsize = size(var->nodetype);
+       expsize = size(exp->nodetype);
+       eval(exp);
+       if (varsize == sizeof(float) and expsize == sizeof(double)) {
+           fvalue = (float) pop(double);
+           dwrite(&fvalue, addr, sizeof(fvalue));
+       } else {
+           if (varsize < sizeof(long)) {
+               lvalue = 0;
+               popn(expsize, &lvalue);
+               if (varsize == sizeof(char)) {
                    cvalue = lvalue;
                    dwrite(&cvalue, addr, sizeof(cvalue));
                    cvalue = lvalue;
                    dwrite(&cvalue, addr, sizeof(cvalue));
-                   break;
-
-               case sizeof(short):
+               } else if (varsize == sizeof(short)) {
                    svalue = lvalue;
                    dwrite(&svalue, addr, sizeof(svalue));
                    svalue = lvalue;
                    dwrite(&svalue, addr, sizeof(svalue));
-                   break;
-
-               default:
-                   panic("bad size %d", varsize);
+               } else {
+                   error("[internal error: bad size %d in assign]", varsize);
+               }
+           } else {
+               if (expsize <= varsize) {
+                   sp -= expsize;
+                   dwrite(sp, addr, expsize);
+               } else {
+                   sp -= expsize;
+                   dwrite(sp, addr, varsize);
+               }
            }
            }
+       }
+    }
+}
+
+/*
+ * Set a debugger variable.
+ */
+
+private set (var, exp)
+Node var, exp;
+{
+    Symbol t;
+
+    if (var == nil) {
+       defvar(nil, nil);
+    } else if (exp == nil) {
+       defvar(var->value.name, nil);
+    } else if (var->value.name == identname("$frame", true)) {
+       t = exp->nodetype;
+       if (not compatible(t, t_int) and not compatible(t, t_addr)) {
+           error("$frame must be an address");
+       }
+       eval(exp);
+       getnewregs(pop(Address));
+    } else {
+       defvar(var->value.name, unrval(exp));
+    }
+}
+
+/*
+ * Execute a list command.
+ */
+
+private list (p)
+Node p;
+{
+    Symbol f;
+    Address addr;
+    Lineno line, l1, l2;
+
+    if (p->value.arg[0]->op == O_SYM) {
+       f = p->value.arg[0]->value.sym;
+       addr = firstline(f);
+       if (addr == NOADDR) {
+           error("no source lines for \"%s\"", symname(f));
+       }
+       setsource(srcfilename(addr));
+       line = srcline(addr);
+       getsrcwindow(line, &l1, &l2);
+    } else {
+       eval(p->value.arg[0]);
+       l1 = (Lineno) (pop(long));
+       eval(p->value.arg[1]);
+       l2 = (Lineno) (pop(long));
+    }
+    printlines(l1, l2);
+}
+
+/*
+ * Execute a func command.
+ */
+
+private func (p)
+Node p;
+{
+    Symbol s, f;
+    Address addr;
+
+    if (p == nil) {
+       printname(stdout, curfunc);
+       putchar('\n');
+    } else {
+       s = p->value.sym;
+       if (isroutine(s)) {
+           setcurfunc(s);
        } else {
        } else {
-           if (expsize <= varsize) {
-               sp -= expsize;
-               dwrite(sp, addr, expsize);
-           } else {
-               sp -= expsize;
-               dwrite(sp, addr, varsize);
+           find(f, s->name) where isroutine(f) endfind(f);
+           if (f == nil) {
+               error("%s is not a procedure or function", symname(s));
            }
            }
+           setcurfunc(f);
+       }
+       addr = codeloc(curfunc);
+       if (addr != NOADDR) {
+           setsource(srcfilename(addr));
+           cursrcline = srcline(addr);
        }
     }
 }
 
 /*
        }
     }
 }
 
 /*
- * Send some nasty mail to the current support person.
+ * Send a message to the current support person.
  */
 
 public gripe()
  */
 
 public gripe()
@@ -1144,22 +1304,26 @@ public gripe()
     int pid, status;
     extern int versionNumber;
     char subject[100];
     int pid, status;
     extern int versionNumber;
     char subject[100];
-    char *maintainer = "linton@berkeley";
-
-    puts("Type control-D to end your message.  Be sure to include");
-    puts("your name and the name of the file you are debugging.");
-    putchar('\n');
-    old = signal(SIGINT, SIG_DFL);
-    sprintf(subject, "dbx (version %d) gripe", versionNumber);
-    pid = back("Mail", stdin, stdout, "-s", subject, maintainer, nil);
-    signal(SIGINT, SIG_IGN);
-    pwait(pid, &status);
-    signal(SIGINT, old);
-    if (status == 0) {
-       puts("Thank you.");
-    } else {
-       puts("\nMail not sent.");
-    }
+
+#   ifdef MAINTAINER
+       puts("Type control-D to end your message.  Be sure to include");
+       puts("your name and the name of the file you are debugging.");
+       putchar('\n');
+       old = signal(SIGINT, SIG_DFL);
+       sprintf(subject, "dbx (version 3.%d) gripe", versionNumber);
+       pid = back("Mail", stdin, stdout, "-s", subject, MAINTAINER, nil);
+       signal(SIGINT, SIG_IGN);
+       pwait(pid, &status);
+       signal(SIGINT, old);
+       if (status == 0) {
+           puts("Thank you.");
+       } else {
+           puts("\nMail not sent.");
+       }
+#   else
+       puts("Sorry, no dbx maintainer available to gripe to.");
+       puts("Try contacting your system manager.");
+#   endif
 }
 
 /*
 }
 
 /*