/*{{{}}}*/
/*{{{  #includes*/
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <signal.h>
#ifndef NO_GETOPT_H
#  include <getopt.h>
#endif

#define KEYBIND_C

#include <h/getmsg.h>
#include "keybind.h"
#include <h/rcformat.h>
#include <h/envvar_str.h>
#include <lib/ori_rc_lib.h>
#include <lib/ori_add_lib.h>
/*}}}  */

/*{{{  variables*/
private unsigned char std_basename[]=STD_BASENAME;
private unsigned char bnd_name[BIND_NAME_LEN]="Origami";
public boolean commenting=False,
               do_opt=False,
               sorting=False,
               warning=False;
public int verbose_level= -1,
           t_counter=0,
           tl_counter=0,
           m_counter=0;
public LOC_FILE rc={ 0,False,0 };
public LOC_FILE in={ 0,False,0 };
public LOC_FILE ref={ 0,False,0 };
public LOC_FILE ref_no={ 0,False,0 };
public unsigned char *dest_mac=0;
public char *lib_path;
#ifndef STD_FILTER
#   define STD_FILTER 0
#endif
private unsigned char *source_filter=STD_FILTER;
#ifndef STD_TOP_FILTER
#   define STD_TOP_FILTER 0
#endif
private unsigned char *top_filter=STD_TOP_FILTER;
private boolean rcref=False;
private LOC_FILE bnd={ 0,False,0 };
private struct RC_STR
 { unsigned char *text;
   struct RC_STR *next;
   TOKEN ad;
 } *rc_strings=0;
private int rc_str_count=0;
private int rc_str_lg=0;
/*}}}  */

/*{{{  display usage*/
private void do_usage(void)
{
  fprintf(stderr,M_USAGE);
  fprintf(stderr,M_MICE);
  show_mice(stderr);
  fputc('\n',stderr);
}
/*}}}  */
/*{{{  completebase*/
private unsigned char *completebase(unsigned char *s, unsigned char *filebase, unsigned char *t)
{
  ustrcpy(s,filebase);
  ustrcat(s,t);

  return(s);
}
/*}}}  */
/*{{{  open source-file*/
public FILE *open_source(LOC_FILE *lf,unsigned char *name,boolean top)
{ unsigned char f[256];

  lf->unlink_name=0;
  if ((top?top_filter:source_filter)==0)
   { lf->fp=fopen((char*)name,(char*)"r");
     lf->pipe=0;
   }
  else
     if (access((char*)name,R_OK))
        lf->fp=0;
     else
      { ustrcpy(f,top?top_filter:source_filter);
        strcat((char*)f," ");
        ustrcat(f,name);
        lf->fp=popen((char*)f,(char*)"r");
        lf->pipe=True;
      }
# ifdef SETBUF
     if (lf->fp) SETBUF(lf->fp);
# endif
  return (lf->fp);
}
/*}}}  */
/*{{{  clear_file*/
public void clear_file(LOC_FILE *f)
{ if (f->fp)
     if (f->pipe)
        pclose(f->fp);
     else
        fclose(f->fp);
  if (f->unlink_name)
     unlink((char*)f->unlink_name);
}
/*}}}  */
/*{{{  kbd_exit*/
public void kbd_exit(int ret)
{ clear_file(&rc);
  clear_file(&bnd);
  clear_file(&in);
  clear_file(&ref);
  clear_file(&ref_no);
  exit(ret);
}
/*}}}  */
/*{{{  kbd_malloc/free*/
public void *kbd_malloc(size_t l)
{
  void *x;

  if (!(x=ORImalloc(l)))
   { fprintf(stderr,M_NOMEMORY);
     kbd_exit(1);
   }
  return(x);
}
public void kbd_free(void *x)
{
  ORIfree(x);
}
/*}}}  */
/*{{{  write procedures*/
/*{{{  write mark-type to rc*/
public void write_mark_rc(unsigned char *name, unsigned char marks[4][FOLD_TAG_LENGTH+1])
{
  int i,j;
  unsigned char *n=name;

  if (dest_mac)
     return;
  rc_put_c(RC_MARKS,rc.fp);
  for (i=1;i<FOLD_PATTERN_LEN;i++)
     if (*n!='\0')
        rc_put_c(*n++,rc.fp);
     else
        rc_put_c('\0',rc.fp);
  for (i=0;i<4;i++)
     for (j=0;j<FOLD_TAG_LENGTH;j++)
        rc_put_c(marks[i][j],rc.fp);
  m_counter++;
  if (verbose_level>0)
     fprintf(stderr,F_MDECLARE,name);
}
/*}}}  */
/*{{{  write binding_name to rc file*/
public void write_name_rc(unsigned char *name)
{
  if (!dest_mac)
     if (*name=='\0' || ustrlen(name)>BIND_NAME_LEN)
        m_exit(M_NOBINDNAME);
     else
        ustrcpy(bnd_name,name);
}
/*}}}  */
/*{{{  write one macro definition to rc file*/
/*{{{  buffer for macro storage*/
#ifndef MAC_BUFF_SIZE
#  define MAC_BUFF_SIZE 0
#endif
private TOKEN mac_buff[OCL_CODE_LEN+secure_macro_lg+MAC_BUFF_SIZE+2];
public TOKEN *mac_ptr=mac_buff+2;
int mb_m_used=0;
int mb_t_used=0;
/*}}}  */
/*{{{  mb_flush*/
private void mb_flush(boolean full)
{
  if (mb_m_used)
     if (full || mb_t_used+2*mb_m_used>MAC_BUFF_SIZE+2)
      { TOKEN *t;
        int i;

        rc_put_c(RC_MAC_SET,rc.fp);
        rc_put_w(mb_t_used+mb_m_used,rc.fp);
        for (t=mac_buff,i=mb_t_used+2*mb_m_used;i;i--,t++)
           rc_put_w(*t,rc.fp);
        mac_ptr=mac_buff+2;
        mb_m_used=0;
        mb_t_used=0;
      }
}
/*}}}  */

public void write_macro_rc(int tag,TOKEN op,int lg,TOKEN *code,unsigned char *name)
{
  if (dest_mac && op!=O_EXE_MACRO)
     return;
  /*{{{  comment*/
  if (name && *name && commenting)
   { char *t="following macro is ";

     rc_put_c(RC_COMMENT,rc.fp);
     while (*t) rc_put_c(*t++,rc.fp);
     do
        rc_put_c(*name,rc.fp);
     while (*name++);
   }
  /*}}}  */
  switch (tag)
   { case RC_MAC_SET:
        if (demand)
           tag=RC_LOADMACRO;
        else
         /*{{{  add to buffer and maybe flush it*/
         {
           /*{{{  add mac to buffer*/
           *(mac_ptr-2)=op;
           *(mac_ptr-1)=lg;
           mac_ptr+=lg+2;
           mb_m_used++;
           mb_t_used+=lg;
           /*}}}  */
           mb_flush(commenting);
           /*{{{  verbose-mode*/
           if (verbose_level>0)
            { fprintf(stderr,F_STMAC,op,lg+1);
              t_counter += lg+1;
            }
           /*}}}  */

           return;
         }
         /*}}}  */
     case RC_INITMACRO:
     case RC_LOADMACRO:
        break;
     default:
       m_exit(M_NOMACROTAG);
   }
  /*{{{  verbose-mode*/
  if (verbose_level>0)
   { fprintf(stderr,(tag==RC_INITMACRO?F_DEMAC:F_LOMAC),op,lg+1);
     t_counter += lg+1;
     if (tag==RC_LOADMACRO)
        tl_counter+=lg+1;
   }
  /*}}}  */
  /*{{{  code*/
  rc_put_c(tag,rc.fp);
  rc_put_w(op,rc.fp);
  rc_put_w(lg,rc.fp);
  while (lg--) rc_put_w(*code++,rc.fp);
  /*}}}  */
}
/*}}}  */
/*{{{  write an usermodestring to rc*/
public void write_ums_rc(int no,unsigned char *lo,unsigned char *sh)
{
  int i;


  if (dest_mac)
     return;

  /*{{{  cut length*/
  lo[BIND_NAME_LEN]=sh[BIND_NAME_LEN]='\0';
  /*}}}  */
  /*{{{  lo==sh -> skip sh*/
  if (!ustrcmp(lo,sh))
     sh=(unsigned char*)"";
  /*}}}  */
  /*{{{  start mode field*/
  rc_put_c(RC_MODE,rc.fp);
  rc_put_c(no,rc.fp);
  /*}}}  */
  /*{{{  write long*/
  rc_put_w(i=ustrlen(lo),rc.fp);
  for (;i--;) rc_put_c(*lo++,rc.fp);
  /*}}}  */
  /*{{{  write short*/
  rc_put_w(i=ustrlen(sh),rc.fp);
  for (;i--;) rc_put_c(*sh++,rc.fp);
  /*}}}  */
}
/*}}}  */
/*{{{  write one definition to bind file*/
public void write_bind(unsigned char const *name,unsigned char *code,int kbd)
{
  unsigned char tag[REF_TAG_LG+1];

  if (dest_mac) return;
  name=cut_overload(name);
  ref_code_tag((char*)tag,kbd);
  fprintf
   ( bnd.fp,
     (kbd==mouse_kbd) ? ref_node_str("Mouse: %c") : ref_node_str("%s"),
     tag,
     ustrlen(name),
     name,
     code
   );
}
/*}}}  */
/*{{{  write_string*/
public TOKEN write_string(TOKEN *t,int lg,boolean generate)
{
  static TOKEN tok=MSG_ARG_FORMAT+1;
  struct RC_STR *x;

  x=kbd_malloc(sizeof(struct RC_STR)+lg+1);
  /*{{{  copy string to node*/
  { int i;

    x->text=(unsigned char*)((struct RC_STR*)x+1);
    for (i=0;i<lg;i++)
       x->text[i]=t[i];
    x->text[lg]='\0';
  }
  /*}}}  */
  /*{{{  check, if already defined*/
  { struct RC_STR *s;

    for (s=rc_strings;s;s=s->next)
       if (!ustrcmp(x->text,s->text))
        { kbd_free(x);
          return(s->ad);
        }
  }
  /*}}}  */
  if (!generate)
   { kbd_free(x);
     return(0);
   }
  /*{{{  insert in list of messages*/
  rc_str_lg+=lg+1;
  rc_str_count++;
  x->next=rc_strings;
  rc_strings=x;
  x->ad=tok++;
  /*}}}  */
  if (verbose_level>0)
     fprintf(stderr,F_STRING,x->text,x->ad);

  return(x->ad);
}
/*}}}  */
/*{{{  write rc-constants*/
public void put_consts(void)
{
  static off_t offset = (off_t)-1;
  off_t current=(off_t)-1;
  int i;

  if (dest_mac)
     return;
  /*{{{  handle position for const block*/
  if (offset==(off_t)-1)
   /*{{{  store position*/
     offset=ftell(rc.fp);
   /*}}}  */
  else
   /*{{{  store current and seek to first*/
   { current=ftell(rc.fp);
     fseek(rc.fp,offset,SEEK_SET);
   }
   /*}}}  */
  /*}}}  */
  /*{{{  write entry*/
  rc_put_c(RC_CONST,rc.fp);
  for (i=0;i<RCC_SIZE;i++)
     rc_put_w(bind_const[i],rc.fp);
  for (i=0;i<BIND_NAME_LEN;i++)
     rc_put_c(bnd_name[i],rc.fp);
  for (i=0;i<NO_OCL_CMD_OPTS*(2*BIND_NAME_LEN+2);i++)
     rc_put_c(ocl_opts[i],rc.fp);
  /*}}}  */
  /*{{{  maybe jump back*/
  if (current!=(off_t)-1)
     fseek(rc.fp,current,SEEK_SET);
  /*}}}  */
  /*{{{  write all missing macros*/
  mb_flush(True);
  /*}}}  */
  if (rc_strings)
   { rc_put_c(RC_STRINGS,rc.fp);
     rc_put_w(rc_str_count,rc.fp);
     rc_put_w(rc_str_lg,rc.fp);
     while (rc_str_count--)
      { char *s;
        struct RC_STR *x;

        for (s=(char*)rc_strings->text;*s;s++)
           rc_put_c(*s,rc.fp);
        rc_put_c('\0',rc.fp);
        x=rc_strings->next;
        kbd_free(rc_strings);
        rc_strings=x;
      }
     rc_str_lg=0;
   }
}
/*}}}  */
/*{{{  write one macro coded to stdout*/
public void write_dest_mac (TOKEN *b,int lg)
{
  write_macro_rc(RC_INITMACRO,O_EXE_MACRO,lg,b,(unsigned char*)0);
  rc_put_c(RC_ENDE,rc.fp);
}
/*}}}  */
/*{{{  write mousebutton-mapping to rc*/
public void write_buttons_rc(TOKEN*map,int buttons)
{
  int i;

  if (dest_mac) return;
  rc_put_c(RC_M_TAB,rc.fp);
  rc_put_w(buttons,rc.fp);
  for (i=0;i<buttons;i++) rc_put_w(map[i],rc.fp);
  if (verbose_level>0) fprintf(stderr,F_M_USE,m_name,buttons);
}
/*}}}  */
/*{{{  rc_app_help*/
/*{{{  compress_and_print_help*/
private unsigned int compress_and_print_help(unsigned char *saved_line)
{
  if (do_opt)
   { unsigned char *line;

     for (line=saved_line;;)
      { switch(*line++)
         { case REF_NODE_LIMITER:
              ref_compress_text(line);
           case '\0':
              break;
           default:
              continue;
         }
        break;
      }
   }
  fputs((char*)saved_line,rc.fp);

  return(ustrlen(saved_line));
}
/*}}}  */

private boolean rc_app_help(unsigned char *filename,boolean add_tag,boolean f_unlink)
{
  /*{{{  variables*/
  FILE *f;
  int c;
  unsigned char line_buff[RC_HELP_LEN+2];
  unsigned char saved_line_buff[RC_HELP_LEN+2];
  unsigned char *l0;
  int lines;
  int pre_c_size=0,post_c_size=0;
  /*}}}  */

  if (!(f=fopen((char*)filename,(char*)"rb")))
     return(True);
# ifdef SETBUF
     SETBUF(f);
# endif
  saved_line_buff[0]='\0';
  l0=line_buff;
  if (add_tag)
   /*{{{  generate reference tag in front of line*/
   { ref_code_tag((char*)line_buff,ref_kbd);
     while (*l0)
        l0++;
     *l0++=REF_NODE_LIMITER;
   }
   /*}}}  */
  *l0='\0';
  for
   ( lines= -1,
     saved_line_buff[0]='\0'
   ; !feof(f)
   ; lines++
   )
   {
     /*{{{  read one line of data*/
     { unsigned char *lx;

       for(lx=l0;;)
        { c=fgetc(f);
          if (c=='\n' || c==EOF)
           { *lx='\0';
             pre_c_size+=(lx-line_buff);
             break;
           }
          else if (lx<l0+RC_HELP_LEN)
           { if (c>=' ')
                *lx++=c;
             else
              { *lx++='^';
                if (lx<l0+RC_HELP_LEN)
                   *lx++=CTRL_CHARS[c];
              }

           }
        }
     }
     /*}}}  */
     /*{{{  cut trailing spaces*/
     { unsigned char *s,*y;

       for (y=line_buff;*y && *y++!=REF_NODE_LIMITER;);
       for (s=y;;)
        { switch (*s++)
           { default:
                y=s;
             case ' ':
                continue;
             case '\n':
             case '\0':
                break;
           }
          break;
        }
       *y++='\n';
       *y='\0';
     }
     /*}}}  */
     if (line_buff[0]!='\0' && line_buff[0]!='\n')
      /*{{{  store this line*/
      { if (saved_line_buff[0])
         /*{{{  print saved line or alias*/
         { if (do_opt)
            { unsigned char *o,*n;

              /*{{{  skip old tag*/
              for (o=saved_line_buff;*o && *o!=REF_NODE_LIMITER;o++);
              /*}}}  */
              /*{{{  skip new tag*/
              for (n=line_buff;*n && *n!=REF_NODE_LIMITER;n++);
              /*}}}  */
              if
               /*{{{  same text, different tags and alias shorter than text*/
               (    (!ustrcmp(o,n))
                 && (ustrlen(n)>(n-line_buff))
                 && (ustrcmp(saved_line_buff,line_buff))
               )
               /*}}}  */
               /*{{{  change old data to link*/
               { *o++=REF_NODE_ALIAS;
                 for (n=line_buff;*n!=REF_NODE_LIMITER;*o++ = *n++);
                 *o++='\n';
                 *o='\0';
               }
               /*}}}  */
            }
           post_c_size+=compress_and_print_help(saved_line_buff);
         }
         /*}}}  */
        ustrcpy(saved_line_buff,line_buff);
      }
      /*}}}  */
   }
  if (saved_line_buff[0])
     post_c_size+=compress_and_print_help(saved_line_buff);
  /*{{{  verbose*/
  if (verbose_level>0 && lines)
     if (do_opt)
        fprintf
         ( stderr,
           "appended %s %d lines as help (compressed to %d%%).\n",
           filename,
           lines,
           (100*post_c_size)/pre_c_size
         );
     else
        fprintf(stderr,"appended %s %d lines as help.\n",filename,lines);
  /*}}}  */
  if (fclose(f))
   { fprintf(stderr,F_CLOSE,filename);return(True); }

  return(f_unlink && unlink((char*)filename));
}
/*}}}  */
/*}}}  */

/*{{{  main*/
int main(int argc,char **argv)
{
  /*{{{  variable declarations*/
  unsigned char
       refname[_POSIX_PATH_MAX],
       refname_no[_POSIX_PATH_MAX],
       tmpbind[_POSIX_PATH_MAX],
       rcfile[_POSIX_PATH_MAX],
       bindfile[_POSIX_PATH_MAX];
  unsigned char *filebase=std_basename;
  boolean crashed;
  /*}}}  */

  /*{{{  init*/
  refname[0]='\0';
  init_alias();
  init_sets();
  signal(SIGTERM,kbd_exit);
  signal(SIGHUP,kbd_exit);
  signal(SIGINT,kbd_exit);
  signal(SIGQUIT,kbd_exit);
  if (!(lib_path=getenv(KBDPATH)) && !(lib_path=getenv(KBDPATH_1)))
     lib_path=KBD_PATH;
  /*}}}  */
  /*{{{  parse arguments*/
  { int c;

    /*{{{  Notes*/
    /* This is the first version which uses getopt, so the code is still suboptimal. */
    /*}}}  */
    while ((c=getopt(argc,argv,"cf:h?lo:sdvwr:F:ORm:M:U:L:V:"))!=EOF)
    switch (c)
    {
      /*{{{  f filter*/
      case 'f':
         top_filter=source_filter=(*optarg?(unsigned char*)optarg:(unsigned char*)0); break;
      /*}}}  */
      /*{{{  h, ?*/
      case '?':
      case 'h':
         do_usage();
         kbd_exit(0);
      /*}}}  */
      /*{{{  l*/
      case 'l':
      {
        sc_list_keys();
        kbd_exit(0);
        break;
      }
      /*}}}  */
      /*{{{  c*/
      case 'c':
      { commenting=True;
        break;
      }
      /*}}}  */
      /*{{{  o name*/
      case 'o':
       { static unsigned char new_out[_POSIX_PATH_MAX];

         strcpy((char*)(filebase=new_out),optarg);
         home_expand((char*)filebase);
         break;
       }
      /*}}}  */
      /*{{{  s*/
      case 's': sorting=True; break;
      /*}}}  */
      /*{{{  d*/
      case 'd': new_vars_enabled=True; break;
      /*}}}  */
      /*{{{  v*/
      case 'v': verbose_level=1; break;
      /*}}}  */
      /*{{{  w*/
      case 'w': warning=True; break;
      /*}}}  */
      /*{{{  r name*/
      case 'r':
         strcpy((char*)refname,optarg);
         home_expand((char*)refname);
         break;
      /*}}}  */
      /*{{{  F filter*/
      case 'F': top_filter= *optarg?(unsigned char*)optarg:(unsigned char*)0;source_filter=0; break;
      /*}}}  */
      /*{{{  L libpath*/
      case 'L': lib_path=optarg;break;
      /*}}}  */
      /*{{{  O*/
      case 'O': do_opt=True; break;
      /*}}}  */
      /*{{{  R*/
      case 'R': rcref=True; break;
      /*}}}  */
      /*{{{  m macro*/
      case 'm': dest_mac=(unsigned char*)optarg; break;
      /*}}}  */
      /*{{{  M name*/
      case 'M': m_name=(unsigned char*)optarg; break;
      /*}}}  */
      /*{{{  U tag*/
      case 'U': use_it((unsigned char*)optarg); break;
      /*}}}  */
      /*{{{  V level*/
      case 'V': verbose_level=atoi(optarg); break;
      /*}}}  */
    }
  }
  if (verbose_level>0)
     warning=True;
  /*}}}  */
  /*{{{  check lib path*/
    { char *k;
      char c;

      k=lib_path;
      while ((c = *k++))
         if
          (    ((c==LIST_C)||(c==LIST_C_1))
            && (((c = *k)==LIST_C)||(c==LIST_C_1)||(c=='\0'))
          )
          { fprintf(stderr,F_INV_PATH,lib_path);
            exit(1);
          }
    }
  /*}}}  */
  /*{{{  init keytabs*/
  init_keytables();
  /*}}}  */
  /*{{{  init @use*/
  default_using();
  /*}}}  */
  /*{{{  init compression data*/
  if (ref_init_comp_data(1))
     m_exit(M_NOMEMORY);
  /*}}}  */
  /*{{{  open files/pipe*/
  /*{{{  open reference files*/
  if (!dest_mac)
   {
     /*{{{  refcard file*/
     ref.unlink_name=0;
     ref.pipe=False;
     if (rcref && !refname[0])
      { tmpnam((char*)refname);
        ref.unlink_name=refname;
      }
     if (refname[0] && (ref.fp=fopen((char*)refname,(char*)"w"))==(FILE*)0)
        m_exit(M_NOREF);
#       ifdef SETBUF
           SETBUF(ref.fp);
#       endif
     /*}}}  */
     /*{{{  numbered refcard file*/
     ref_no.unlink_name=0;
     ref_no.pipe=False;
     tmpnam((char*)refname_no);
     ref.unlink_name=refname_no;
     if
      (    refname_no[0]
        && !(ref_no.fp=fopen((char*)refname_no,(char*)"w"))
      )
        m_exit(M_NOREF);
#       ifdef SETBUF
           SETBUF(ref_no.fp);
#       endif
     /*}}}  */
   }
  /*}}}  */
  /*{{{  open input-file*/
  if (optind>=argc)
   { do_usage();
     kbd_exit(1);
   }
  if (open_source(&in,(unsigned char*)argv[optind],True)==(FILE*)0)
     m_exit(M_NOBFILE);
  source=(unsigned char*)argv[optind];
  init_scan();
  /*}}}  */
  /*{{{  open .origamirc*/
  rc.pipe=False;
  rc.unlink_name=0;
  if (dest_mac)
     rc.fp=stdout;
  else if ((rc.fp=fopen((char*)completebase(rcfile,filebase,(unsigned char*)RC_ENDING),(char*)"wb"))==(FILE*)0)
     m_exit(F_NORC,filebase);
#  ifdef SETBUF
     SETBUF(rc.fp);
#  endif
  /*}}}  */
  /*{{{  open .origamibind*/
  tmpnam((char*)tmpbind);
  if (!dest_mac)
   { if (!sorting)
      /*{{{  open file*/
      { bnd.pipe=False;
        bnd.unlink_name=tmpbind;
        if ((bnd.fp=fopen((char*)tmpbind,(char*)"w"))==(FILE*)0)
           m_exit(F_NOBIND,tmpbind);
      }
      /*}}}  */
     else
      /*{{{  open pipe*/
      { bnd.pipe=True;
        bnd.unlink_name=tmpbind;
        sprintf((char*)bindfile,SORTCMD,(char*)tmpbind);
        if ((bnd.fp=popen((char*)bindfile,(char*)"w"))==(FILE*)0)
           m_exit(F_NOPIPE,bindfile);
      }
      /*}}}  */
#    ifdef SETBUF
        SETBUF(bnd.fp);
#    endif
   }
  /*}}}  */
  /*}}}  */
  if (dest_mac) verbose_level=0;
  crashed=process_file();
  if (!crashed && !dest_mac)
   /*{{{  handle bind*/
   { ref_put_comp_data(rc.fp);
     if (sorting ? pclose(bnd.fp) : fclose(bnd.fp))
      { bnd.fp=0;
        m_exit(F_CLOSE,"bindfile");
      }
     else
      { rc_put_c(RC_BIND,rc.fp);
        if (rc_app_help(tmpbind,False,True))
         { fprintf(stderr,F_NOBIND,tmpbind);
           crashed=True;
         }
      }
   }
   /*}}}  */
  else
   /*{{{  close bind*/
     clear_file(&bnd);
   /*}}}  */
  /*{{{  close ref*/
  if (ref.fp && fclose(ref.fp))
   { crashed=True;
     fprintf(stderr,F_CLOSE,refname);
     ref.fp=0;
   }
  /*}}}  */
  /*{{{  close ref_no*/
  if (ref_no.fp && fclose(ref_no.fp))
   { crashed=True;
     fprintf(stderr,F_CLOSE,refname_no);
     ref_no.fp=0;
   }
  /*}}}  */
  /*{{{  maybe copy ref to rc*/
  if (!dest_mac && !crashed)
   { if (rcref)
      { char pseudo_ref[8];

        ref_code_tag(pseudo_ref,-ref_file_id);
        fprintf(rc.fp,ref_format_str("r-file"),pseudo_ref);
        crashed=rc_app_help(refname,True,ref.unlink_name!=0);
      }
     if (!crashed)
      { char pseudo_ref[8];

        ref_code_tag(pseudo_ref,-ref_class_id);
        fprintf(rc.fp,ref_format_str("r-class"),pseudo_ref);
        crashed=rc_app_help(refname_no,False,True);
      }
     if (!crashed && !rcref)
      { char pseudo_ref[8];

        ref_code_tag(pseudo_ref,-ref_file_id);
        fprintf(rc.fp,ref_format_str("r-file"),pseudo_ref);
      }
   }
  /*}}}  */
  /*{{{  close rc and in and unlink tmp*/
  clear_file(&in);
  if (!dest_mac && fclose(rc.fp))
   { fprintf(stderr,F_CLOSE,"rc-file");
     crashed=True;
   }
  rc.fp=0;
  /*}}}  */
  /*{{{  maybe message*/
  if (crashed)
     m_exit(M_INCORRECTFILES);
  else if (verbose_level>0)
   { fprintf(stderr,F_INTS,var_count);
     fprintf(stderr,F_BINDS,t_counter,t_counter-tl_counter,tl_counter);
     fprintf(stderr,F_MARKT,m_counter);
     fprintf(stderr,F_MOUSE,m_name);
   }
  /*}}}  */
  kbd_exit(0);
}
/*}}}  */
