/*{{{}}}*/
/*{{{  #includes*/
#ifdef CONFIG_H
#   include "config.h"
#endif

#include <sys/types.h>
#include <limits.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>

#define MESSAGES_C
#define I_GETMSG_C
#define I_INIT_C

#include "origami.h"
#include <h/envvar_str.h>
#include <lib/ori_add_lib.h>
/*}}}  */

/*{{{  inputs - if possible, this defaults will be overwritten by origamimsg*/
public unsigned char NO=MSG_I_NO;
public unsigned char YES=MSG_I_YES;
public unsigned char AB=MSG_I_AB;
public unsigned char DO_AB=MSG_I_DO_AB;
public unsigned char DO_REST=MSG_I_DO_REST;
/*}}}  */
/*{{{  messages which can/should not be handled in getmsg*/
/*{{{  my name, maybe overwritten by rc-file*/
public unsigned char origami_name[BIND_NAME_LEN+1]="Origami";
/*}}}  */
/*{{{  coding chars 0..31 with @A.. HEX digits*/
public unsigned char const ctrl_decode[]=CTRL_CHARS;
public unsigned char const hex_digits[]=HEX_CHARS;
/*}}}  */
/*{{{  error's, which can occur before msg and rc are read*/
public char const M_FM[]=MSG_M_FM;
public char const M_INV_OCL[]=MSG_M_INV_OCL;
public unsigned char const M_MIS_MES[]=MSG_M_MIS_MES;
public unsigned char const M_IN_MES[]=MSG_M_IN_MES;
public unsigned char const M_NO_MEMORY[]=MSG_M_NO_MEMORY;
public unsigned char const M_NO_MALLOC[]=MSG_M_NO_MALLOC;
public unsigned char const M_INVALID_PATH[]=MSG_M_INVALID_PATH;
/*}}}  */
/*{{{  parts of filename*/
public unsigned char const M_CUT_PATH[]=CUT_PATH;
public char const M_RCSTR[]=RC_ENDING;
public char const M_MSGSTR[]=MSG_ENDING;
public char const M_HELPSTR[]=HELP_ENDING;
/*}}}  */
/*{{{  coding filed folds and attributes*/
public unsigned char const fold_f[]="F ";
public unsigned char const fold_a[]="A ";
/*}}}  */
/*{{{  some texts, used more than once*/
public unsigned char const question[]=" ? ";
#if FOLD_TAG_LENGTH>=3
   public const unsigned char pseudo_mark[]=PSEUDO_MARK;
#else
   extern const unsigned char three_space[]="   ";
#endif
public unsigned char const M_PSTR[]="pipe";
/*}}}  */
/*{{{  paths*/
#ifdef DOC_MSG
   public char const M_DOC_PATH[]=DOC_MSG;
#endif
public char const M_RC_PATH[]=ORIGAMI_RC_PATH;
/*}}}  */
#ifndef REGEXP
   /*{{{  missing functions*/
   public unsigned char const M_NOT_HERE[]=MSG_M_NOT_HERE;
   /*}}}  */
#endif
/*{{{  get_path_strings*/
private void get_path_strings(char *rc,char *help, char *msg)
{
  char *f;
  const char *dummy=MSG_NO_PLACE;

  f=open_sysfile(M_MSGSTR,(char*)0);
  strcpy(msg,(*f)?f:dummy);
  f=open_sysfile(M_RCSTR,(char*)0);
  strcpy(rc,(*f)?f:dummy);
  f=open_sysfile(M_HELPSTR,(char*)0);
  strcpy(help,(*f)?f:dummy);
}
/*}}}  */
/*{{{  copyright message*/
#ifdef NO_MSG
#  define copyright False
#else
   public boolean copyright=True;
#endif
/*{{{  get_copyright*/
public unsigned char const *get_copyright(boolean paths)
{
  char rc[_POSIX_PATH_MAX+1];
  char help[_POSIX_PATH_MAX+1];
  char msg[_POSIX_PATH_MAX+1];

  if (paths || copyright)
   { if (paths)
        get_path_strings(rc,help,msg);
     return
      ( get_msg
         ( MSG_ARG_FORMAT,
#          ifndef NO_MSG
               MSG_M_CP_INFO
#              ifdef PORTER
                  PORTER
#              endif
#          endif
#          ifdef DOC_MSG
              MSG_M_CP_DOC
#          endif
           "%c\n"
           MSG_PATHS,
#          ifdef DOC_MSG
              M_DOC_PATH,
#          endif
           (paths ? ' ' : '\0'),
           (unsigned char*)M_RC_PATH,
           msg,
           rc,
           help
         )
      );
   }
  else
     return((unsigned char*)empty_text);
}
/*}}}  */
/*}}}  */
/*{{{  the command line argument list*/
public unsigned char const M_S_USAGE[]=
   MSG_USAGE
   "\t" "origami"
   "\t" "[-ehinopvACDPVZ] [-a auto-save-"MSG_CLARG_DELAY"] [-d "MSG_CLARG_DSP_MODE"] [-f " MSG_CLARG_MASTR "]\n"
   "\t" "[-k " MSG_CLARG_NBASE "] [-l " MSG_CLARG_NUMBER "] [-m "MSG_CLARG_MNAME "] [-t " MSG_CLARG_TAB "]\n"
   "\t" "[-F "MSG_CLARG_NMASTR  "] [-K N|A] [-M " MSG_CLARG_MSTRING "] [-N " MSG_CLARG_LLINES "]\n"
   "\t" "[-O " MSG_CLARG_OCLV "] [-R " MSG_CLARG_RC "] [-S " MSG_CLARG_SHELL "] [-T " MSG_CLARG_DEFAULT_NAME "]\n"
   "\t" "[-W " MSG_CLARG_WINNAME "] "
#ifdef OWN_ARG_USAGE_SHORT
                                     OWN_ARG_USAGE_SHORT
#else
                                     "[-X " MSG_CLARG_OSO "]"
#endif
                                                           " [" MSG_CLARG_FILES "]\n"
   MSG_DETAILS
#  ifdef DEBUGGING
   " and debugging options"
#  endif
  "\n"
;
/*}}}  */
/*{{{  long version of ^*/
/*{{{  string*/
#define first_indent "    "
#define tag_entry(o,s) first_indent "-" o ":\t\t" s "\n"
#define arg_entry(o,a,s)  first_indent "-" o " " a ":\t" s "\n"
private char const M_L_USAGE[]=
   MSG_USAGE "\n"
   first_indent "origami [" MSG_OPTIONS "] [" MSG_CLARG_FILES "]\n"
   "Origami " MAJOR_VERSION "." MINOR_VERSION "." REVISION " " MSG_OPT_ARE ":\n"
   arg_entry("a",MSG_CLARG_DELAY,  MSG_CLOP_a)
   arg_entry("d",MSG_CLARG_DSP_MODE,MSG_CLOP_d)
   tag_entry("e",                  MSG_CLOP_e)
   arg_entry("f",MSG_CLARG_MASTR,  MSG_CLOP_f)
   tag_entry("h",                  MSG_CLOP_h)
   tag_entry("i",                  MSG_CLOP_i)
   arg_entry("k",MSG_CLARG_NAME,   MSG_CLOP_k)
   arg_entry("l",MSG_CLARG_NUMBER, MSG_CLOP_l)
   arg_entry("m",MSG_CLARG_NAME,   MSG_CLOP_m)
   tag_entry("n",                  MSG_CLOP_n)
   tag_entry("o",                  MSG_CLOP_o)
   tag_entry("p",                  MSG_CLOP_p)
   arg_entry("t",MSG_CLARG_WIDTH,  MSG_CLOP_t)
   tag_entry("v",                  MSG_CLOP_v)
   tag_entry("A",                  MSG_CLOP_A)
#  ifdef SW_MSG
   tag_entry("C",                  MSG_CLOP_C)
#  else
   tag_entry("C",                  MSG_CLOP_IGNORE)
#  endif
   tag_entry("D",                  MSG_CLOP_D)
   arg_entry("F",MSG_CLARG_NMASTR, MSG_CLOP_F)
   arg_entry("K",MSG_CLARG_STATE,  MSG_CLOP_K)
   arg_entry("M",MSG_CLARG_MARK,   MSG_CLOP_M)
#  ifdef VIRTUAL
   arg_entry("N",MSG_CLARG_LINES,  MSG_CLOP_N)
#  else
   arg_entry("N",MSG_CLARG_LINES,  MSG_CLOP_IGNORE)
#  endif
   arg_entry("O",MSG_CLARG_VALUE,  MSG_CLOP_O "%s")
   tag_entry("P",                  MSG_CLOP_P)
   arg_entry("R",MSG_CLARG_RC,     MSG_CLOP_R)
   arg_entry("S",MSG_CLARG_SHELL,  MSG_CLOP_S)
#  ifdef WINDOW_TITLE_CHANGE
   arg_entry("T",MSG_CLARG_NAME,   MSG_CLOP_T)
#  else
   arg_entry("T",MSG_CLARG_NAME,   MSG_CLOP_IGNORE)
#  endif
   tag_entry("V",                  MSG_CLOP_V)
   arg_entry("W",MSG_CLARG_NAME,   MSG_CLOP_W)
#  ifdef OWN_ARG_USAGE_LONG
   first_indent  OWN_ARG_USAGE_LONG
#  else
   arg_entry("X",MSG_CLARG_STRING, MSG_CLOP_IGNORE)
#  endif
   tag_entry("Z",                  MSG_CLOP_Z)
#  ifdef DEBUGGING
   "and debugging options:\n"
#  ifdef MALLOC_DEBUG
   arg_entry("@","m",              "display number of malloced bytes")
   arg_entry("@","ms<no>",         "only <xx> bytes can be malloced")
   arg_entry("@","mp<no>",         "malloced paket sizes are multiples of <no>, a power of 2")
   arg_entry("@","m%<no>",         "free looses <no> percent (fragmentation)")
   arg_entry("@","mf<name>",       "malloc writes a dumb to file <name>")
#  ifndef FILE_DEBUG
#     define FILE_DEBUG
#  else
#     ifndef M_FILE_DEBUG
#        define M_FILE_DEBUG
#     endif
#  endif
#  endif
#  ifdef OCL_DEBUG
   arg_entry("@","os",             "show current stack depth")
   arg_entry("@","oS",             "show max reached stack depth")
   arg_entry("@","od",             "screen-off does not switch off the screen, but displays OFF")
   arg_entry("@","ot<delay>",      "sleep for <delay>/1000 seconds between each OCL command")
   arg_entry("@","of<name>",       "dump executed commands on file")
   arg_entry("@","ok<name>",       "dump keyboard input on file")
#  ifndef FILE_DEBUG
#     define FILE_DEBUG
#  else
#     ifndef M_FILE_DEBUG
#        define M_FILE_DEBUG
#     endif
#  endif
#  endif
#  ifdef VIR_DEBUG
   arg_entry("@","v",              "display the size of the virtual file")
   arg_entry("@","vf<name>",       "virtual line handling writes a dumb")
#  ifndef FILE_DEBUG
#     define FILE_DEBUG
#  else
#     ifndef M_FILE_DEBUG
#        define M_FILE_DEBUG
#     endif
#  endif
#  endif
#  ifdef FILE_DEBUG
      "\t\tA missing debug file name causes Origami to use: '" DEBUG_FILE "'\n"
#     ifdef M_FILE_DEBUG
         "\t\tMultiple usage of one debug file is allowed.\n"
#     endif
#  endif
#  endif
#  ifdef DOC_MSG
      MSG_DOC_PATH
#  endif
   MSG_PATHS
;
/*}}}  */
public unsigned char const *get_long_usage(void)
{
  /*{{{  variables*/
  char rc[_POSIX_PATH_MAX+1];
  char msg[_POSIX_PATH_MAX+1];
  char help[_POSIX_PATH_MAX+1];
#  define HELP_OFF (BIND_NAME_LEN+8)
#  define DEF_TAB 8
#  define DEF_SCR 80
  char opts[HELP_OFF+NO_OCL_CMD_OPTS*(2*BIND_NAME_LEN+2)+2];
  /*}}}  */

  /*{{{  get rc-options*/
  opts[0]='\0';
  if (!rcfileparser(opts+HELP_OFF,(char*)0) && opts[HELP_OFF])
   /*{{{  collect all options in one string*/
   { char *o,*p;
     int l;

     /*{{{  start message: 'name:'*/
     opts[0]='\n';
     opts[1]=opts[2]='\t';
     strcpy(opts+3,(char*)origami_name);
     for (p=opts;*p;p++);
     l=2*DEF_TAB+ustrlen(origami_name);
     p=opts+l-2*(DEF_TAB-1);
     *p++=':';
     /*}}}  */
     for (o=opts+HELP_OFF;*o;)
      {
        /*{{{  whitespace or newline*/
        if (l++<DEF_SCR-strlen(o))
           *p++=' ';
        else
         { strcpy(p,"\n\t\t\t");
           p+=4;
           l=3*DEF_TAB;
         }
        /*}}}  */
        /*{{{  append*/
        while ((*p = *o++))
         { p++;
           l--;
         }
        /*}}}  */
        /*{{{  skip argument*/
        while (*o++);
        /*}}}  */
      }
     *p='\0';
   }
   /*}}}  */
  /*}}}  */
  get_path_strings(rc,help,msg);
  return
   ( get_msg
      ( MSG_ARG_FORMAT,
        M_L_USAGE,
        MIN_ALARMTIME,
        MAX_ALARMTIME,
        NORM_ALARMTIME,
        opts,
        M_DOC_PATH,
        M_RC_PATH,
        msg,
        rc,
        help
      )
   );
}
/*}}}  */
/*}}}  */
