class DjVuParseOptions Examples

Examples using the DjVuParseOptions class
The following DjVuParseOptions examples demonstrates how to use the DjVuParseOptions class in your code.

                                        
        // First we define the command line arguments with the
        // normal option structure defined by getopt(3)
        // Only I didn't add support for any feature that requires
        // a non-constant structure.  So we can use a compile time
        // constant.
        static const char favorite_color_string[]="favorite-color";
        static const char pizza_topping_string[]="pizza-topping";
        static const char bignumber_string[]="bignumber";
        static const char redo_string[]="redo";
        static const char profile_string[]="profile";

   	static const djvu_option long_options[] = {
   	  {favorite_color_string,1,0,'f'},
   	  {pizza_topping_string,1,0,'P'},
   	  {bignumber_string,1,0,'n'},
   	  {redo_string,0,0,'r'},
   	  {profile_string,0,0,'p'},
   	  {0,0,0,0}
   	};
  
   	int
    	main(int argc,const char **argv,char **env)
      {
   	    char *profile,*topping,*color;
        int redo,bignumber;

   		  // This will read in the default configuration file
   		  // which is either ~/.DjVu/global.conf if it exists,
   		  // otherwise /etc/DjVu/global.conf.
   		  // Next the file MyConfigFile.conf will be read from
   		  // either ~/.DjVu or /etc/DjVu
        DjVuParseOptions MyOptions("MyConfigFile");

   		  // This parses the command line arguments.
        MyOptions.ParseArguments(argc,argv,long_options);

   		  // We could for example, check the value of a profile
   		  // option, and switch which profile we are using.
   	    profile=MyOptions.GetValue(profile_string);
        if(profile) MyOptions.ChangeProfile(profile);

   		  // Now we can read in the variables.
   		  // I find it is a good idea to only list the variable
   		  // strings once, so I use constant strings.  But this
        // isn't required.
   	    topping=MyOptions.GetValue(pizza_topping_string);
   	    color=MyOptions.GetValue(favorite_color_string);

   		  // We can also read in integers, and specify a default value
   		  // to return in case the value is not an integer.  In this
   		  // case I specified -1.
   	    bignumber=MyOptions.GetNumber(bignumber_string,-1);

   		  // We can also check true/false type values.
   	    redo=MyOptions.GetInteger(redo_string,0);

   		  // Now before we do anything with these values, we might
   		  // want to check for errors.
   	    if(MyOptions.HasError())
   	    {
   	       MyOptions.perror();
   	       usage();
   	    }

   	    ... Now we can do the real work of this program...

   	    exit(0);
   	  }

Now the more complicated issue is using the same object for libraries with a minimal amount of changes. The first issue to note is we don't want a library function to re-read the configuration file each time it is called. And we don't want to use static variables, since that could causing threading problems. So, I took the simplest solution, which is to assume a copy of the class object will always get once created in the first function.

So, then the problem is if we pass by value, then if a function reads in it's own profile, each time it is recalled, it will have lost that information and need to read in the same profile again. If we pass by references we run into problems that multiple functions can not parse argv[] arrays.

The compromise I reached is the profiles are stored in the class as references. So when you pass by "value," the profile information is still passed by reference. Consequently if you do something like:

                                        
   	  int foo(DjVuParseOptions);
   	  DjVuParseOptions Opts("Config");
   	  Opts.ParseArguments(argc,argv,long_opts,long_only);
   	  foo(Opts);

the copy of Opts passed to foo will not contain any information from the argv[] array. But it will contain the profile information. If you do a ChangeProfile() it will only affect the original to the extent if it does the same ChangeProfile() the configuration file will have already been parsed.

The core functionality is also available via C wrappers.

The configuration files themselves are fairly simple. They simple listings of the form:

                                        
   	<varable>=<value>

e.g.

                                        
   	foo="689234 ksdf"
   	fi=bar
   	test=TRUE

The one unique implementation detail is alternate profiles may be specified within a configuration file. The rules are simple. The default profile name is the file name. To end the current profile and begin a new one, simply list the new profile name followed by a ':'. e.g.

                                        
   	name=fido
   	species=dog
   	birthday=today
   	
   	# Lets begin an alternate profile for mycat
  
   	cats:
   	name=fluffy
   	species=cat
   	birthday=tomorrow
   	favorite-food=mice
   	mice-eaten-this-week=5

You can use quotes the same as in a shell script. If you don't use quotes, extra white spaces are stripped, and escape characters are used. All of the following are equivalent. e.g.

                                        
   	test="This is a simple test.\nThis is only a test.\\"
  
   	test="This is a simple test.
   	This is only a test.\\"
  
   	test= This is a simple test.\ 
   	\nThis 		is only		a test.\\ 
  
   	test='This is a simple test.
   	This is only a test.\'

Be very careful of missing quotes...

Alphabetic index Hierarchy of classes


DjVu is a trademark of LizardTech, Inc.
All other products mentioned are registered trademarks or trademarks of their respective companies.