diff --git a/source/auto_vararg.h b/source/auto_vararg.h
new file mode 100644
index 0000000..7829256
--- /dev/null
+++ b/source/auto_vararg.h
@@ -0,0 +1,44 @@
+#ifndef AUTO_VARARG
+#define AUTO_VARARG
+
+/* The following horrid macros can be used
+ *  to create vararg function which do not
+ *  require the developer to pass in the
+ *  argument count by hand.
+ */
+
+// useless without it, so might as well include
+#include <stdarg.h>
+
+#define PP_NARG(...)  PP_NARG_(__VA_ARGS__, PP_RSEQ_N())
+#define PP_NARG_(...) PP_128TH_ARG(__VA_ARGS__)
+#define PP_128TH_ARG( \
+          _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
+         _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
+         _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
+         _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
+         _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
+         _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
+         _61,_62,_63,_64,_65,_66,_67,_68,_69,_70, \
+         _71,_72,_73,_74,_75,_76,_77,_78,_79,_80, \
+         _81,_82,_83,_84,_85,_86,_87,_88,_89,_90, \
+         _91,_92,_93,_94,_95,_96,_97,_98,_99,_100, \
+         _101,_102,_103,_104,_105,_106,_107,_108,_109,_110, \
+         _111,_112,_113,_114,_115,_116,_117,_118,_119,_120, \
+         _121,_122,_123,_124,_125,_126,_127,N,...) N
+#define PP_RSEQ_N() \
+         127,126,125,124,123,122,121,120, \
+         119,118,117,116,115,114,113,112,111,110, \
+         109,108,107,106,105,104,103,102,101,100, \
+         99,98,97,96,95,94,93,92,91,90, \
+         89,88,87,86,85,84,83,82,81,80, \
+         79,78,77,76,75,74,73,72,71,70, \
+         69,68,67,66,65,64,63,62,61,60, \
+         59,58,57,56,55,54,53,52,51,50, \
+         49,48,47,46,45,44,43,42,41,40, \
+         39,38,37,36,35,34,33,32,31,30, \
+         29,28,27,26,25,24,23,22,21,20, \
+         19,18,17,16,15,14,13,12,11,10, \
+         9,8,7,6,5,4,3,2,1,0
+
+#endif
diff --git a/source/global.h b/source/global.h
index 0c157a5..fca2925 100644
--- a/source/global.h
+++ b/source/global.h
@@ -229,7 +229,9 @@ char *pathcomponents(char *path, int components);
 char *read_block(void);
 char *scanpast(char c);
 
-char	   **parse_options(int *argc, char **argv);
+char **parse_options(int *argc, char **argv);
+void readenv(void);
+
 void		 error_usage(void);
 void		 longusage(void);
 void		 usage(void);
diff --git a/source/library.h b/source/library.h
index e3ff5c2..028465c 100644
--- a/source/library.h
+++ b/source/library.h
@@ -41,7 +41,6 @@ char	   *egrepinit(const char *egreppat);
 char	   *logdir(char *name);
 const char *basename(const char *path);
 FILE	   *myfopen(char *path, char *mode);
-char	   *mygetenv(char *variable, char *deflt);
 int			myopen(char *path, int flag, int mode);
 FILE	   *mypopen(char *cmd, char *mode);
 int			mypclose(FILE *ptr);
diff --git a/source/main.c b/source/main.c
index ba59dde..fce98ae 100644
--- a/source/main.c
+++ b/source/main.c
@@ -50,13 +50,6 @@
 #include <signal.h>
 #include <getopt.h>
 
-/* defaults for unset environment variables */
-#define EDITOR	 "vi"
-#define HOME	 "/"   /* no $HOME --> use root directory */
-#define SHELL	 "sh"
-#define LINEFLAG "+%s" /* default: used by vi and emacs */
-#define TMPDIR	 "/tmp"
-
 /* note: these digraph character frequencies were calculated from possible
    printable digraphs in the cross-reference for the C compiler */
 char dichar1[] = " teisaprnl(of)=c";	/* 16 most frequent first chars */
@@ -65,9 +58,6 @@ char dichar2[] = " tnerpla";			/* 8 most frequent second chars
 char dicode1[256];						/* digraph first character code */
 char dicode2[256];						/* digraph second character code */
 
-char		*editor, *shell, *lineflag; /* environment variables */
-char		*home;						/* Home directory */
-bool		 lineflagafterfile;
 char		*argv0;						/* command name */
 bool		 compress = true;			/* compress the characters in the crossref */
 bool		 dbtruncated;				/* database symbols are truncated to 8 chars */
@@ -94,14 +84,12 @@ long		 totalterms;				/* total inverted index terms */
 bool		 trun_syms;					/* truncate symbols to 8 characters */
 char		 tempstring[TEMPSTRING_LEN + 1]; /* use this as a buffer, instead of 'yytext',
 											  * which had better be left alone */
-char *tmpdir;								 /* temporary directory */
 
 static char path[PATHLEN + 1];				 /* file path */
 
 /* Internal prototypes: */
 static void		   skiplist(FILE *oldrefs);
 static void		   initcompress(void);
-static inline void readenv(void);
 static inline void linemode_event_loop(void);
 static inline void screenmode_event_loop(void);
 
@@ -207,17 +195,6 @@ void myexit(int sig) {
 	exit(sig);
 }
 
-static inline void readenv(void) {
-	editor			  = mygetenv("EDITOR", EDITOR);
-	editor			  = mygetenv("VIEWER", editor);		   /* use viewer if set */
-	editor			  = mygetenv("CSCOPE_EDITOR", editor); /* has last word */
-	home			  = mygetenv("HOME", HOME);
-	shell			  = mygetenv("SHELL", SHELL);
-	lineflag		  = mygetenv("CSCOPE_LINEFLAG", LINEFLAG);
-	lineflagafterfile = getenv("CSCOPE_LINEFLAG_AFTER_FILE") ? 1 : 0;
-	tmpdir			  = mygetenv("TMPDIR", TMPDIR);
-}
-
 static inline void linemode_event_loop(void) {
 	int c;
 
diff --git a/source/mygetenv.c b/source/mygetenv.c
deleted file mode 100644
index 2f965c1..0000000
--- a/source/mygetenv.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*===========================================================================
- Copyright (c) 1998-2000, The Santa Cruz Operation
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- *Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- *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.
-
- *Neither name of The Santa Cruz Operation 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 COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
- IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT falseT 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 falseT 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.
- =========================================================================*/
-
-#include "library.h"
-
-#include <stdlib.h>
-
-/* return the non-null environment value or the default argument */
-
-char *mygetenv(char *variable, char *deflt) {
-	char *value;
-
-	value = getenv(variable);
-	if(value == NULL || *value == '\0') { return (deflt); }
-	return (value);
-}
diff --git a/source/opt.c b/source/opt.c
index 9fd3d0c..ffe1b6a 100644
--- a/source/opt.c
+++ b/source/opt.c
@@ -3,14 +3,70 @@
 #include "build.h"
 #include "vp.h"
 #include "version.inc"
+#include "auto_vararg.h"
 
 #include <stdlib.h>	 /* atoi */
 #include <getopt.h>
 
+/* defaults for unset environment variables */
+#define DEFAULT_EDITOR	 "vi"
+#define DEFAULT_HOME	 "/"   /* no $HOME --> use root directory */
+#define DEFAULT_SHELL	 "sh"
+#define DEFAULT_LINEFLAG "+%s" /* default: used by vi and emacs */
+#define DEFAULT_TMPDIR	 "/tmp"
+
+/* environment variable holders */
+char * editor;
+char * home;
+char * shell;
+char * lineflag;
+char * tmpdir;
+bool lineflagafterfile;
+
 bool  remove_symfile_onexit = false;
 bool  onesearch; /* one search only in line mode */
 char *reflines;	 /* symbol reference lines file */
 
+/* From a list of envirnment variable names,
+ *  return the first valid variable value
+ *  or the user given default.
+ */
+#define coalesce_env(def, ...) _coalesce_env(def, PP_NARG(__VA_ARGS__), __VA_ARGS__)
+static inline
+char * _coalesce_env(char * mydefault, size_t argc, ...) {
+    char * r = mydefault;
+    va_list va;
+    va_start(va, argc);
+
+    for (int i = 0; i < argc; i++) {
+        char * value = va_arg(va, char*);
+        value = getenv(value);
+
+        if (value != NULL
+        &&  *value != '\0') {
+            r = value;
+            goto end;
+        }
+    }
+
+  end:
+    va_end(va);
+    return r;
+}
+
+/* XXX: Add CSOPE_* equivalents while preserving the originals.
+ *       DO NOT do it without writting documentation
+ */
+void readenv(void) {
+    editor   = coalesce_env(DEFAULT_EDITOR, "CSCOPE_EDITOR", "VIEWER", "EDITOR");
+    home     = coalesce_env(DEFAULT_HOME, "HOME");
+    shell    = coalesce_env(DEFAULT_SHELL, "SHELL");
+    lineflag = coalesce_env(DEFAULT_LINEFLAG, "CSCOPE_LINEFLAG");
+    tmpdir   = coalesce_env(DEFAULT_TMPDIR, "TMPDIR");
+
+    lineflagafterfile = getenv("CSCOPE_LINEFLAG_AFTER_FILE") ? 1 : 0;
+}
+
 char **parse_options(int *argc, char **argv) {
 	int	  opt;
 	int	  longind;