/*	listvar		1994(?)  G. Flierl(?)				*/
/*    Provide list of variables in a JGOFS object to stdout.  One	*/
/*  variable is listed on each line, preceded by 0 or more spaces.  The	*/
/*  number of spaces, divided by 2, is the JGOFS "level" of the		*/
/*  variable within the object						*/
/*    Input arg is object name in the several permissible formats	*/
/*  See code of jdb.c followed by dct.c for definitive info		*/
/*  	1. [//machine]/subdir_of_obj_root/obj_name			*/
/*	2. "object file entry" (ie, method(param1,param2,...))		*/
/*	3. datafile_name						*/
/*	4.   ??								*/

#define LISTVAR_ID "listvar version 1.3b  30 Aug 2004"
/*  30 Aug 2004 - version 1.3b WJS					*/
/*	jdbfuncdefns.h							*/
/*  25 Aug 2004 - version 1.3b WJS					*/
/*	Needs an err entry for utils.c routine errors			*/
/*  23 Apr 2004 - version 1.3b WJS                                      */
/*	Mods to "version-returning function".				*/
/*	  a) change from local to global to ensure it can't be "opti-	*/
/*	     mized out"							*/
/*	  b) don't want "version" in any function name since such       */
/* 	     names appear when grep'ping for "version"		        */
/*  11 Feb 2004 - version 1.3b WJS					*/
/*	Fixes to get rid of compiler warnings				*/
/*	Use core.h & get its ID into this module			*/

/*  16 Oct 2003 - version 1.3a WJS					*/
/*	Explicitly exit with status of 0 after normal run		*/

/*  28 Jul 1998 - version 1.3 clh					*/
/*	Add -l switch to output level at which variable occurs		*/
/* 	    format of output becomes X, variablename			*/
/*	    where X is the level of the var				*/

/*  23 Sep 97.  v 1.2.	WJS						*/
/*	Add some comments.						*/
/*	Add an ID string and print it in diagnostic situations		*/
/*	Add error message if jdbopen_ returns error status		*/
/*	Diagnose incorrect # args					*/
/*	Add -a switch to add attributes string after variable names	*/
/*	  Attributes are ; separated and enclosed in []s		*/
/*		[Begin 1.2]						*/
/*  1995(?)								*/
/*	include <string.h> (? this entry a surmise based on info from	*/
/*	  C Hammond)							*/
/************************************************************************/
#include INNEROPTIONS
#include "jdbfuncdefns.h"

void err(s,t)
char *s,*t;
{
    /*  Quick and dirty for now (1.3b) ...				*/
  printf ("%s\n%s\n",s,t);
  printf ("%s\n",LISTVAR_ID);
  exit(1);
}

char *listvar_return_vers()
/*  Dummy routine.  Exists only to force .h file version string into	*/
/*  this module.  Note string must not be global or we'll have con-	*/
/*  flicts if another routine similarly includes the version string	*/
{
  static char version[] = LISTVAR_ID"/"FULL_JDBFUNCDEFNSH_VERSION;
  return version;
}

void print_usage(program_as_invoked)
char *program_as_invoked;
{
  printf ("Usage: %s [-a][-l] object\n",program_as_invoked);
  printf ("Options: \n	-a   follow variable names with attributes\n");
  printf ("  -l   precede variable names with level at which it occurs\n as X, variable\n");
  printf ("%s\n",LISTVAR_ID);
  exit(1);
}

int main(argc,argv)
int argc;
char *argv[];
{
char obj[1025];
int unit,maxlev,i,j;
char names[NVAR][VARNAMESIZE+1];
char attr[ATTRSIZE+1];
int num;
int namesize=VARNAMESIZE+1;	 /* Size of buffer, not max name		*/
int narg,nattr,attr_switch,level_switch;

  /*  Get switches (each assumed to start with -).  Assume there is	*/
  /*	only 1 non-switch argument (namely, the object name)		*/
narg = 0;
attr_switch = 0;
level_switch = 0;
for (i = 1; i < argc; i++) {
  if (*argv[i] == '-') {
    switch ( *(argv[i]+1) )   {
      case 'a':
	attr_switch = 1;
	break;
      case 'l':
	level_switch = 1;
	break;
      default:
	print_usage(argv[0]);
	break;
    }
      /*  Replace switch w/last arg so switches can occur anyplace	*/
      /*    and also so object ends up argv[1] as originally expected	*/
      /*  This logic fails if we ever add a second non-switch argument	*/
      /*    and depend on the order of the 2				*/
      /*  Non unix-like, but I hate having to put the switches first	*/
    argv[i--] = argv[--argc];
  } else {
    narg++;
  }
}
if (narg != 1) print_usage(argv[0]);

num= -NVAR;
unit=1;
strcpy(obj,argv[1]);
maxlev=jdbopen_(&unit,obj,names,&namesize,&num);
if(maxlev<0){
  printf ("jdbopen_: %d\n%s\n",maxlev,LISTVAR_ID);
  exit(1);
};

for(i=0;i<num;i++) {
  j=jdblevel_(&unit,&i);
  if (level_switch) 
    printf("%d, %s",j,names[i]);
  else 
    printf("%*.*s%s",j*2,j*2," ",names[i]);

  nattr = 0;
  if (attr_switch) {
    while (jdbattributes_(&unit,&i,attr)) {
      if (nattr == 0) printf ("[");
      else printf (";");
      printf ("%s",attr);
      nattr++;
    }
    if (nattr > 0) printf ("]");
  }
  printf ("\n");
};

jdbclose_(&unit);
exit(0);
}
