/*
Copyright (c) 2000-2010, Dirk Krause
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 
  opyright notice, this list of conditions and the following
  disclaimer in the documentation and/or other materials
  provided with the distribution.
* Neither the name of the Dirk Krause nor the names of
  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 NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*/



/*
-h	help
-v	version
-c	configure permanent options
-C	show permanent options
-r	skip permanent options for program invokation
-u	unconfigure (forget) permanent options

-t ft	input file type (png, jpeg, netpbm)
-l name	output file type, configured in .bmeps (eps/pdf)
-f n-m	frames (i.e. from tiff)
-o opt  options
-m      make style
*/



/**	@file	b2main.c
	The main program.
*/



/** Inside the b2main.c module.
*/
#define B2MAIN_C	1
#include "bmepsi.h"
#include "dktools-version.h"




#line 71 "b2main.ctr"




/**	Long options.
*/
static char *long_options[] = {
  /*   0 */ "h$elp",
  /*   1 */ "v$ersion",
  /*   2 */ "conf$igure",
  /*   3 */ "unconf$igure",
  /*   4 */ "res$et",
  /*   5 */ "sh$ow-configuration",
  /*   6 */ "sil$ently",
  /*   7 */ "lang$uage",
  /*   8 */ "opt$ion",
  /*   9 */ "f$rames",
  /*  10 */ "t$ype",
  /*  11 */ "configuration-file",
  /*  12 */ "write-configuration-file",
  NULL
};


/** String on. */
static char str_on[] = { "on" };

/** String off. */
static char str_off[] = { "off" };

/** String /language. */
static char pk_lang[] = { "/language" };

/** String /make. */
static char pk_make[] = { "/make" };

/** String /pdf/suppress-alpha-info. */
static char pk_alph[] = { "/pdf/suppress-alpha-info" };

/** Empty string. */
static char empty_string[] = { "" };

/**	Help text to show from "bmeps --help".
*/
static char *help_text[] = {
"Usage:",
"------",
"",
"bmeps [-l <language>] [ <inputfile> [ <outputfile> ] ] [<options>]",
"",
"Options:",
"<language>          Output language",
"-o <option-setting>    Configuration setting",
"-m                     Make style",
"-f <frame-range>       Start and end frame",
"-t <file-type>         Input file type when processing standard input",
"-a                     Automatically create output file name",
"-A                     Suppress notice about transferred alpha channel(s)",
NULL
};

/**	Name of help text file.
*/
static char help_file_name[] = { "bmeps.txt" };

/**	Names of output types.
*/
static char *output_type_names[] = {
  "EPS", "PDF", "BB (bounding box)"
};

/**	EPS levels.
*/
static char *eps_levels[] = { "1", "2", "3" };

/**	PDF levels.
*/
static char *pdf_levels[] = { "1.2", "1.3", "1.4" };

/**	Text to show as version information.
*/
static char *version_text[] = {
"",
"bmeps, version " VERSNUMB,
"Copyright (C) 2007-2010 Dipl.-Ing. D. Krause",
"http://dktools.sourceforge.net/bmeps.html",
"Supported input file types: PNG"
#if DK_HAVE_JPEGLIB_H
" JPEG"
#endif
#if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H
" NetPBM"
#endif
#if DK_HAVE_TIFF_H
" TIFF"
#endif
"",
"",
"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 the name of the Dirk Krause nor the names of other 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 NOT LIMITED TO, THE",
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE",
"ARE DISCLAIMED.",
"IN NO EVENT SHALL THE COPYRIGHT OWNER 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.",
NULL
};

/**	Encoding type names.
*/
static char *encoding_types[] = {
  "ascii85", "run-length", "lzw", "dct", "flate"
};

/**	File name separator character.
*/
static char sep[] = {
#if DK_HAVE_FEATURE_BACKSLASH
"\\"
#else
"/"
#endif
};


/** Output file name suffixes.
*/
static char *suffixes[] = { ".pdf", ".eps", ".bb" };

/**	The bmeps options set.
*/
static BO bo;

/**	The bmeps job data.
*/
static BJ bj;



/**	Check whether or not to run silently.
	Set *rs (run silently) and *rf (run as filter).
	@param	argc	Number of command line arguments.
	@param	argv	Command line arguments array.
	@param	rs	Pointer to run-silently flag.
	@param	rf	Pointer to run-as-filter flag.
*/
static
void
silence_check DK_P4(int,argc, char **,argv, int *,rs, int *,rf)
{
  int i; char *ptr, **lfdptr;
  int myrf = 1, myrs = 0;
  lfdptr = argv; lfdptr++; i = 1;
  
  while(i < argc) {
    ptr = *lfdptr;
    if(*ptr == '-') {
      ptr++;
      if(*ptr == '-') {
        ptr++;
	switch(dkstr_array_abbr(long_options, ptr, '$', 0)) {
	  case 6: myrs = 1; break;
	}
      } else {
        switch(*ptr) {
	  case 't': case 'l': case 'f': case 'o':
	  {
	    ptr++;
	    if(!(*ptr)) {
	      lfdptr++; i++;
	    }
	  } break;
	  case 's': {
	    myrs = 1;
	  } break;
	}
      }
    } else {
      myrf = 0;
    }
    lfdptr++; i++;
  }
  if(rs) { *rs = myrs; }
  if(rf) { *rf = myrf; }
  
}



/**	Apply command line arguments to bmeps job.
	@param	bj	Bmeps job.
	@param	dl	Argument to apply.
*/
static
void
apply_arguments DK_P2(BJ *,bj, char *,dl)
{
  char *ptr, **myargv, **lfdptr, *vptr, *ovptr;
  int have_configured = 0, myargc, i;
  
  myargc = dkapp_get_argc(bj->a);
  myargv = dkapp_get_argv(bj->a);
  lfdptr = myargv; lfdptr++; i = 1;
  while(i < myargc) {
    ptr = *lfdptr;
    if(*ptr == '-') {
      ptr++;
      switch(*ptr) {
        case '-': {
	  ptr++;
	  vptr = dkstr_chr(ptr, '=');
	  ovptr = vptr;
	  if(vptr) { *(vptr++) = '\0'; }
	  switch(dkstr_array_abbr(long_options, ptr, '$', 0)) {
	    case 0: {	/* help */
	      bj->cmd |= BMEPS_CMD_HELP;
	    } break;
	    case 1: {	/* version */
	      bj->cmd |= BMEPS_CMD_VERSION;
	    } break;
	    case 2: {	/* configure */
	      bj->cmd |= BMEPS_CMD_CONFIGURE;
	    } break;
	    case 3: {	/* unconfigure */
	      bj->cmd |= BMEPS_CMD_UNCONFIGURE;
	    } break;
	    case 4: {	/* reset */
	      bj->mm = 0x00;
	      bmeps_bo_get_configuration(bj, NULL, 0);
	    } break;
	    case 5: {	/* show-configuration */
	      bj->cmd |= BMEPS_CMD_SHOWCONF;
	    } break;
	    case 6: {	/* silently */
	    } break;
	    case 7: {	/* language */
	      if(vptr) {
	        if(!have_configured) {
		  bj->lang = vptr;
		  have_configured = 1;
		  bmeps_bo_get_configuration(bj, vptr, 1);
		} else {
		  bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 49);
		  bj->exval = 1;
		}
	      }
	    } break;
	    case 8: {	/* option */
	      if(vptr) {
	        if(!have_configured) {
		  have_configured = 1;
		  bmeps_bo_get_configuration(bj, NULL, 1);
		}
		bmeps_bo_add_line(bj, bj->bo, vptr);
	      }
	    } break;
	    case 9: {	/* frames */
	      if(vptr) {
	        long l; int ok = 0;
	        char *ptr1, *ptr2;
	        ptr1 = dkstr_start(vptr, NULL);
	        if(ptr1) {
	          ptr2 = dkstr_chr(ptr1, '-');
	          if(ptr2) {
	            *ptr2 = '\0';
	          }
	          if(sscanf(ptr1, "%ld", &l) == 1) {
	            if(l > 0L) {
	              bj->frame_s = bj->frame_e = l - 1L;
	              ok = 1;
		      bj->frame_c = 0x01;
		      
	            }
	          }
	          if(ptr2) {
	            *(ptr2++) = '-';
	            if(ok) {
	              if(sscanf(ptr2, "%ld", &l) == 1) {
		        if(l > 0L) {
		          if(l > bj->frame_s) {
		            bj->frame_e = l - 1L;
		            
		          }
		        }
		      }
	            }
	            ptr2++;
	          }
	        }
	      }
	    } break;
	    case 10: {	/* type */
	      if(vptr) {
	        bj->it = dkbif_get_type(vptr);
	      }
	    } break;
	    case 11: {
	      bj->cmd |= BMEPS_CMD_CONFIGURATION_FILE;
	    } break;
	    case 12: {
	      bj->cmd |= BMEPS_CMD_WRITE_CONFIGURATION_FILE;
	    } break;
	  }
	  if(ovptr) { *ovptr = '='; }
	} break;
	case 'a': {
	  bj->af = 0x01;
	} break;
	case 'A': {
	  ptr++;
	  if(*ptr == '-') {
	    bj->suppress_alpha_info = 0x00;
	  } else {
	    bj->suppress_alpha_info = 0x01;
	  }
	} break;
        case 'h': {
	  bj->cmd |= BMEPS_CMD_HELP;
	} break;
        case 'v': {
	  bj->cmd |= BMEPS_CMD_VERSION;
	} break;
        case 'c': {
	  bj->cmd |= BMEPS_CMD_CONFIGURE;
	} break;
        case 'u': {
	  bj->cmd |= BMEPS_CMD_UNCONFIGURE;
	} break;
        case 'r': {
	  bj->mm = 0x00;
	  bj->suppress_alpha_info = 0x00;
	  bmeps_bo_get_configuration(bj, NULL, 0);
	} break;
        case 'C': {
	  bj->cmd |= BMEPS_CMD_SHOWCONF;
	} break;
        case 'l': {
	  ptr++;
	  if(!(*ptr)) {
	    lfdptr++; i++;
	    if(i < myargc) {
	      ptr = *lfdptr;
	    }
	  }
	  if(ptr) {
	    if(!have_configured) {
	      bj->lang = ptr;
	      have_configured = 1;
	      bmeps_bo_get_configuration(bj, ptr, 1);
	    } else {
	      bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 49);
	      bj->exval = 1;
	    }
	  }
	} break;
        case 'o': {
	  ptr++;
	  if(!(*ptr)) {
	    lfdptr++; i++;
	    if(i < myargc) {
	      ptr = *lfdptr;
	    }
	  }
	  if(ptr) {
	    if(!have_configured) {
	      have_configured = 1;
	      bmeps_bo_get_configuration(bj, NULL, 1);
	    }
	    bmeps_bo_add_line(bj, bj->bo, ptr);
	  }
	} break;
	case 'f': {
	  ptr++;
	  if(!(*ptr)) {
	    lfdptr++; i++;
	    if(i < myargc) {
	      ptr = *lfdptr;
	    }
	  }
	  if(ptr) {
	    long l; int ok = 0;
	    char *ptr1, *ptr2;
	    ptr1 = dkstr_start(ptr, NULL);
	    if(ptr1) {
	      ptr2 = dkstr_chr(ptr1, '-');
	      if(ptr2) {
	        *ptr2 = '\0';
	      }
	      if(sscanf(ptr1, "%ld", &l) == 1) {
	        if(l > 0L) {
	          bj->frame_s = bj->frame_e = l - 1L;
	          ok = 1;
		  bj->frame_c = 0x01;
		  
	        }
	      }
	      if(ptr2) {
	        *(ptr2++) = '-';
	        if(ok) {
	          if(sscanf(ptr2, "%ld", &l) == 1) {
		    if(l > 0L) {
		      if(l > bj->frame_s) {
		        bj->frame_e = l - 1L;
		        
		      }
		    }
		  }
	        }
	        ptr2++;
	      }
	    }
	  }
	} break;
        case 'm': {
	  ptr++;
	  if(*ptr == '-') {
	    bj->mm = 0x0;
	  } else {
	    bj->mm = 0x1;
	  }
	} break;
        case 's': {
	} break;
	case 't': {
	  ptr++;
	  if(!(*ptr)) {
	    lfdptr++; i++;
	    if(i < myargc) {
	      ptr = *lfdptr;
	    }
	  }
	  if(ptr) {	
	    bj->it = dkbif_get_type(ptr);
	    
	  }
	} break;
	default: {
	  bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 50, 51, ptr);
	  bj->exval = 1;
	} break;
      }
    } else {
      if(bj->o1) {
	bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 52);
	bj->exval = 1;
      } else {
        if(bj->i1) { bj->o1 = ptr; }
	else { bj->i1 = ptr; }
      }
    }
    lfdptr++; i++;
  }
  if(!have_configured) {
    bmeps_bo_get_configuration(bj, NULL, 1);
    bj->lang = dl;
  }
  
}



/**	Show the version number and license information.
	@param	bj	Bmeps job.
*/
static
void
show_version DK_P1(BJ *,bj)
{
  char **xptr;
  
  xptr = version_text;
  while(*xptr) {
    fputs(*(xptr++), stdout); fputc('\n', stdout);
  }
  fputc('\n', stdout);
  fputs("Libraries used:\n\n", stdout);
  xptr = dkbif_lic_get();
  while(*xptr) { fputs(*(xptr++), stdout); fputc('\n', stdout); }
  xptr = dklic_get();
  while(*xptr) { fputs(*(xptr++), stdout); fputc('\n', stdout); }
  fputc('\n', stdout);
  
}



/**	Show help text.
	@param	bj	Bmeps job.
*/
static
void
show_help DK_P1(BJ *,bj)
{
  
  dkapp_help(bj->a, help_file_name, help_text);
}



/**	Find maximum string length in print (after text -> utf-8 conversion).
	@param	bj	Bmeps job.
	@param	s1	Start index.
	@param	s2	End index.
	@return	The maximum string length.
*/
static
size_t
max_str_length DK_P3(BJ *,bj, size_t, s1, size_t,s2)
{
  size_t back = 0, i = 0, sz = 0;
  for(i = s1; i <= s2; i++) {
    sz = dkapp_prlen(bj->a, (bj->msg)[i]);
    if(sz > back) back = sz;
  }
  return back;
}



/**	Print string formatted.
	Spaces are appended to fit the string to maxl.
	@param	bj	Bmeps job.
	@param	s	String to print.
	@param	maxl	Length reserved for string.
*/
static
void
fputs_formatted DK_P3(BJ *,bj, char *,s, size_t,maxl)
{
  size_t sz, i;
  dkapp_stdout(bj->a, s);
  sz = dkapp_prlen(bj->a, s);
  if(sz < maxl) {
    for(i = sz; i < maxl; i++) fputc(' ', stdout);
  }
}



/**	Write configuration to preferences.
	@param	bj	Bmeps sjob.
*/
static
void
write_configuration DK_P1(BJ *,bj)
{
  
  dkapp_set_pref(bj->a, pk_lang,((bj->lang) ? bj->lang : empty_string));
  dkapp_set_pref(bj->a, pk_make,((bj->mm) ? str_on : str_off));
  dkapp_set_pref(bj->a, pk_alph,((bj->suppress_alpha_info) ? str_on : str_off));
  
}



/**	Show whether output is colored.
	@param	bj	Bmeps job.
	@param	maxl	Reserved space.
	@param	cp	Code page.
*/
static
void
show_colored_output DK_P3(BJ *,bj, size_t, maxl, unsigned char *,cp)
{
  fputs_formatted(bj, (bj->msg)[8], maxl);
  dkapp_stdout(
    bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_COLOR_OUTPUT) ? 3 : 4]
  );
  fputc('\n', stdout);
}



/**	Show details.
	@param	bj	Bmeps job.
	@param	cp	Code page.
*/
static
void
show_details DK_P2(BJ *,bj, unsigned char *,cp)
{
  size_t sz, i;
  fputc('\n', stdout);
  dkapp_stdout(bj->a, (bj->msg)[24]); fputc('\n', stdout);
  sz = strlen((bj->msg)[24]);
  for(i = 0; i < sz; i++) fputc('-', stdout);
  fputc('\n', stdout);
}



/**	Show encodings.
	@param	bj	Bmeps job.
	@param	maxl	Reserved text width for output.
	@param	cp	Code page.
*/
static
void
show_encodings DK_P3(BJ *,bj, size_t,maxl, unsigned char *,cp)
{
  int found_data = 0;
  fputs_formatted(bj, (bj->msg)[9], maxl);
  if(((bj->bo)->enc) & BMEPS_ENCODING_ASCII85) {
    if(found_data) fputc(',', stdout);
    dkapp_stdout(bj->a, encoding_types[0]); found_data = 1;
  }
  if(((bj->bo)->enc) & BMEPS_ENCODING_RUNLENGTH) {
    if(found_data) fputc(',', stdout);
    dkapp_stdout(bj->a, encoding_types[1]); found_data = 1;
  }
  if(((bj->bo)->enc) & BMEPS_ENCODING_DCT) {
    if(found_data) fputc(',', stdout);
    dkapp_stdout(bj->a, encoding_types[3]); found_data = 1;
  }
  if(((bj->bo)->enc) & BMEPS_ENCODING_FLATE) {
    if(found_data) fputc(',', stdout);
    dkapp_stdout(bj->a, encoding_types[4]); found_data = 1;
  }
  fputc('\n', stdout);
}



/**	Show interpolation.
	@param	bj	Bmeps job.
	@param	maxl	Reserved space.
	@param	cp	Code page.
*/
static
void
show_interpolation DK_P3(BJ *,bj, size_t,maxl, unsigned char *,cp)
{
  fputs_formatted(bj, (bj->msg)[22], maxl);
  dkapp_stdout(bj->a, (bj->msg)[((bj->bo)->opt & BMEPS_OPT_INTERPOLATE) ? 3 : 4]);
  fputc('\n', stdout);
}



/**	Show alpha-channel mixing settings.
	@param	bj	Bmeps job.
	@param	maxl	Reserved space for output.
	@param	cp	Code page.
*/
static
void
show_alpha_channel_mixing DK_P3(BJ *,bj, size_t,maxl, unsigned char *,cp)
{
  char colorbuffer[256];
  fputs_formatted(bj, (bj->msg)[11], maxl);
  dkapp_stdout(bj->a, (bj->msg)[((bj->bo)->opt & BMEPS_OPT_ALPHA_MIX) ? 3 : 4]);
  fputc('\n', stdout);
  if((bj->bo)->opt & BMEPS_OPT_ALPHA_MIX) {
    
    fputs_formatted(bj, (bj->msg)[25], maxl);
    
    sprintf(
      colorbuffer,
      "r=%lg g=%lg b=%lg",
      (bj->bo)->dbgr, (bj->bo)->dbgg, (bj->bo)->dbgb
    );
    
    dkapp_stdout(bj->a, colorbuffer);
    
    fputc('\n', stdout);
    
    fputs_formatted(bj, (bj->msg)[12], maxl);
    
    dkapp_stdout(bj->a, (bj->msg)[((bj->bo)->opt & BMEPS_OPT_PREFER_SPEC_BG) ? 3 : 4]);
    
    fputc('\n', stdout);
  }
  fputs_formatted(bj, (bj->msg)[13], maxl);
  dkapp_stdout(bj->a, (bj->msg)[((bj->bo)->opt & BMEPS_OPT_IMAGE_MASK) ? 3 : 4]);
  fputc('\n', stdout);
  if((bj->bo)->opt & BMEPS_OPT_IMAGE_MASK) {
    fputs_formatted(bj, (bj->msg)[14], maxl);
    sprintf(colorbuffer, "%lg", (bj->bo)->mtl);
    dkapp_stdout(bj->a, colorbuffer);
    fputc('\n', stdout);
  }
}



/**	Show resolution and media size settings.
	@param	bj	Bmeps job
	@param	maxl	Reserved space for output.
	@param	cp	Code page.
*/
static
void
show_resolution_and_media_size DK_P3(BJ *,bj, size_t, maxl, unsigned char *,cp)
{
  char colorbuffer[256];
  if((bj->bo)->opt & BMEPS_OPT_PAPER_SIZE) {
    fputs_formatted(bj, (bj->msg)[21], maxl);
    sprintf(
      colorbuffer, 
      "(%lg %lg)...(%lg %lg) / (%lg %lg)...(%lg %lg)",
      ((bj->bo)->ms).bx0,
      ((bj->bo)->ms).by0,
      ((bj->bo)->ms).bx1,
      ((bj->bo)->ms).by1,
      ((bj->bo)->ms).px0,
      ((bj->bo)->ms).py0,
      ((bj->bo)->ms).px1,
      ((bj->bo)->ms).py1
    );
    dkapp_stdout(bj->a, colorbuffer);
    fputc('\n', stdout);
  } else {
    fputs_formatted(bj, (bj->msg)[15], maxl);
    dkapp_stdout(bj->a, (bj->msg)[((bj->bo)->opt & BMEPS_OPT_RESOLUTION) ? 3 : 4]);
    fputc('\n', stdout);
  }
}



/**	Show EPS output options.
	@param	bj	Bmeps job.
	@param	maxl	Reserved space for output.
	@param	cp	Code page.
*/
static
void
show_configuration_eps DK_P3(BJ *,bj, size_t, maxl, unsigned char *,cp)
{
  fputs_formatted(bj, (bj->msg)[6], maxl);
  switch((bj->bo)->l) {
    case BMEPS_PS_LEVEL_1: {
      dkapp_stdout(bj->a, eps_levels[0]);
    } break;
    case BMEPS_PS_LEVEL_2: {
      dkapp_stdout(bj->a, eps_levels[1]);
    } break;
    case BMEPS_PS_LEVEL_3: {
      dkapp_stdout(bj->a, eps_levels[2]);
    } break;
  }
  fputc('\n', stdout);
  fputs_formatted(bj, (bj->msg)[23], maxl);
  dkapp_stdout(bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_DRAFT) ? 3 : 4]);
  fputc('\n', stdout);
  if((bj->bo)->l >= BMEPS_PS_LEVEL_2) {
    show_colored_output(bj, maxl, cp);
    if(((bj->bo)->opt) & BMEPS_OPT_COLOR_OUTPUT) {
      fputs_formatted(bj, (bj->msg)[10], maxl);
      dkapp_stdout(bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_SEPARATED_DATA) ? 3 : 4]);
      fputc('\n', stdout);
    }
    fputs_formatted(bj, (bj->msg)[19], maxl);
    dkapp_stdout(bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_OPERATOR_DICTIONARY) ? 3 : 4]);
    fputc('\n', stdout);
    if((bj->bo)->opt & BMEPS_OPT_OPERATOR_DICTIONARY) {
      show_interpolation(bj, maxl, cp);
    }
    show_encodings(bj, maxl, cp);
    show_alpha_channel_mixing(bj, maxl, cp);
  }
  show_resolution_and_media_size(bj, maxl, cp);
  fputs_formatted(bj, (bj->msg)[16], maxl);
  dkapp_stdout(bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_SHOWPAGE) ? 3 : 4]);
  fputc('\n', stdout);
  if((bj->bo)->l >= BMEPS_PS_LEVEL_2) {
    fputs_formatted(bj, (bj->msg)[17], maxl);
    dkapp_stdout(bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_DICTIONARY) ? 3 : 4]);
    fputc('\n', stdout);
    fputs_formatted(bj, (bj->msg)[18], maxl);
    dkapp_stdout(bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_VMRECLAIM) ? 3 : 4]);
    fputc('\n', stdout);
  }
}



/**	Show PDF output settings.
	@param	bj	Bmeps job.
	@param	maxl	Space reserved for output.
	@param	cp	Code page.
*/
static
void
show_configuration_pdf DK_P3(BJ *,bj, size_t, maxl, unsigned char *,cp)
{
  int ta;	/* transfer alpha channel */
  ta = 0;
  fputs_formatted(bj, (bj->msg)[6], maxl);
  switch((bj->bo)->l) {
    case BMEPS_PDF_LEVEL_12: {
      dkapp_stdout(bj->a, pdf_levels[0]); 
    } break;
    case BMEPS_PDF_LEVEL_13: {
      dkapp_stdout(bj->a, pdf_levels[1]);
    } break;
    case BMEPS_PDF_LEVEL_14: {
      dkapp_stdout(bj->a, pdf_levels[2]);
    } break;
  }
  fputc('\n', stdout);
  fputs_formatted(bj, (bj->msg)[23], maxl);
  dkapp_stdout(bj->a, (bj->msg)[(((bj->bo)->opt) & BMEPS_OPT_DRAFT) ? 3 : 4]);
  fputc('\n', stdout);
  show_colored_output(bj, maxl, cp);
  show_encodings(bj, maxl, cp);
  show_interpolation(bj, maxl, cp);
  if((bj->bo)->l >= BMEPS_PDF_LEVEL_14) {
    if((bj->bo)->opt & BMEPS_OPT_TRANSFER_ALPHA) {
      ta = 1;
    }
  }
  fputs_formatted(bj, (bj->msg)[20], maxl);
  dkapp_stdout(bj->a, (bj->msg)[(ta) ? 3 : 4]);
  fputc('\n', stdout);
  if(!ta) {
    show_alpha_channel_mixing(bj, maxl, cp);
  } else {
  }
  show_resolution_and_media_size(bj, maxl, cp);
}



/**	Show configuration.
	@param	bj	Bmeps job.
*/
static
void
show_configuration DK_P1(BJ *,bj)
{
  char *str;
  size_t sz, i;
  unsigned char *cp = NULL;;
  
  if(bj->a) {
    cp = dkapp_get_stdout_codepage(bj->a);
  }
  /* section */
  fputc('\n', stdout);
  str = (bj->msg)[0];
  dkapp_fputs(bj->a, str, stdout);
  fputc('\n', stdout);
  /* underline section */
  sz = dkapp_prlen(bj->a, str);
  for(i = 0; i < sz; i++) fputc('-', stdout);
  fputc('\n', stdout);
  sz = max_str_length(bj, 1, 2);
  if(dkapp_prlen(bj->a, (bj->msg)[96]) > sz) {
    sz = dkapp_prlen(bj->a, (bj->msg)[96]);
  }
  sz++;
  fputs_formatted(bj, (bj->msg)[1], sz);
  dkapp_stdout(bj->a, ((bj->lang) ? (bj->lang) : empty_string));
  fputc('\n', stdout);
  fputs_formatted(bj, (bj->msg)[2], sz);
  dkapp_stdout(bj->a, (bj->msg)[(bj->mm) ? 3 : 4]);
  fputc('\n', stdout);
  fputs_formatted(bj, (bj->msg)[96], sz);
  dkapp_stdout(bj->a, (bj->msg)[(bj->suppress_alpha_info) ? 3 : 4]);
  fputc('\n', stdout);
  show_details(bj, cp);
  sz = 1 + max_str_length(bj, 5, 23);
  fputs_formatted(bj, (bj->msg)[5], sz);
  switch((bj->bo)->ot) {
    case BMEPS_OUTPUT_TYPE_PDF: {
      dkapp_stdout(bj->a, output_type_names[1]);
    } break;
    case BMEPS_OUTPUT_TYPE_BB: {
      dkapp_stdout(bj->a, output_type_names[2]);
    } break;
    default: {
      dkapp_stdout(bj->a, output_type_names[0]);
    } break;
  }
  fputc('\n', stdout);
  switch((bj->bo)->ot) {
    case BMEPS_OUTPUT_TYPE_PDF: {
      show_configuration_pdf(bj, sz, cp);
    } break;
    case BMEPS_OUTPUT_TYPE_BB: {
    } break;
    default: {
      show_configuration_eps(bj, sz, cp);
    } break;
  }
  
}



/**	Run for application options.
	@param	bj	Bmeps job.
*/
static
void
run_for_app_options DK_P1(BJ *,bj)
{
  
    if((bj->cmd) & BMEPS_CMD_HELP) {
      show_version(bj);
      show_help(bj);
    } else {
      if((bj->cmd) & BMEPS_CMD_VERSION) {
        show_version(bj);
      }
      if((bj->cmd) & BMEPS_CMD_UNCONFIGURE) {
        dkapp_unconfigure(bj->a);
      } else {
        if((bj->cmd) & BMEPS_CMD_CONFIGURE) {
	  write_configuration(bj);
	}
      }
      if((bj->cmd) & (BMEPS_CMD_CONFIGURE | BMEPS_CMD_SHOWCONF)) {
        show_configuration(bj);
      }
    }
    if((bj->cmd) & BMEPS_CMD_CONFIGURATION_FILE) {
      bmeps_bo_show_configuration_file(bj);
    }
    if((bj->cmd) & BMEPS_CMD_WRITE_CONFIGURATION_FILE) {
      if(!bmeps_bo_write_configuration_file(bj)) {
        bj->exval = 1;
      }
    }
  
}



/**	Transfer file contents (to create copy of a tiff file).
	@param	bj	Bmeps jobs.
	@param	fi	Input file.
	@param	fo	Output file.
	@return	1 on success, 0 on error.
*/
static
int
transfer_file_contents DK_P3(BJ *,bj, FILE *,fi, FILE *,fo)
{
  int back = 1, write_failed = 0;
  char buffer[4096]; size_t s1 = 0, s2 = 0; int cc = 1;
  while(cc) {
    s1 = fread((void *)buffer, 1, sizeof(buffer), fi);
    if(s1 > 0) {
      if(fo) {
        s2 = fwrite((void *)buffer, 1, s1, fo);
        if(s2 < s1) {
          cc = 0; back = 0;
	  write_failed = 1;
        }
      }
    } else {
      cc = 0;
    }
  }
  if(write_failed) {
    bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 53);
  }
  return back;
}



/**	Run for two real file names.
	Wildcards in the file names are expanded/resolved.
	@param	bj	Bmeps job.
	@param	in	Input file name.
	@param	on	Output file name.
*/
static
void
run_for_two_real_filenames DK_P3(BJ *,bj, char *,in, char *,on)
{
  FILE *fpi = NULL, *fpo = NULL;
  
  if(bj->it == DKBIF_TYPE_UNKNOWN) bj->it = dkbif_get_type(in);
  fpi = dkapp_fopen(bj->a, in, "rb");
  if(fpi) {
    fpo = dkapp_fopen(bj->a, on, "wb");
    if(fpo) {
      bj->inf = fpi;
      bj->outf = fpo;
      bj->infname = in;
      bmeps_convert(bj);
      fclose(fpo); fpo = NULL;
    } else {
      bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 38, 39, on);
      bj->exval = 1;
    }
    fclose(fpi); fpi = NULL;
  } else {
    bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 36, 37, in);
    bj->exval = 1;
  }
  
}



/**	Run for two file names, wildcards are not yet expaneded/resolved.
	@param	bj	Bmeps job.
*/
static
void
run_for_two_filenames DK_P1(BJ *,bj)
{
  dk_fne_t *fnei, *fneo;
  char *iname = NULL, *oname = NULL;
  
  if(dksf_must_expand_filename(bj->i1)) {
    fnei = dkfne_open(bj->i1, 1, 0);
    if(fnei) {
      iname = dkfne_get_one(fnei);
      if(iname) {
        if(dksf_must_expand_filename(bj->o1)) {
	  fneo = dkfne_open(bj->o1, 1, 0);
	  if(fneo) {
	    oname = dkfne_get_one(fneo);
	    if(oname) {
	      run_for_two_real_filenames(bj, iname, oname);
	    } else {
	      bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 43, 44, bj->o1);
	      bj->exval = 1;
	    }
	    dkfne_close(fneo); fneo = NULL;
	  } else {
	    bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 40);
	    bj->exval = 1;
	  }
	} else {
	  run_for_two_real_filenames(bj, iname, bj->o1);
	}
      } else {
	bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 41, 42, bj->i1);
	bj->exval = 1;
      }
      dkfne_close(fnei);
    } else {
      bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 40);
      bj->exval = 1;
    }
  } else {
    if(dksf_must_expand_filename(bj->o1)) {
      fneo = dkfne_open(bj->o1, 1, 0);
      if(fneo) {
        oname = dkfne_get_one(fneo);
	if(oname) {
	  run_for_two_real_filenames(bj, bj->i1, oname);
	} else {
	  bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 43, 44, bj->o1);
	  bj->exval = 1;
	}
        dkfne_close(fneo); fneo = NULL;
      } else {
	bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 40);
	bj->exval = 1;
      }
    } else {
      run_for_two_real_filenames(bj, bj->i1, bj->o1);
    }
  }
  
}



/**	Run for on file name (input file) expaned/resolved.
	@param	bj	Bmeps job.
	@param	n	Input file name.
*/
static
void
run_for_one_real_filename DK_P2(BJ *,bj, char *,n)
{
  FILE *fp;
  
  if(bj->it == DKBIF_TYPE_UNKNOWN) bj->it = dkbif_get_type(n);
  fp = dkapp_fopen(bj->a, n, "rb");
  if(fp) {
    bj->inf = fp;
    bj->infname = n;
    bmeps_convert(bj);
    fclose(fp); fp = NULL;
  } else {
    bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 36, 37, n);
    bj->exval = 1;
  }
  
}



/**	Run for one file name (input file). Wildcards are not
	yet expanded/resolved.
	@param	bj	Bmeps job.
*/
static
void
run_for_one_filename DK_P1(BJ *,bj)
{
  dk_fne_t *fne = NULL;
  char *in;
  
  if(dksf_must_expand_filename(bj->i1)) {
    fne = dkfne_open(bj->i1, 1, 0);
    if(fne) {
      in = dkfne_get_one(fne);
      if(in) {
        run_for_one_real_filename(bj, in);
      } else {
	bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 41, 42, bj->i1);
	bj->exval = 1;
      }
      dkfne_close(fne); fne = NULL;
    } else {
      bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 40);
      bj->exval = 1;
    }
  } else {
    run_for_one_real_filename(bj, bj->i1);
  }
  
}



/**	Run for a directory (file name in bj->i1).
	This function is invoked if only file name was provided
	and this file name points to a directory.
	@param	bj	Bmeps job.
*/
static
void
run_for_directory DK_P1(BJ *,bj)
{
  dk_storage_t *s; dk_storage_iterator_t *si;
  char *namei = NULL, *nameo = NULL, *n, *c, *fn, *ots; int t, onok, dnt;
  dk_dir_t *d; long mpl;
  unsigned char mr;
  
  s = dksto_open(0);
  if(s) {
    si = dksto_it_open(s);
    if(si) {
      mpl = dksf_get_maxpathlen();
      namei = dk_new(char,mpl); nameo = dk_new(char,mpl);
      if((namei) && (nameo)) {
        d = dkdir_open(bj->i1);
	if(d) {
	  while((dnt = dkdir_next(d))) {
	    if(dnt == 1) {
	      n = dkdir_get_shortname(d);
	      if(n) {
	        t = dkbif_get_type(n);
	        if(t != DKBIF_TYPE_UNKNOWN) {
		  if(dkbif_can_handle(t)) {
		    c = dkstr_dup(n);
		    if(c) {
		      if(!dksto_add(s, (void *)c)) {
		        bmeps_tool_error_memory(bj); bj->exval = 1;
		        dk_delete(c); c = NULL;
		      }
		    } else {
		      bmeps_tool_error_memory(bj); bj->exval = 1;
		    }
		  }
	        }
	      } else {
	        bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 56);
	        bj->exval = 1;
	      }
	    }
	  }
          dkdir_close(d); d = NULL;
	} else {
	  bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 54, 55, bj->i1);
	  bj->exval = 1;
	}
        dksto_it_reset(si);
        while((fn = (char *)dksto_it_next(si)) != NULL) {
          /* TODO: Complete */
          
	  if((strlen(bj->i1) + strlen(fn) + 1) < (size_t)mpl) {
	    sprintf(namei, "%s%s%s", bj->i1, sep, fn);
	    strcpy(nameo, namei);
	    onok = 0; ots = bmeps_tool_suffix_for_output_type((bj->bo)->ot);
	    c = dksf_get_file_type_dot(nameo);
	    if(c) {
	      *c = '\0';
	      if((strlen(nameo) + strlen(ots)) < (size_t)mpl) {
	        strcpy(c, ots); onok = 1;
	      }
	    } else {
	      if((strlen(nameo) + strlen(ots)) < (size_t)mpl) {
	        strcat(nameo, ots); onok = 1;
	      }
	    }
	    if(onok) {
	      
	      mr = 0x01;
	      if(bj->mm) {
		if(!dksf_must_rebuild(nameo, namei)) {
		  mr = 0x00;
		}
	      }
	      if(mr) {
		if(bj->a) {
		  bmeps_tool_msg_3(bj, DK_LOG_LEVEL_PROGRESS, 97, 98, namei);
		}
	        run_for_two_real_filenames(bj, namei, nameo);
	      }
	    } else {
	      bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 47, 48, fn);
	      bj->exval = 1;
	    }
	  } else {
	    bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 45, 46, fn);
	    bj->exval = 1;
	  }
        }
      } else {
	bmeps_tool_error_memory(bj); bj->exval = 1;
      }
      if(namei) { dk_delete(namei); namei = NULL; }
      if(nameo) { dk_delete(nameo); nameo = NULL; }
      /* release file names */
      dksto_it_reset(si);
      while((fn = (char *)dksto_it_next(si)) != NULL) {
        dk_delete(fn);
      }
      dksto_it_close(si); si = NULL;
    } else {
      bmeps_tool_error_memory(bj); bj->exval = 1;
    }
    dksto_close(s); s = NULL;
  } else {
    bmeps_tool_error_memory(bj); bj->exval = 1;
  }
  
}



/**	After creating temporary file names,  run now.
	@param	bj	Bmeps job.
*/
static
void
run_for_filenames DK_P1(BJ *,bj)
{
  FILE *fp = NULL; int res;
  char *auto_file_name = NULL, *ptr = NULL;
  size_t lgt;
  int old_stdin_binary = 0, old_stdout_binary = 0;
  
  if(bj->o1) {		
    run_for_two_filenames(bj);
  } else {
    /* dksf_set_file_binary(stdout); */
    old_stdout_binary = dksf_fdesk_binary(1, 1);
    bj->outf = stdout;
    if(bj->i1) {
      if(dksf_must_expand_filename(bj->i1)) {
        run_for_one_filename(bj);
      } else {
        if(dksf_is_directory(bj->i1)) {
	  run_for_directory(bj);
	} else {
	  if(bj->af) {
	    lgt = 5 + strlen(bj->i1);
	    auto_file_name = dk_new(char,lgt);
	    if(auto_file_name) {
	      strcpy(auto_file_name, bj->i1);
	      ptr = dksf_get_file_type_dot(auto_file_name);
	      if(ptr) { *ptr = '\0'; }
	      if(bj->bo) {
	        switch((bj->bo)->ot) {
	          case BMEPS_OUTPUT_TYPE_PDF: {
	            strcat(auto_file_name, suffixes[0]);
	          } break;
	          case BMEPS_OUTPUT_TYPE_EPS: {
	            strcat(auto_file_name, suffixes[1]);
	          } break;
	          default: {
	            strcat(auto_file_name, suffixes[2]);
	          } break;
		}
		bj->o1 = auto_file_name;
		bmeps_tool_msg_3(bj, DK_LOG_LEVEL_DEBUG, 79, 80, auto_file_name);
		run_for_two_filenames(bj);
	      }
	      bj->o1 = NULL;
	      dk_delete(auto_file_name);
	      auto_file_name = NULL;
	    } else {
	      bmeps_tool_error_memory(bj); bj->exval = 1;
	    }
	  } else {
	    run_for_one_real_filename(bj, bj->i1);
	  }
	}
      }
    } else {		
      if(bj->it != DKBIF_TYPE_UNKNOWN) {
        /* dksf_set_file_binary(stdin); */
	old_stdin_binary = dksf_fdesk_binary(0, 1);
	fp = dkapp_fopen(bj->a, bj->tmp1, "wb");
	if(fp) {
	  res = transfer_file_contents(bj, stdin, fp);
	  fclose(fp); fp = NULL;
	  if(res) {
	    bj->inf = dkapp_fopen(bj->a, bj->tmp1, "rb");
	    if(bj->inf) {
	      bj->outf = stdout;
	      bj->infname = NULL;
	      bmeps_convert(bj);
	      fclose(bj->inf); bj->inf = NULL;
	    } else {
	      bmeps_tool_msg_3(bj, DK_LOG_LEVEL_ERROR, 34, 35, bj->tmp1);
	      bj->exval = 1;
	    }
	  }
	  /* remove temporary file */
	  dksf_remove_file(bj->tmp1);
	} else {
	  (void)transfer_file_contents(bj, stdin, NULL);
	}
	(void)dksf_fdesk_binary(0, old_stdin_binary);
      } else {		
	bmeps_tool_msg_1(bj, DK_LOG_LEVEL_ERROR, 33);
	bj->exval = 1;
      }
    }
    (void)dksf_fdesk_binary(1, old_stdout_binary);
  }
  if(bj->alpha_channel_transferred) {
    if(!(bj->suppress_alpha_info)) {
      bmeps_tool_msg_1(bj, DK_LOG_LEVEL_INFO, 95);
    }
  }
  
}



/**	Go and do the conversion.
	This function creates file names for temporary files
	and invokes run_for_filenames().
	@param	bj	Bmeps job.
*/
static
void
do_real_work DK_P1(BJ *,bj)
{
  char *bptr, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
  size_t blen;
  
  p1 = p2 = p3 = p4 = p5 = p6 = p7 = NULL;
  blen = (size_t)dksf_get_maxpathlen();
  bptr = dk_new(char,blen);
  if(bptr) {
    p1 = p2 = p3 = NULL;
    if(dkapp_tmpnam(bj->a, bptr, blen)) {
      p1 = dkstr_dup(bptr);
    }
    if(dkapp_tmpnam(bj->a, bptr, blen)) {
      p2 = dkstr_dup(bptr);
    }
    if(dkapp_tmpnam(bj->a, bptr, blen)) {
      p3 = dkstr_dup(bptr);
    }
    if(dkapp_tmpnam(bj->a, bptr, blen)) {
      p4 = dkstr_dup(bptr);
    }
    if(dkapp_tmpnam(bj->a, bptr, blen)) {
      p5 = dkstr_dup(bptr);
    }
    if(dkapp_tmpnam(bj->a, bptr, blen)) {
      p6 = dkstr_dup(bptr);
    }
    if(dkapp_tmpnam(bj->a, bptr, blen)) {
      p7 = dkstr_dup(bptr);
    }
    if((p1) && (p2) && (p3) && (p4) && (p5) && (p6) && (p7)) {
      bj->tmp1 = p1; bj->tmp2 = p2; bj->tmp3 = p3; bj->tmp4 = p4;
      bj->tmp5 = p5; bj->tmp6 = p6; bj->tmp7 = p7;
      run_for_filenames(bj);
    } else {
      bmeps_tool_error_memory(bj);
      bj->exval = 1;
    }
    if(p1) { dk_delete(p1); }
    if(p2) { dk_delete(p2); }
    if(p3) { dk_delete(p3); }
    if(p4) { dk_delete(p4); }
    if(p5) { dk_delete(p5); }
    if(p6) { dk_delete(p6); }
    if(p7) { dk_delete(p7); }
    dk_delete(bptr); bptr = NULL;
  } else {
    bmeps_tool_error_memory(bj);
    bj->exval = 1;
  }
  
}



/**	After loading localized strings, go to work now.
	This function reads defaults from the preferences system
	and invokes apply_arguments() to process the command
	line arguments and do_real_work().
	@param	bj	Bmeps job.
*/
static
void
run_with_strings DK_P1(BJ *,bj)
{
  char namebuffer[NAME_BUFFER_SIZE], *ptr, *l;
  
  if(dkapp_get_pref(bj->a, pk_alph, namebuffer, sizeof(namebuffer), 0)) {
    ptr = dkstr_start(namebuffer, NULL);
    if(ptr) {
      dkstr_chomp(ptr, NULL);
      if(dkstr_is_bool(namebuffer)) {
        if(dkstr_is_on(namebuffer)) {
	  bj->suppress_alpha_info = 0x01;
	}
      }
    }
  }
  if(dkapp_get_pref(bj->a, pk_make, namebuffer, sizeof(namebuffer), 0)) {
    if(dkstr_is_bool(namebuffer)) {
      if(dkstr_is_on(namebuffer)) {
        bj->mm = 0x01;
      } else {
        bj->mm = 0x00;
      }
    }
  }
  l = NULL;
  if(bmeps_bo_get_pref_lang(bj, namebuffer, sizeof(namebuffer))) {
    l = namebuffer;
  }
  apply_arguments(bj, l);
  if(!((bj->cmd) & BMEPS_CMD_ERROR)) {
    if((bj->cmd) & BMEPS_CMD_APP) {
      bj->exval = 0;	/* we will succeed */
      run_for_app_options(bj);
    } else {
      do_real_work(bj);
    }
  }
  
}



/**	After creating the application structure, go to real work now.
	This function is invoked by the main() function after
	the application structure was created.
	The function loads the localized strings and invokes
	run_with_strings().
	@param	bj	Bmeps job.
*/
static
void
run DK_P1(BJ *,bj)
{
  size_t sz, i;
  dk_string_finder_t *fp, *fpptr; PCHAR *pp, *ppptr;
  char buffer[32], *x;
  int ok = 0;
  
  sz = bmeps_get_num();
  
  fp = dk_new(dk_string_finder_t,(sz+1));
  if(fp) {				
    pp = dk_new(PCHAR,sz);
    if(pp) {				
      fpptr = fp; ppptr = pp;
      ok = 1;
      for(i = 0; i < sz; i++) {
        sprintf(buffer, "/m/%03lu", (unsigned long)i);
	fpptr->key = dkstr_dup(buffer);
	if(!(fpptr->key)) {		
	  ok = 0;
	}
        fpptr->value_pointer = ppptr;
	fpptr->default_value = bmeps_str_get(i);
        fpptr++; ppptr++;
      }
      fp[sz].key = NULL;
      fp[sz].value_pointer = NULL;
      fp[sz].default_value = NULL;
      if(ok) {				
        dkapp_find_multi(bj->a, fp, "bmeps");
	bj->msg = pp;
	run_with_strings(bj);
	bj->msg = NULL;
      } else {
	bmeps_tool_error_memory(bj);
	bj->exval = 1;
      }
      fpptr = fp;
      for(i = 0; i < sz; i++) {
        if(fpptr->key) {		
	  x = fpptr->key; dk_delete(x);
	}
	fpptr->key = NULL;
	
#line 1597 "b2main.ctr"
	
#line 1598 "b2main.ctr"
	
#line 1599 "b2main.ctr"
	
#line 1600 "b2main.ctr"
	
#line 1601 "b2main.ctr"
	
#line 1602 "b2main.ctr"
	
#line 1603 "b2main.ctr"
	
#line 1604 "b2main.ctr"
	
#line 1605 "b2main.ctr"
	
#line 1606 "b2main.ctr"
	
#line 1607 "b2main.ctr"
	fpptr->value_pointer = NULL;
	
#line 1609 "b2main.ctr"
	
#line 1610 "b2main.ctr"
	
#line 1611 "b2main.ctr"
	
#line 1612 "b2main.ctr"
	
#line 1613 "b2main.ctr"
	
#line 1614 "b2main.ctr"
	
#line 1615 "b2main.ctr"
	
#line 1616 "b2main.ctr"
	
#line 1617 "b2main.ctr"
	fpptr->default_value = NULL;
        fpptr++;
      }
      dk_delete(pp);
    } else {				
      bmeps_tool_error_memory(bj);
      bj->exval = 1;
    }
    dk_delete(fp);
  } else {				
    bmeps_tool_error_memory(bj);
    bj->exval = 1;
  }
  
}



/**	The main program. This function creates an
	application structure and invokes the run() function.
	@param	argc	Number of command line arguments.
	@param	argv	Command line arguments array.
	@return	0 on success, any other value on error.
*/
#if DK_HAVE_PROTOTYPES
int main(int argc, char *argv[])
#else
int main(argc, argv) int argc; char *argv[];
#endif
{
  int rs = 0, rf = 0; 
  dk_app_t *a = NULL;
  
#line 1649 "b2main.ctr"

  
  bj.exval = 0;
  silence_check(argc, argv, &rs, &rf);
  a = dkapp_open_ext1(argc, argv, GROUPNAME, DK_SYSCONFDIR, rs, rf);
  if(a) {
    bmeps_bj_init(&bj);
    bj.bo = &bo;
    bj.a  = a;
    run(&bj);
    dkapp_close(a); a = NULL;
  } else {
    if(!rs) {
      fprintf(stderr, "Not enough memory (RAM/swap)!\n"); fflush(stderr);
    }
    bj.exval = 1;
  }
  
  
#line 1667 "b2main.ctr"

  exit(bj.exval); return bj.exval;
}



