/*
Copyright (c) 2002-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.
*/



/**	@file	writeau.c	The writeau module of the genau program.
*/



#include <dk.h>
#include <dkmem.h>
#include <dksf.h>
#include <dkstream.h>
#include <dkstr.h>
#include <dksto.h>
#include <dkapp.h>
#include <dklogc.h>

#if DK_HAVE_STRING_H
#include <string.h>
#endif
#if DK_HAVE_STRINGS_H
#include <strings.h>
#endif

#include <genau.h>
#include <reducau.h>

/**	Inside the writeau.c module.
*/
#define WRITEAU_C 1
#include <writeau.h>


#line 69 "writeau.ctr"


typedef au_state_transition_t TR;


static char *test_file_part1a[] = {
"",
"#include <stdio.h>",
NULL
};

static char *test_file_part1d[] = {
"#include <dk.h>",
"#include <dktypes.h>",
"#if DK_HAVE_STDLIB_H",
"#include <stdlib.h>",
"#endif",
"#if DK_HAVE_STRING_H",
"#include <string.h>",
"#endif",
"",
NULL
};

static char *test_file_part1b[] = {
"#include <stdlib.h>",
"#include <string.h>",
"",
NULL 
};

static char *dox_trans[] = {
"/**\tState transition.",
"\t@param\ts\tPointer to state variable (in: current, out: new).",
"\t@param\ti\tCurrent state machine input.",
"\t@return\tState machine output.",
"*/",
NULL
};

static char *dox_res[] = {
"/**\tState machine reset.",
"\t@param\ts\tPointer to state variable.",
"*/",
NULL
};

static char *test_file_part1c[] = {
"",
"typedef struct {",
"  int i;",
"  char *name;",
"} int_info;",
"",
"typedef struct {",
"  int_info *ptr;",
"  size_t    sz;",
"} int_info_summary;",
"",
NULL
};

static char *test_file_part2a[] = {
"",
"int_info_summary states_info_summary =",
"{ states_info, sizeof(states_info)/sizeof(int_info) };",
"",
"int_info_summary inputs_info_summary =",
"{ inputs_info, sizeof(inputs_info)/sizeof(int_info) };",
"",
"int_info_summary outputs_info_summary =",
"{ outputs_info, sizeof(outputs_info)/sizeof(int_info) };",
"",
NULL
};

static char *test_file_part2b[] = {
"static char *find_string_for(s,n) int_info_summary *s; int n;",
NULL
};

static char *test_file_part2c[] = {
"static char *find_string_for(int_info_summary *s, int n)",
NULL
};

static char *test_file_part2d[] = {
"static char *find_string_for DK_P2(int_info_summary *, s, int, n)",
NULL
};

static char *test_file_part2e[] = {
"{",
"  char *back = NULL;",
"  int i;",
"  i = 0;",
"  while((!back) && (i < s->sz)) {",
"    if((((s->ptr)[i]).i) == n) {",
"      back = ((s->ptr)[i]).name;",
"    } else {",
"      i++;",
"    }",
"  }",
"  return back;",
"}",
"",
"static char notfound[] = { \"<UNKNOWN>\" };",
"",
NULL
};

static char *test_file_part2f[] = {
"int main(argc,argv) int argc; char *argv[];",
NULL
};

static char *test_file_part2g[] = {
"int main(int argc, char *argv[])",
NULL,
};

static char *test_file_part2h[] = {
"#if DK_HAVE_PROTOTYPES",
"int main(int argc, char *argv[])",
"#else",
"int main(argc, argv) int argc; char *argv[];",
"#endif",
NULL
};

static char *test_file_part2i[] = {
"{",
"  int l, maxl, i, j, old_state, input, new_state, output;",
"  int state_machine;",
"  char *name_old_state; char *name_new_state;",
"  char *name_input; char *name_output;",
"  maxl = 0;",
"  for(i = 0; i < states_info_summary.sz; i++) {",
"    l = strlen(((states_info_summary.ptr)[i]).name);",
"    if(l > maxl) maxl = l;",
"  }",
"  for(i = 0; i < inputs_info_summary.sz; i++) {",
"    l = strlen(((inputs_info_summary.ptr)[i]).name);",
"    if(l > maxl) maxl = l;",
"  }",
"  for(i = 0; i < outputs_info_summary.sz; i++) {",
"    l = strlen(((outputs_info_summary.ptr)[i]).name);",
"    if(l > maxl) maxl = l;",
"  }",
"  l = strlen(notfound);",
"  if(l > maxl) maxl = l;",
"  for(i = 0; i < states_info_summary.sz; i++) {",
"    old_state = ((states_info_summary.ptr)[i]).i;",
"    name_old_state = ((states_info_summary.ptr)[i]).name;",
"    for(j = 0; j < inputs_info_summary.sz; j++) {",
"      input = ((inputs_info_summary.ptr)[j]).i;",
"      name_input = ((inputs_info_summary.ptr)[j]).name;",
"      state_machine = old_state;",
NULL
};

static char *test_file_part2j[] = {
 /* "      output = au_action(&state_machine, input);", */
"      new_state = state_machine;",
"      name_new_state = find_string_for(&states_info_summary, new_state);",
"      if(!name_new_state) name_new_state = notfound;",
"      name_output = find_string_for(&outputs_info_summary, output);",
"      if(!name_output) name_output = notfound;",
"      printf(\"%s\", name_old_state);",
"      l = strlen(name_old_state);",
"      while(l++ < maxl) { printf(\" \"); }",
"      printf(\" \");",
"      printf(\"%s\", name_input);",
"      l = strlen(name_input);",
"      while(l++ < maxl) { printf(\" \"); }",
"      printf(\" \");",
"      printf(\"%s\", name_new_state);",
"      l = strlen(name_new_state);",
"      while(l++ < maxl) { printf(\" \"); }",
"      printf(\" \");",
"      printf(\"%s\", name_output);",
"      l = strlen(name_output);",
"      while(l++ < maxl) { printf(\" \"); }",
"      printf(\"\\n\");",
"    }",
"  }",
"  exit(0); return 0;",
"}",
"",
NULL
};


static char *opt_c_file[] = {
  "c", "file", NULL
};

static char *opt_h_file[] = {
  "h", "file", NULL
};

static char *opt_prototypes[] = {
  "prototypes", NULL
};

static char *opt_transition_function[] = {
  "transition", "function", NULL
};

static char *opt_reset_function[] = {
  "reset", "function", NULL
};


static char *opt_reduced_file[] = {
  "reduced", "file", NULL
};

static char *opt_reduce[] = {
  "reduce", NULL
};

static char *opt_include_protect[] = {
  "include", "protect", NULL
};

static char *opt_c_define[] = {
  "c", "define", NULL
};

static char *opt_test_file[] = {
  "test", "file", NULL
};

static char *opt_squeezed[] = {
  "squeezed", NULL
};

static char *opt_doxygen[] = {
  "doxygen", "comments", NULL
};

static char **options[]  = {
  opt_c_file,
  opt_h_file,
  opt_prototypes,
  opt_transition_function,
  opt_reset_function,
  opt_reduced_file,
  opt_reduce,
  opt_include_protect,
  opt_c_define,
  opt_test_file,
  opt_squeezed,
  opt_doxygen,
  NULL
};

static char key_stdout[] = { "-" };

static char default_fct_name[] = { "genau_t" };
static char default_res_name[] = { "genau_r" };
static char default_i_prot[]   = { "INC_GENAU" };
static char default_c_define[] = { "GENAU_C" };
static char default_h_file_name[] = { "automata.h" };

static char *start_text[] = {
"/*",
"  This file was generated by genau.",
"  You should not apply changes to this file because they",
"  may be overwritten by the next run of genau.",
"*/",
NULL
};

static char *cpp_begin_text[] = {
  "#ifdef __cplusplus",
  "extern \"C\" {",
  "#endif",
  NULL
};

static char *cpp_end_text[] = {
  "#ifdef __cplusplus",
  "}",
  "#endif",
  NULL
};

static char nl[] = { "\n" };
static char sp[] = { " " };
static char str_dk[] =    { "dk" };
static char str_options[] = { "[options]" };
static char str_states[]  = { "[states]" };
static char str_inputs[]  = { "[inputs]" };
static char str_outputs[]  = { "[outputs]" };
static char str_rules[]  = { "[rules]" };
static char str_tab[] = { "\t" };
static char str_dk_have_prototypes[] = { "DK_HAVE_PROTOTYPES" };
static char str_dk_pr[] = { "DK_PR" };
static char str_space[] = { " " };
static char str_exclam[] = { "!" };
static char str_nix[]   = { "/* nix */" };
static char str_cross[] = { "#" };
static char x_if[] =      { "#if" };
static char x_ifndef[]  = { "#ifndef " };
static char x_protection[] = {
  "/**\tInclude only once.\n*/\n"
};
static char x_else[]    = { "#else" };
static char x_endif[]   = { "#endif" };
static char x_define[]  = { "#define " };
static char x_include[] = { "#include " };

static char decl_states_info[] = { "int_info states_info[] = {\n  " };
static char decl_inputs_info[] = { "int_info inputs_info[] = {\n  " };
static char decl_outputs_info[] = { "int_info outputs_info[] = {\n  " };

static char c_states[]  = { "/* states    */" };
static char c_inputs[]  = { "/* inputs    */" };
static char c_outputs[] = { "/* outputs   */" };
static char c_fct[]     = { "/* functions */" };
static char str_type[]  = { "int" };
static char str_void[]  = { "void" };
static char str_bropen[]    = { "(" };
static char str_brclose[]   = { ")" };
static char str_all[]       = { "*" };
static char str_semicol[]   = { ";" };
static char str_s[]         = { "s" };
static char str_i[]         = { "i" };
static char str_comma[]     = { "," };
static char str_extern[]    = { "extern" };
static char str_EXTERN[]    = { "EXTERN" };
static char str_colon[]     = { ":" };
static char str_equal[]     = { "=" };
static char str_switch[]    = { "switch" };
static char str_case[]      = { "case" };
static char str_break[]     = { "break" };
static char str_default[]   = { "default" };
static char str_curlopen[]  = { "{" };
static char str_curlclose[] = { "}" };
static char str_if[]        = { "if" };
static char str_decl[]      = { "int n,o;"};
static char str_n[]         = { "n" };
static char str_o[]         = { "o" };
static char str_return[]    = { "return" };
static char str_0[]         = { "0" };
static char str_null[]      = { "NULL" };
static char str_quote[]     = { "\"" };

static char str_dox1[] = { "/**\t\t\t\t\t\t" };
static char str_dox2[] = { "*/" };
static char str_dox3[] = { " State: " };
static char str_dox4[] = { " Input: " };
static char str_dox5[] = { " Output: " };
static char str_dox6[] = { "." };



/**	Write array of strings to output stream.
	@param	s	Output stream.
	@param	a	String array.
*/
static
void
put_string_array DK_P2(dk_stream_t *,s, char **,a) {
  char **ptr;
  ptr = a;
  while(*ptr) {
    dkstream_puts(s, *(ptr++));
    dkstream_puts(s, nl);
  }
}



/**	Write automata to output file.
	@param	a	Automata.
	@param	s	Output stream.
	@param	what	Output stream type (0=recuded automata,
			1=header file, 2=source file, 3=test source).
*/
void
write_automata DK_P3(automata_t *, a, dk_stream_t *, s, int, what)
{
char *line, buffer[32], *ptrs[16];
char *fct_name, *res_name, *i_prot, *c_def, **ptr;
char *h_file_name;
int  maxl, l;
au_state_t *st, *st2;
au_input_t *in;
au_output_t *out, *out2;
au_state_transition_t *tr, *tr2, *tr3;
au_option_line_t *ol;
int is_first_state, is_first_transition, is_first_default_transition;
size_t maxi, maxo, maxs, maxx, xl;
char *errmsgs[16], **allstrings;

line = dk_new(char,LINELENGTH);
if(line) {
if(a && s) {
  fct_name = ((a->name_trans) ? (a->name_trans) : default_fct_name);
  res_name = ((a->name_res)   ? (a->name_res)   : default_res_name);
  i_prot   = ((a->i_prot)     ? (a->i_prot)     : default_i_prot);
  c_def    = ((a->c_def)      ? (a->c_def)      : default_c_define);
  h_file_name = ((a->h_file_name) ? (a->h_file_name) : default_h_file_name);
  maxl = 0;
  switch(what) {
    case 0: {				/* reduced file */
      maxi = maxo = maxs = 0;
      dksto_it_reset(a->stit);
      while((st = (au_state_t *)dksto_it_next(a->stit)) != NULL) {
	if(st->name) { xl = strlen(st->name); if(xl > maxs) { maxs = xl; } }
      }
      dksto_it_reset(a->init);
      while((in = (au_input_t *)dksto_it_next(a->init)) != NULL) {
	if(in->name) { xl = strlen(in->name); if(xl > maxi) { maxi = xl; } }
      }
      dksto_it_reset(a->outit);
      while((out = (au_output_t *)dksto_it_next(a->outit)) != NULL) {
	if(out->name) { xl = strlen(out->name); if(xl > maxo) { maxo = xl; } }
      }
      maxx = maxs;
      if(maxo > maxx) maxx = maxo;
      if(maxi > maxx) maxx = maxi;
      dksto_it_reset(a->optit);
      is_first_state = 1;
      while((ol = (au_option_line_t *)dksto_it_next(a->optit)) != NULL) {
        if(ol->line) {
	  if(strlen(ol->line) < LINELENGTH) {
	    strcpy(line, ol->line); 
	    ptrs[0] = dkstr_chr(line, '=');
	    if(ptrs[0]) {
	      *(ptrs[0]) = '\0';
	    }
	    for(l = 0; l < 16; l++) { ptrs[l] = NULL; }
	    ptrs[0] = dkstr_start(line, NULL);
	    for(l = 1; l < 16; l++) {
	      if(ptrs[l-1]) {
		ptrs[l] = dkstr_next(ptrs[l-1], NULL);
	      }
	    }
	    
#line 512 "writeau.ctr"
	    
	    
#line 514 "writeau.ctr"
	    switch(dkstr_find_multi_part_cmd(ptrs, options, 1)) {
	      case 5:
	      case 6: break;
	      default: {
		if(is_first_state) {
		  dkstream_puts(s, str_options);
		  dkstream_puts(s, nl);
		  is_first_state = 0;
		}
		dkstream_puts(s, str_tab);
		dkstream_puts(s, ol->line);
		dkstream_puts(s, nl);
	      }
	    }
	  }
	}
      }
      is_first_state = 1;
      dksto_it_reset(a->stit);
      while((st = (au_state_t *)dksto_it_next(a->stit)) != NULL) {
	if(st->compat) {
	  if(is_first_state) {
	    is_first_state = 0;
	    dkstream_puts(s, str_cross);
	    dkstream_puts(s, nl);
	  }
	  dkstream_puts(s, str_cross);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, st->name);
	  xl = strlen(st->name);
	  while(xl++ < maxs) { dkstream_puts(s, sp); }
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_equal);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, ((au_state_t *)(st->compat))->name);
	  dkstream_puts(s, nl);
	}
      }
      if(!is_first_state) {
	dkstream_puts(s, str_cross);
	dkstream_puts(s, nl);
      }
      if(a->initial_state) {
        dksto_it_reset(a->stit);
        st = a->initial_state;
        if(st) {
	  if(st->compat) { st = st->compat; }
        }
        st2 = st;
        dkstream_puts(s, str_states);
        dkstream_puts(s, nl);
        dkstream_puts(s, str_tab);
	dkstream_puts(s, st->name);
	if(st->number_defined) {
	  xl = strlen(st->name);
	  while(xl++ < maxx) { dkstream_puts(s, sp); }
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  sprintf(line, "%d", st->number);
	  dkstream_puts(s, line);
	}
	dkstream_puts(s, nl);
	while((st = (au_state_t *)dksto_it_next(a->stit)) != NULL) {
	  if(!(st->compat)) {
	    if(st != st2) {
	      dkstream_puts(s, str_tab);
	      dkstream_puts(s, st->name);
	      if(st->number_defined) {
		xl = strlen(st->name);
		while(xl++ < maxx) { dkstream_puts(s, sp); }
		dkstream_puts(s, sp);
		dkstream_puts(s, sp);
		dkstream_puts(s, sp);
		sprintf(line, "%d", st->number);
		dkstream_puts(s, line);
	      }
	      dkstream_puts(s, nl);
	    }
	  }
	}
      }
      dksto_it_reset(a->init);
      is_first_state = 1;
      while((in = (au_input_t *)dksto_it_next(a->init)) != NULL) {
	if(is_first_state) {
	  is_first_state = 0;
	  dkstream_puts(s, str_inputs);
	  dkstream_puts(s, nl);
	}
	dkstream_puts(s, str_tab);
	dkstream_puts(s, in->name);
	if(in->number_defined) {
	  sprintf(line, "%d", in->number);
	  xl = strlen(in->name);
	  while(xl++ < maxx) { dkstream_puts(s, sp); }
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, line);
	}
	dkstream_puts(s, nl);
      }
      
      if(a->def_output) {
        out = out2 = a->def_output;
	dkstream_puts(s, str_outputs);
	dkstream_puts(s, nl);
	dkstream_puts(s, str_tab);
	dkstream_puts(s, out->name);
	
	if(out->number_defined) {
	  sprintf(line, "%d", out->number);
	  xl = strlen(out->name);
	  while(xl++ < maxx) { dkstream_puts(s, sp); }
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, line);
	}
	dkstream_puts(s, nl);
	
	dksto_it_reset(a->outit);
	while((out = (au_output_t *)dksto_it_next(a->outit)) != NULL) {
	  
	  if(out != out2) {
	    dkstream_puts(s, str_tab);
	    dkstream_puts(s, out->name);
	    if(out->number_defined) {
	      sprintf(line, "%d", out->number);
	      xl = strlen(out->name);
	      while(xl++ < maxx) { dkstream_puts(s, sp); }
	      dkstream_puts(s, sp);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, line);
	    }
	    dkstream_puts(s, nl);
	  }
	}
      }
      
      dksto_it_reset(a->alltrit);
      is_first_state = 1;
      while((tr = (TR *)dksto_it_next(a->alltrit)) != NULL) {
	st  = tr->current_data;
	st2 = tr->next_data;
	if(st2) { if(st2->compat) { st2 = st2->compat; } }
	is_first_transition = 1;
	if(st) {
	  if(st->compat) {
	    is_first_transition = 0;
	  }
	}
	if(is_first_transition) {
	  if(is_first_state) {
	    is_first_state = 0;
	    dkstream_puts(s, str_rules);
	    dkstream_puts(s, nl);
	  }
	  dkstream_puts(s, str_tab);
	  dkstream_puts(s, tr->current_name);
	  xl = strlen(tr->current_name);
	  while(xl++ < maxx) { dkstream_puts(s, sp); }
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, tr->input_name);
	  xl = strlen(tr->input_name);
	  while(xl++ < maxi) { dkstream_puts(s, sp); }
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  if(st2) {
	    dkstream_puts(s, st2->name);
	    xl = strlen(st2->name);
	  } else {
	    dkstream_puts(s, tr->next_name);
	    xl = strlen(tr->next_name);
	  }
	  while(xl++ < maxs) { dkstream_puts(s, sp); }
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, tr->output_name);
	  dkstream_puts(s, nl);
	}
      }
    } break;
    case 1: {				/* header file */
      ptr = start_text;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      dkstream_puts(s, x_ifndef); dkstream_puts(s, i_prot); dkstream_puts(s, nl);
      dkstream_puts(s, nl);
      if(a->doxy_output) { dkstream_puts(s, x_protection); }
      dkstream_puts(s, x_define); dkstream_puts(s, i_prot); dkstream_puts(s, nl);
      dksto_it_reset(a->stit);
      while((st = (au_state_t *)dksto_it_next(a->stit)) != NULL) {
	if(st->name) {
	  l = strlen(st->name);
	  if(l > maxl) maxl = l;
	}
      }
      dksto_it_reset(a->init);
      while((in = (au_input_t *)dksto_it_next(a->init)) != NULL) {
	if(in->name) {
	  l = strlen(in->name);
	  if(l > maxl) maxl = l;
	}
      }
      dksto_it_reset(a->outit);
      while((out = (au_output_t *)dksto_it_next(a->outit)) != NULL) {
	if(out->name) {
	  l = strlen(out->name);
	  if(l > maxl) maxl = l;
	}
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, c_states); dkstream_puts(s, nl);
      dksto_it_reset(a->stit);
      while((st = (au_state_t *)dksto_it_next(a->stit)) != NULL) {
	if(st->name) {
	  if(a->doxy_output) {
	    dkstream_puts(s, nl);
	    dkstream_puts(s, str_dox1);
	    dkstream_puts(s, str_dox3);
	    dkstream_puts(s, st->name);
	    dkstream_puts(s, str_dox6);
	    dkstream_puts(s, nl);
	    dkstream_puts(s, str_dox2);
	    dkstream_puts(s, nl);
	  }
	  l = strlen(st->name);
	  dkstream_puts(s, x_define);
	  while(l < maxl) {
	    l++; dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, st->name);
	  dkstream_puts(s, sp);
	  sprintf(buffer, "%d", st->number);
	  dkstream_puts(s, buffer);
	  dkstream_puts(s, nl);
	}
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, c_inputs); dkstream_puts(s, nl);
      dksto_it_reset(a->init);
      while((in = (au_input_t *)dksto_it_next(a->init)) != NULL) {
	if(in->name) {
	  if(a->doxy_output) {
	    dkstream_puts(s, nl);
	    dkstream_puts(s, str_dox1);
	    dkstream_puts(s, str_dox4);
	    dkstream_puts(s, in->name);
	    dkstream_puts(s, str_dox6);
	    dkstream_puts(s, nl);
	    dkstream_puts(s, str_dox2);
	    dkstream_puts(s, nl);
	  }
	  l = strlen(in->name);
	  dkstream_puts(s, x_define);
	  while(l < maxl) {
	    l++; dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, in->name);
	  dkstream_puts(s, sp);
	  sprintf(buffer, "%d", in->number);
	  dkstream_puts(s, buffer);
	  dkstream_puts(s, nl);
	}
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, c_outputs); dkstream_puts(s, nl);
      dksto_it_reset(a->outit);
      while((out = (au_output_t *)dksto_it_next(a->outit)) != NULL) {
	if(out->name) {
	  if(a->doxy_output) {
	    dkstream_puts(s, nl);
	    dkstream_puts(s, str_dox1);
	    dkstream_puts(s, str_dox5);
	    dkstream_puts(s, out->name);
	    dkstream_puts(s, str_dox6);
	    dkstream_puts(s, nl);
	    dkstream_puts(s, str_dox2);
	    dkstream_puts(s, nl);
	  }
	  l = strlen(out->name);
	  dkstream_puts(s, x_define);
	  while(l < maxl) {
	    l++; dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, out->name);
	  dkstream_puts(s, sp);
	  sprintf(buffer, "%d", out->number);
	  dkstream_puts(s, buffer);
	  dkstream_puts(s, nl);
	}
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, c_fct); dkstream_puts(s, nl);
      switch(a->prototypes) {
	case 2: {
	  dkstream_puts(s, x_include);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, "<dk.h>");
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_include);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, "<dktypes.h>");
	  dkstream_puts(s, nl);
	  dkstream_puts(s, nl);
          dkstream_puts(s, x_ifndef);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, c_def);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_if);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_exclam);
	  dkstream_puts(s, str_dk_have_prototypes);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_define);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_EXTERN);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_extern);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_else);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_define);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_EXTERN);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_nix);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_endif);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_else);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_define);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_EXTERN);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_nix);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_endif);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, nl);
	  ptr = cpp_begin_text;
	  while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
	  dkstream_puts(s, nl);
	  if(a->doxy_output) { put_string_array(s, dox_trans); }
	  dkstream_puts(s, str_EXTERN);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, fct_name);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_dk_pr);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_all);
	  dkstream_puts(s, str_s);
	  dkstream_puts(s, str_comma);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_i);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, nl);
	  if(a->doxy_output) { put_string_array(s, dox_res); }
	  dkstream_puts(s, str_EXTERN);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_void);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, res_name);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_dk_pr);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_all);
	  dkstream_puts(s, str_s);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, nl);
	  ptr = cpp_end_text;
	  while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
	  dkstream_puts(s, nl);
	} break;
	case 1: {
	  ptr = cpp_begin_text;
	  while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
	  if(a->doxy_output) { put_string_array(s, dox_trans); }
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, fct_name);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_all);
	  dkstream_puts(s, str_s);
	  dkstream_puts(s, str_comma);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_i);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, nl);
	  if(a->doxy_output) { put_string_array(s, dox_res); }
	  dkstream_puts(s, str_void);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, res_name);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_all);
	  dkstream_puts(s, str_s);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, nl);
	  ptr = cpp_end_text;
	  while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
	} break;
	default: {
	  ptr = cpp_begin_text;
	  while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
	  dkstream_puts(s, x_ifndef);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, c_def);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_extern);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_endif);
	  dkstream_puts(s, nl);
	  if(a->doxy_output) { put_string_array(s, dox_trans); }
	  dkstream_puts(s, str_type);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, fct_name);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_ifndef);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, c_def);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_extern);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, x_endif);
	  dkstream_puts(s, nl);
	  if(a->doxy_output) { put_string_array(s, dox_res); }
	  dkstream_puts(s, str_void);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, res_name);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_brclose);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, nl);
	  ptr = cpp_end_text;
	  while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
	} break;
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, x_endif); dkstream_puts(s, nl);
    } break;
    case 2: {				/* source file */
      ptr = start_text;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      if(!(a->squeezed_output)) {
        dkstream_puts(s,nl);
        dkstream_puts(s,nl);
      }
      if(h_file_name) {
      if(strcmp(h_file_name, "-")) {
      dkstream_puts(s, x_include);
      dkstream_puts(s, str_quote);
      dkstream_puts(s, h_file_name);
      dkstream_puts(s, str_quote);
      dkstream_puts(s,nl);
      }
      }
      if(!(a->squeezed_output)) {
        dkstream_puts(s,nl);
      }
      if(a->initial_state) {
	st = a->initial_state;
	if(st->compat) { st = st->compat; }
	if(st->name) {
	  switch(a->prototypes) {
	    case 2: {
	      if(a->doxy_output) { put_string_array(s, dox_res); }
	      dkstream_puts(s, str_void);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, res_name);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, "DK_P1");
	      dkstream_puts(s, str_bropen);
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_comma);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_brclose);
	    } break;
	    case 1: {
	      if(a->doxy_output) { put_string_array(s, dox_res); }
	      dkstream_puts(s, str_void);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, res_name);
	      dkstream_puts(s, str_bropen);
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_brclose);
	    } break;
	    default : {
	      if(a->doxy_output) { put_string_array(s, dox_res); }
	      dkstream_puts(s, str_void);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, res_name);
	      dkstream_puts(s, str_bropen);
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_brclose);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_semicol);
	    } break;
	  }
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_curlopen);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, nl);
	  }
	  dkstream_puts(s, str_if);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_s);
	  dkstream_puts(s, str_brclose);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_curlopen);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_all);
	  dkstream_puts(s, str_s);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_equal);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, st->name);
	  dkstream_puts(s, str_semicol);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_curlclose);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, nl);
	  }
	  dkstream_puts(s, str_curlclose);
	  dkstream_puts(s, nl);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, nl);
	  }
	  switch(a->prototypes) {
	    case 2: {
	      if(a->doxy_output) { put_string_array(s, dox_trans); }
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, fct_name);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, "DK_P2");
	      dkstream_puts(s, str_bropen);
              dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_comma);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_comma);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, str_comma);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_i);
	      dkstream_puts(s, str_brclose);
	    } break;
	    case 1: {
	      if(a->doxy_output) { put_string_array(s, dox_trans); }
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, fct_name);
	      dkstream_puts(s, str_bropen);
              dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_comma);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_i);
	      dkstream_puts(s, str_brclose);
	    } break;
	    default : {
	      if(a->doxy_output) { put_string_array(s, dox_trans); }
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, fct_name);
	      dkstream_puts(s, str_bropen);
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_comma);
	      dkstream_puts(s, str_i);
	      dkstream_puts(s, str_brclose);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_semicol);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_type);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_i);
	      dkstream_puts(s, str_semicol);
	    } break;
	  }
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_curlopen);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_decl);
	  dkstream_puts(s, nl);
	  if(a->general_rule) {
	    st = (a->general_rule)->next_data;
	    if(st) {
	      if(st->compat) { st = st->compat ; }
	    }
	    out = (a->general_rule)->output_data;
	    if(out) {
	      if(out->name) {
	        dkstream_puts(s, str_o);
		if(!(a->squeezed_output)) {
	          dkstream_puts(s, sp);
		}
	        dkstream_puts(s, str_equal);
		if(!(a->squeezed_output)) {
	          dkstream_puts(s, sp);
		}
		dkstream_puts(s, out->name);
	        dkstream_puts(s, str_semicol);
	      } else {
	        dkstream_puts(s, str_o);
		if(!(a->squeezed_output)) {
	          dkstream_puts(s, sp);
		}
	        dkstream_puts(s, str_equal);
		if(!(a->squeezed_output)) {
	          dkstream_puts(s, sp);
		}
	        dkstream_puts(s, str_0);
	        dkstream_puts(s, str_semicol);
	      }
	    } else {
	      dkstream_puts(s, str_o);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_equal);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_0);
	      dkstream_puts(s, str_semicol);
	    }
	  } else {
	    dkstream_puts(s, str_o);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_equal);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    if(a->def_output) {
	      dkstream_puts(s, (a->def_output)->name);
	    } else {
	      dkstream_puts(s, str_0);
	    }
	    dkstream_puts(s, str_semicol);
	  }
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_if);
	  dkstream_puts(s, str_bropen);
	  dkstream_puts(s, str_s);
	  dkstream_puts(s, str_brclose);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_curlopen);
	  dkstream_puts(s, nl);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp); dkstream_puts(s, sp);
	  }
	  if(a->general_rule) {
	    st = (a->general_rule)->next_data;
	    if(st) {
	      if(st->compat) { st = st->compat ; }
	    }
	    if(st) {
	      if(st->name) {
	        dkstream_puts(s, str_n);
		if(!(a->squeezed_output)) {
	          dkstream_puts(s, sp);
		}
	        dkstream_puts(s, str_equal);
		if(!(a->squeezed_output)) {
	          dkstream_puts(s, sp);
		}
	        dkstream_puts(s, st->name);
	        dkstream_puts(s, str_semicol);
	      } else {
	        dkstream_puts(s, str_n);
		if(!(a->squeezed_output)) {
	          dkstream_puts(s, sp);
		}
	        dkstream_puts(s, str_equal);
	        dkstream_puts(s, sp);
	        dkstream_puts(s, str_all);
	        dkstream_puts(s, str_s);
	        dkstream_puts(s, str_semicol);
	      }
	    } else {
	      dkstream_puts(s, str_n);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_equal);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_s);
	      dkstream_puts(s, str_semicol);
	    }
	    out = (a->general_rule)->output_data;
	  } else {
	    dkstream_puts(s, str_n);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_equal);
	    dkstream_puts(s, sp);
	    dkstream_puts(s, str_all);
	    dkstream_puts(s, str_s);
	    dkstream_puts(s, str_semicol);
	  }
	  dkstream_puts(s, nl);
	  /* die zustandsunabhaengigen Regeln hier */
	  is_first_state = 1;
	  dksto_it_reset(a->asttrit);
	  while((tr = (TR *)dksto_it_next(a->asttrit)) != NULL) {
	    if(is_first_state) {
	      is_first_state = 0;
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp); dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_switch);
	      dkstream_puts(s, str_bropen);
	      dkstream_puts(s, str_i);
	      dkstream_puts(s, str_brclose);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_curlopen);
	      dkstream_puts(s, nl);
	    }
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_case);
	    dkstream_puts(s, sp);
	    dkstream_puts(s, tr->input_name);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_colon);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_curlopen);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, nl);
	    }
	    st2 = tr->next_data;
	    out = tr->output_data;
	    if(st2) {
	      if(st2->compat) {
		st2 = st2->compat;
	      }
	    }
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_n);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_equal);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    if(st2) {
	      if(st2->name) {
		dkstream_puts(s, st2->name);
	      } else {
	        if(a->squeezed_output) {
		  dkstream_puts(s, sp);
		}
		dkstream_puts(s, str_all);
		dkstream_puts(s, str_s);
	      }
	    } else {
	      if(a->squeezed_output) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_all);
	      dkstream_puts(s, str_s);
	    }
	    dkstream_puts(s, str_semicol);
	    if(out) {
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	    }
	    if(out) {
	      dkstream_puts(s, str_o);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_equal);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, out->name);
	      dkstream_puts(s, str_semicol);
	    }
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, nl);
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_curlclose);
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_break);
	    dkstream_puts(s, str_semicol);
	    dkstream_puts(s, nl);
	  }
	  if(!is_first_state) {
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp);
	      dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_curlclose);
	    dkstream_puts(s, nl);
	  }
	  is_first_state = 1;
	  dksto_it_reset(a->stit);
	  while((st = (au_state_t *)dksto_it_next(a->stit)) != NULL) {
	    if(!(st->compat)) {
	      if(is_first_state) {
		is_first_state = 0;
		if(!(a->squeezed_output)) {
		  dkstream_puts(s, sp);
		  dkstream_puts(s, sp);
		}
		dkstream_puts(s, str_switch);
		dkstream_puts(s, str_bropen);
		dkstream_puts(s, str_all);
		dkstream_puts(s, str_s);
		dkstream_puts(s, str_brclose);
		if(!(a->squeezed_output)) {
		  dkstream_puts(s, sp);
		}
		dkstream_puts(s, str_curlopen);
		dkstream_puts(s, nl);
	      }
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp); dkstream_puts(s, sp);
	        dkstream_puts(s, sp); dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_case);
	      dkstream_puts(s, sp);
	      dkstream_puts(s, st->name);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_colon);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_curlopen);
	      dkstream_puts(s, nl);
	      is_first_transition = 1;
              dksto_it_reset(st->trit);
	      while((tr = (TR *)dksto_it_next(st->trit)) != NULL) {
		if(tr->input_data) {
		  if(is_first_transition) {
		    is_first_transition = 0;
		    if(!(a->squeezed_output)) {
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		    }
		    dkstream_puts(s, str_switch);
		    dkstream_puts(s, str_bropen);
		    dkstream_puts(s, str_i);
		    dkstream_puts(s, str_brclose);
		    if(!(a->squeezed_output)) {
		      dkstream_puts(s, sp);
		    }
		    dkstream_puts(s, str_curlopen);
		    dkstream_puts(s, nl);
		  }
		  st2 = tr->next_data;
		  if(st2) {
		    if(st2->compat) {
		      st2 = st2->compat;
		    }
		  }
		  out = tr->output_data;
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_case);
		  dkstream_puts(s, sp);
		  dkstream_puts(s, (tr->input_data)->name);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_colon);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_curlopen);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, nl);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_n);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_equal);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  if(st2) {
		    dkstream_puts(s, st2->name);
		  } else {
		    if(a->squeezed_output) {
		      dkstream_puts(s, sp);
		    }
		    dkstream_puts(s, str_all);
		    dkstream_puts(s, str_s);
		  }
		  dkstream_puts(s, str_semicol);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_o);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_equal);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  if(out) {
		    dkstream_puts(s, out->name);
		  } else {
		    dkstream_puts(s, str_0);
		  }
		  dkstream_puts(s, str_semicol);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, nl);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_curlclose);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_break);
		  dkstream_puts(s, str_semicol);
		  dkstream_puts(s, nl);
		}
	      }
	      dksto_it_reset(st->trit);
	      tr2 = dksto_it_find_like(st->trit, str_all, 2);
	      if(tr2) {
		/*
		if(is_first_transition) {
		  is_first_transition = 0;
		  dkstream_puts(s, sp); dkstream_puts(s, sp);
		  dkstream_puts(s, sp); dkstream_puts(s, sp);
		  dkstream_puts(s, sp); dkstream_puts(s, sp);
		  dkstream_puts(s, str_switch);
		  dkstream_puts(s, str_bropen);
		  dkstream_puts(s, str_i);
		  dkstream_puts(s, str_brclose);
		  dkstream_puts(s, sp);
		  dkstream_puts(s, str_curlopen);
		  dkstream_puts(s, nl);
		}
		*/
		if(!is_first_transition) {
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_default);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_colon);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_curlopen);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, nl);
		  }
		}
		is_first_default_transition = 1;
		dksto_it_reset(a->asttrlit);
		while((tr3 = (TR *)dksto_it_next(a->asttrlit)) != NULL) {
		  if((tr3->lineno) < (tr2->lineno)) {
		    if(is_first_default_transition) {
		      is_first_default_transition = 0;
		      if(!(a->squeezed_output)) {
		        dkstream_puts(s, sp); dkstream_puts(s, sp);
		        dkstream_puts(s, sp); dkstream_puts(s, sp);
		        dkstream_puts(s, sp); dkstream_puts(s, sp);
		        dkstream_puts(s, sp); dkstream_puts(s, sp);
		        dkstream_puts(s, sp); dkstream_puts(s, sp);
		      }
		      dkstream_puts(s, str_switch);
		      dkstream_puts(s, str_bropen);
		      dkstream_puts(s, str_i);
		      dkstream_puts(s, str_brclose);
		      if(!(a->squeezed_output)) {
		        dkstream_puts(s, sp);
		      }
		      dkstream_puts(s, str_curlopen);
		      dkstream_puts(s, nl);
		    }
		    if(!(a->squeezed_output)) {
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		      dkstream_puts(s, sp); dkstream_puts(s, sp);
		    }
		    dkstream_puts(s, str_case); dkstream_puts(s, sp);
		    dkstream_puts(s, tr3->input_name);
		    if(!(a->squeezed_output)) {
		      dkstream_puts(s, sp);
		    }
		    dkstream_puts(s, str_colon);

		    dkstream_puts(s, nl);
		  }
		}
		if(!is_first_default_transition) {
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_break);
		  dkstream_puts(s, str_semicol);
		  dkstream_puts(s, nl);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_default);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_colon);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_curlopen);
		  dkstream_puts(s, nl);
		  /* tr2 ausgeben */
		  st2 = tr2->next_data;
		  if(st2) {
		    if(st2->compat) {
		      st2 = st2->compat;
		    }
		  }
		  out = tr2->output_data;
		  if(!(a->squeezed_output)) {
		   dkstream_puts(s, sp); dkstream_puts(s, sp);
		   dkstream_puts(s, sp); dkstream_puts(s, sp);
		   dkstream_puts(s, sp); dkstream_puts(s, sp);
		   dkstream_puts(s, sp); dkstream_puts(s, sp);
		   dkstream_puts(s, sp); dkstream_puts(s, sp);
		   dkstream_puts(s, sp); dkstream_puts(s, sp);
		   dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_n);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_equal);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  if(st2) {
		    dkstream_puts(s, st2->name);
		  } else {
		    if(a->squeezed_output) {
		      dkstream_puts(s, sp);
		    }
		    dkstream_puts(s, str_all);
		    dkstream_puts(s, str_s);
		  }
		  dkstream_puts(s, str_semicol);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_o);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_equal);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  if(out) {
		    dkstream_puts(s, out->name);
		  } else {
		    dkstream_puts(s, str_0);
		  }
		  dkstream_puts(s, str_semicol);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, nl);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_curlclose);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_break);
		  dkstream_puts(s, str_semicol);
		  dkstream_puts(s, nl);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_curlclose);
		  dkstream_puts(s, nl);
		} else {
		  st2 = tr2->next_data;
		  if(st2) {
		    if(st2->compat) {
		      st2 = st2->compat;
		    }
		  }
		  out = tr2->output_data;
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_n);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_equal);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  if(st2) {
		    dkstream_puts(s, st2->name);
		  } else {
		    if(a->squeezed_output) {
		      dkstream_puts(s, sp);
		    }
		    dkstream_puts(s, str_all);
		    dkstream_puts(s, str_s);
		  }
		  dkstream_puts(s, str_semicol);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_o);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_equal);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  if(out) {
		    dkstream_puts(s, out->name);
		  } else {
		    dkstream_puts(s, str_0);
		  }
		  dkstream_puts(s, str_semicol);
		  dkstream_puts(s, nl);
		}
		if(!is_first_transition) {
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		    dkstream_puts(s, sp); dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_curlclose);
		  if(!(a->squeezed_output)) {
		    dkstream_puts(s, sp);
		  }
		  dkstream_puts(s, str_break);
		  dkstream_puts(s, str_semicol);
		  dkstream_puts(s, nl);
		}
	      }
	      if(!is_first_transition) {
	        if(!(a->squeezed_output)) {
		  dkstream_puts(s, sp); dkstream_puts(s, sp);
		  dkstream_puts(s, sp); dkstream_puts(s, sp);
		  dkstream_puts(s, sp); dkstream_puts(s, sp);
		}
		dkstream_puts(s, str_curlclose);
		dkstream_puts(s, nl);
	      }
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	        dkstream_puts(s, sp);
	        dkstream_puts(s, sp);
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_curlclose);
	      if(!(a->squeezed_output)) {
	        dkstream_puts(s, sp);
	      }
	      dkstream_puts(s, str_break);
	      dkstream_puts(s, str_semicol);
	      dkstream_puts(s, nl);
	    }
	  }
	  if(!is_first_state) {
	    if(!(a->squeezed_output)) {
	      dkstream_puts(s, sp); dkstream_puts(s, sp);
	    }
	    dkstream_puts(s, str_curlclose);
	    dkstream_puts(s, nl);
	  }
	  /* neuen Zustand setzen, o zurueckgeben */
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp); dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_all);
	  dkstream_puts(s, str_s);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_equal);
	  if(!(a->squeezed_output)) {
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_n);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_curlclose);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_return);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_o);
	  dkstream_puts(s, str_semicol);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, str_curlclose);
	  dkstream_puts(s, nl);
	  dkstream_puts(s, nl);
	}
      }
    } break;
    case 3: {				/* Test file */
      
      ptr = start_text;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      dkstream_puts(s, nl);
      ptr = test_file_part1a;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}

      ptr = test_file_part1b;
      if((a->prototypes) == 2) {
	ptr = test_file_part1d;
      }
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      if(h_file_name) {
      if(strcmp(h_file_name, "-")) {
      dkstream_puts(s, x_include);
      dkstream_puts(s, str_quote);
      dkstream_puts(s, h_file_name);
      dkstream_puts(s, str_quote);
      dkstream_puts(s,nl);
      }
      }
      ptr = test_file_part1c;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      is_first_state = 1;
      dksto_it_reset(a->stit);
      while((st = (au_state_t *)dksto_it_next(a->stit)) != NULL) {
	if(!(st->compat)) {
	  if(is_first_state) {
	    dkstream_puts(s, decl_states_info);
	  } else {
	    dkstream_puts(s, str_comma);
	    dkstream_puts(s, nl);
	    dkstream_puts(s, sp);
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_curlopen);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, st->name);
	  dkstream_puts(s, str_comma);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_quote);
	  dkstream_puts(s, st->name);
	  dkstream_puts(s, str_quote);
	  dkstream_puts(s, str_curlclose);
	  is_first_state = 0;
	}
      }
      if(is_first_state) {
	dkstream_puts(s, decl_states_info);
	dkstream_puts(s, str_curlopen);
	dkstream_puts(s, sp);
	dkstream_puts(s, str_0);
	dkstream_puts(s, str_comma);
	dkstream_puts(s, sp);
	dkstream_puts(s, str_null);
	dkstream_puts(s, str_curlclose);
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, str_curlclose);
      dkstream_puts(s, str_semicol);
      dkstream_puts(s, nl);
      dkstream_puts(s, nl);

      is_first_state = 1;
      dksto_it_reset(a->init);
      while((in = (au_input_t *)dksto_it_next(a->init)) != NULL) {
	  if(is_first_state) {
	    dkstream_puts(s, decl_inputs_info);
	  } else {
	    dkstream_puts(s, str_comma);
	    dkstream_puts(s, nl);
	    dkstream_puts(s, sp);
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_curlopen);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, in->name);
	  dkstream_puts(s, str_comma);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_quote);
	  dkstream_puts(s, in->name);
	  dkstream_puts(s, str_quote);
	  dkstream_puts(s, str_curlclose);
	  is_first_state = 0;
      }
      if(is_first_state) {
	dkstream_puts(s, decl_inputs_info);
	dkstream_puts(s, str_curlopen);
	dkstream_puts(s, sp);
	dkstream_puts(s, str_0);
	dkstream_puts(s, str_comma);
	dkstream_puts(s, sp);
	dkstream_puts(s, str_null);
	dkstream_puts(s, str_curlclose);
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, str_curlclose);
      dkstream_puts(s, str_semicol);
      dkstream_puts(s, nl);
      dkstream_puts(s, nl);

      is_first_state = 1;
      dksto_it_reset(a->outit);
      while((out = (au_output_t *)dksto_it_next(a->outit)) != NULL) {
	  if(is_first_state) {
	    dkstream_puts(s, decl_outputs_info);
	  } else {
	    dkstream_puts(s, str_comma);
	    dkstream_puts(s, nl);
	    dkstream_puts(s, sp);
	    dkstream_puts(s, sp);
	  }
	  dkstream_puts(s, str_curlopen);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, out->name);
	  dkstream_puts(s, str_comma);
	  dkstream_puts(s, sp);
	  dkstream_puts(s, str_quote);
	  dkstream_puts(s, out->name);
	  dkstream_puts(s, str_quote);
	  dkstream_puts(s, str_curlclose);
	  is_first_state = 0;
      }
      if(is_first_state) {
	dkstream_puts(s, decl_outputs_info);
	dkstream_puts(s, str_curlopen);
	dkstream_puts(s, sp);
	dkstream_puts(s, str_0);
	dkstream_puts(s, str_comma);
	dkstream_puts(s, sp);
	dkstream_puts(s, str_null);
	dkstream_puts(s, str_curlclose);
      }
      dkstream_puts(s, nl);
      dkstream_puts(s, str_curlclose);
      dkstream_puts(s, str_semicol);
      dkstream_puts(s, nl);
      dkstream_puts(s, nl);
      ptr = test_file_part2a;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      switch(a->prototypes) {
	case 2: ptr = test_file_part2d; break;
	case 1: ptr = test_file_part2c; break;
	default: ptr = test_file_part2b;
      }
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      ptr = test_file_part2e;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      switch(a->prototypes) {
	case 2: ptr = test_file_part2h; break;
	case 1: ptr = test_file_part2g; break;
	default : ptr = test_file_part2f; break;
      }
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      ptr = test_file_part2i;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      dkstream_puts(s, "      output = ");
      dkstream_puts(s, fct_name);
      dkstream_puts(s, "(&state_machine, input);");
      ptr = test_file_part2j;
      while(*ptr) { dkstream_puts(s,*ptr); dkstream_puts(s,nl); ptr++;}
      
    } break;
  }
}
dk_delete(line); line = NULL;
} else {
  allstrings = genau_strings();
  if(allstrings && (a->app)) {
    errmsgs[0] = allstrings[20];
    dkapp_log_msg(a->app, DK_LOG_LEVEL_ERROR, errmsgs, 1);
  }
}
}



/**	Open a stream for writing.
	@param	name	File name.
	@param	app	Application.
	@return	Pointer to stream on success, NULL on error.
*/
static
dk_stream_t *
open_write_stream DK_P2(char *, name, dk_app_t *, app)
{
  dk_stream_t *back = NULL;
  char *suffix;
  int  compression_type;
#if (!DK_HAVE_ZLIB_H) || (!DK_HAVE_BZLIB_H)
  char *errmsgs[16], **allstrings;
#endif
  compression_type = 0;
  suffix = dksf_get_file_type_dot(name);
  if(suffix) {
    if(dkstr_casecmp(suffix, ".gz") == 0) { compression_type = 1; }
    if(dkstr_casecmp(suffix, ".bz2") == 0) { compression_type = 2; }
  }
  switch(compression_type) {
    case 1: {
#if DK_HAVE_ZLIB_H
      back = dkapp_stream_opengz(app, name, "w");
#else
      /* 03 ERROR: No support for zlib */
      allstrings = genau_strings();
      if(name && app && allstrings) {
	errmsgs[0] = str_quote;
	errmsgs[1] = name;
	errmsgs[2] = str_quote;
	errmsgs[3] = str_colon;
	errmsgs[4] = str_space;
	errmsgs[5] = allstrings[2];
	dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 6);
      }
#endif
    } break;
    case 2: {
#if DK_HAVE_BZLIB_H
      back = dkapp_stream_openbz2(app, name, "w");
#else
      /* 05 ERROR: No support for bzlib */
      allstrings = genau_strings();
      if(name && app && allstrings) {
	errmsgs[0] = str_quote;
	errmsgs[1] = name;
	errmsgs[2] = str_quote;
	errmsgs[3] = str_colon;
	errmsgs[4] = str_space;
	errmsgs[5] = allstrings[4];
	dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 6);
      }
#endif
    } break;
    default : {
      back = dkapp_stream_openfile(app, name, "w");
    } break;
  }
  return back;
}



/**	Process automata.
	@param	a	Automata to process.
	@param	app	Application.
	@return	1 on success, 0 on error.
*/
int
process_automata DK_P2(automata_t *, a, dk_app_t *, app)
{
int back = 0;
char *line, *ptrs[16], *arg;
char *c_file_name, *h_file_name, *r_file_name, *t_file_name;
char *fct_trans, *fct_res, *i_prot, *c_def;
dk_stream_t *os;
au_option_line_t *ol;
int  run_reduce, i;
char *errmsgs[16], **allstrings;

line = dk_new(char,LINELENGTH);
if(line) {
if(a && app) {
  back = 1;
  a->app = app;
  /*
    initialize variables
  */
  c_file_name = h_file_name = r_file_name = t_file_name = NULL;
  run_reduce = 0;
  fct_trans = fct_res = i_prot = c_def = NULL;
  /*
    process options, find out what to do
  */
  /* progress 05 : processing options section */
  allstrings = genau_progress();
  if(allstrings) {
    errmsgs[0] = allstrings[5];
    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
  }
  a->error_code = 0;
  dksto_it_reset(a->optit);
  while((ol = (au_option_line_t *)dksto_it_next(a->optit)) != NULL) {
    if(ol->line) {
      if(strlen(ol->line) < LINELENGTH) {
	strcpy(line, ol->line);
	arg = dkstr_chr(line, '=');
	if(arg) {
	  *(arg++) = '\0';
	  arg = dkstr_start(arg, NULL);
	  if(arg) {
	    for(i = 0; i < 16; i++) { ptrs[i] = NULL; }
	    ptrs[0] = dkstr_start(line, NULL);
	    if(ptrs[0]) {
	      dkstr_chomp(ptrs[0], NULL);
	      for(i = 1; i < 16; i++) {
		if(ptrs[i-1]) {
		  ptrs[i] = dkstr_next(ptrs[i-1], NULL);
		}
	      }
	      if(ptrs[15]) { ptrs[15] = NULL; }
	      switch(dkstr_find_multi_part_cmd(ptrs, options, 1)) {
		case 0 : {				/* c file */
		  c_file_name = dkstr_dup(arg);
		  if(!c_file_name) { a->error_code = 1; }
		} break;
		case 1 : {				/* h file */
		  h_file_name = dkstr_dup(arg);
		  if(!h_file_name) { a->error_code = 1; }
		} break;
		case 2 : {				/* prototypes */
		  if(dkstr_is_on(arg)) { a->prototypes = 1; }
		  else                 {
		    if(strcmp(arg, str_dk) == 0) {
		      a->prototypes = 2;
		    } else {
		      a->prototypes = 0; 
		    }
		  }
		} break;
		case 3 : {				/* transition fct */
		  fct_trans = dkstr_dup(arg);
		  if(!fct_trans) { a->error_code = 1; }
		} break;
		case 4 : {				/* reset fct */
		  fct_res = dkstr_dup(arg);
		  if(!fct_res) { a->error_code = 1; }
		} break;
		case 5 : {				/* reduced file */
		  r_file_name = dkstr_dup(arg);
		  if(!r_file_name) { a->error_code = 1; }
		} break;
		case 6 : {				/* reduce */
		  if(dkstr_is_on(arg)) run_reduce = 1;
		  else                 run_reduce = 0;
		} break;
		case 7 : {				/* include protect */
		  i_prot = dkstr_dup(arg);
		  if(!i_prot) { a->error_code = 1; }
		} break;
		case 8 : {				/* c define */
		  c_def = dkstr_dup(arg);
		  if(!c_def) { a->error_code = 1; }
		} break;
		case 9: {
		  t_file_name = dkstr_dup(arg);
		  if(!t_file_name) { a->error_code = 1; }
		} break;
		case 10: {
		  if(arg) {
		    a->squeezed_output = dkstr_is_on(arg);
		  } else {
		    a->squeezed_output = 1;
		  }
		} break;
		case 11: {
		  if(arg) {
		    a->doxy_output = dkstr_is_on(arg);
		  } else {
		    a->doxy_output = 1;
		  }
		} break;
	      }
	    }
	  }
	}
      }
    }
  }
  /*
    reduce if necessary
  */
  
  if(!(a->error_code)) {
    a->name_trans = (fct_trans ? fct_trans : default_fct_name);
    a->name_res   = (fct_res   ? fct_res   : default_res_name);
    a->app        = app;
    a->i_prot     = (i_prot ? i_prot : default_i_prot);
    a->c_def      = (c_def ? c_def : default_c_define);
    a->h_file_name = (h_file_name ? h_file_name : default_h_file_name);
    a->t_file_name = t_file_name;
    
    if(run_reduce || r_file_name) {
      
      reduce_automata(a, app);
      
    }
  }
  
  /*
    continue if no errors
  */
  if(!(a->error_code)) {
    /*
      write header file
    */
    if(h_file_name) {
      if(strcmp(h_file_name, key_stdout)) {	
	os = open_write_stream(h_file_name, app);
	if(os) {
	  /* progress 06 : writing header file */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[6];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 1);
	  dkstream_close(os);
	} else {
	  /* ERROR: Failed to open output file */
          allstrings = genau_strings();
          if(h_file_name && app && allstrings) {
	    errmsgs[0] = str_quote;
	    errmsgs[1] = h_file_name;
	    errmsgs[2] = str_quote;
	    errmsgs[3] = str_colon;
	    errmsgs[4] = str_space;
	    errmsgs[5] = allstrings[18];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 6);
          }
	}
      } else {					
	os = dkstream_for_file(stdout);
	if(os) {
	  /* progress 06 : writing header file */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[6];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 1);
	  dkstream_close(os);
	} else {
	  /* 20 ERROR: Failed to open stream for stdout */
          allstrings = genau_strings();
          if(app && allstrings) {
	    errmsgs[0] = allstrings[19];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 1);
          }
	}
      }
    }
    /*
      write c file
    */
    if(c_file_name) {
      if(strcmp(c_file_name, key_stdout)) {	
	os = open_write_stream(c_file_name, app);
	if(os) {
	  /* progress 07 : writing function */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[7];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 2);
	  dkstream_close(os);
	} else {
	  /* 19 ERROR: Failed to open output file */
          allstrings = genau_strings();
          if(c_file_name && app && allstrings) {
	    errmsgs[0] = str_quote;
	    errmsgs[1] = c_file_name;
	    errmsgs[2] = str_quote;
	    errmsgs[3] = str_colon;
	    errmsgs[4] = str_space;
	    errmsgs[5] = allstrings[18];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 6);
          }
	}
      } else {					
	os = dkstream_for_file(stdout);
	if(os) {
	  /* progress 07 : writing function */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[7];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 2);
	  dkstream_close(os);
	} else {
	  /* 20 ERROR: Failed to open stream for stdout */
          allstrings = genau_strings();
          if(app && allstrings) {
	    errmsgs[0] = allstrings[19];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 1);
          }
	}
      }
    }
    /*
      write reduced file
    */
    if(r_file_name) {
      if(strcmp(r_file_name, key_stdout)) {
	os = open_write_stream(r_file_name, app);
	if(os) {
	  /* progress 08 : writing reduced file */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[8];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 0);
	  dkstream_close(os);
	} else {
	  /* 19 ERROR: Failed to open output file */
          allstrings = genau_strings();
          if(r_file_name && app && allstrings) {
	    errmsgs[0] = str_quote;
	    errmsgs[1] = r_file_name;
	    errmsgs[2] = str_quote;
	    errmsgs[3] = str_colon;
	    errmsgs[4] = str_space;
	    errmsgs[5] = allstrings[18];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 6);
          }
	}
      } else {
	os = dkstream_for_file(stdout);
	if(os) {
	  /* progress 08 : writing reduced file */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[8];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 0);
	  dkstream_close(os);
	} else {
	  /* 20 ERROR: Failed to open stream for stdout */
          allstrings = genau_strings();
          if(app && allstrings) {
	    errmsgs[0] = allstrings[19];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 1);
          }
	}
      }
    } else {
    }
    /*
      write test file
    */
    if(t_file_name) {
      if(strcmp(t_file_name, key_stdout)) {
	os = open_write_stream(t_file_name, app);
	if(os) {
	  /* progress 09 : writing test file */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[9];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 3);
	  dkstream_close(os);
	} else {
	  /* 19 ERROR: Failed to open output file */
          allstrings = genau_strings();
          if(t_file_name && app && allstrings) {
	    errmsgs[0] = str_quote;
	    errmsgs[1] = t_file_name;
	    errmsgs[2] = str_quote;
	    errmsgs[3] = str_colon;
	    errmsgs[4] = str_space;
	    errmsgs[5] = allstrings[18];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 6);
          }
	}
      } else {
	os = dkstream_for_file(stdout);
	if(os) {
	  /* progress 09 : writing test file */
	  allstrings = genau_progress();
	  if(allstrings) {
	    errmsgs[0] = allstrings[9];
	    dkapp_log_msg(app, DK_LOG_LEVEL_PROGRESS, errmsgs, 1);
	  }
	  write_automata(a, os, 3);
	  dkstream_close(os);
	} else {
	  /* 20 ERROR: Failed to open stream for stdout */
          allstrings = genau_strings();
          if(app && allstrings) {
	    errmsgs[0] = allstrings[19];
	    dkapp_log_msg(app, DK_LOG_LEVEL_ERROR, errmsgs, 1);
          }
	}
      }
    }
  }
  if(c_def)       { dk_delete(c_def); }
  if(i_prot)      { dk_delete(i_prot); }
  if(fct_res)     { dk_delete(fct_res); }
  if(fct_trans)   { dk_delete(fct_trans); }
  if(r_file_name) { dk_delete(r_file_name); }
  if(c_file_name) { dk_delete(c_file_name); }
  if(h_file_name) { dk_delete(h_file_name); }
  if(t_file_name) { dk_delete(t_file_name); }
  if(a->error_code) {
    back = 0;
    
  }
}
  dk_delete(line); line = NULL;
} else {
  allstrings = genau_strings();
  if(allstrings && (a->app)) {
    errmsgs[0] = allstrings[20];
    dkapp_log_msg(a->app, DK_LOG_LEVEL_ERROR, errmsgs, 1);
  }
}

return back;
}


