/*
* dvi2tty
* Copyright (C) 2003 Marcel J.E. Mol <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
*/

/*
* Include files
*/

#include "dvi2tty.h"
#if defined(VMS)
# include unixio
#endif
#if defined(THINK_C)
# include <unix.h>
# include "macintosh.h"
#endif

#if defined(WIN32) && defined(KPATHSEA)
#undef fopen
#define fopen fsyscp_fopen
#endif


/*
* Constant definitons
*/
   /*-----------------------------------------------------------------------*/
   /* The following constants may be toggled before compilation to          */
   /* customize the default behaviour of the program for your site.         */
   /* Whichever their settings are, the defaults can be overridden at       */
   /* runtime.                                                              */
   /*-----------------------------------------------------------------------*/

#define DEFSCAND    FALSE     /* default is not Scandinavian, toggle this if */
                             /* you have terminals with Scand. nat. chars */
#define DEFLATIN1   FALSE     /* default is no latin1, toggle this if you */
                             /* have terminals with latin1 chars */
#define WANTPAGER   TRUE      /* default: try to pipe through a pager (like  */
                             /* more) if stdout is tty and no -o switch     */
#define DEFPAGER    "more"   /* CHANGE TO YOUR LOCAL PAGER            */

   /*------------------ end of customization constants ---------------------*/

#if defined(MSDOS) || defined(VMS) || defined(AMIGA)
#define OPTSET      "haJweEpPousltvbcANUC" /* legal options                  */
#define OPTWARG     "weEpPovb"  /* options with argument                     */
#else
#define OPTSET      "haJweEpPousqlfFtvbcANUC" /* legal options               */
#define OPTWARG     "weEpPoFvb"     /* options with argument                 */
#endif

/*
* USAGE CODES
*/

#define wrnge  1                /* width switch arg out of range     */
#define ign    2                /* ignore cause, print 'Usage:..'    */
#define nan    3                /* not a number where one expected   */
#define gae    4                /* garbage at end                    */
#define bdlst  5                /* bad page-numberlist               */
#define onef   6                /* only one dvifile allowed          */
#define bdopt  7                /* bad option                        */
#define onepp  8                /* only one page list allowed        */
#define noarg  9                /* argument expected                 */
#define confl  10               /* -J, -N, -A, and -U conflict       */
#define incone 11               /* inconsistent output encoding      */
#if defined(THINK_C)
#define nored 100               /* if no input file, redirect stdin  */
#endif


/*
* Variable definitions
*/

const char *dvi2tty = "@(#) dvi2tty.c " VERSION " 20160305 M.J.E. Mol (c) 1989-2010, and contributors (c) -2016";


printlisttype * currentpage;    /* current page to print                     */
printlisttype * firstpage;      /* first page selected                       */
printlisttype * lastpage;       /* last page selected                        */

FILE *          DVIfile;
FILE *          output;
bool            outputtofile;   /* tells if output goes to file or stdout    */
#if defined(THINK_C)
bool            inputfromfile;  /* tells if input comes from file or stdin   */
#endif
int             ttywidth;       /* max nr of chars per printed line          */
int             espace;         /* to fake calcs with ttywidth               */

long            foo;            /* utility variable, "register"              */
#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C) && !defined(AMIGA)
bool            pager;          /* tells if output is piped to a pager       */
const char  *   path;           /* name of the pager to run                  */
#endif
char  *         progname;       /* our name                                  */
int             Argc;
char **         Argv;
char  *         DVIfilename;
const char *    OUTfilename;
char            optch;          /* for option handling                       */



/*
* Function declarations
*/

#if defined(MSDOS)
void    setoption (const char *);
void    getargs   (void);
void    getpages  (int, const char *);
void    plcnxt    (int);
void    getfname  (const char *);
int     getinteger(int *, int *, const char *);
int     getlong   (long *, int *, const char *);
void    usage     (int);
#else

# if defined(VMS)
       main      (int argc, char ** argv);
# endif
void    setoption (const char * optarg);
void    getargs   (void);
void    getpages  (int j, const char * str);
void    plcnxt    (int pagnr);
void    getfname  (const char * str);
int     getinteger(int * dest, int * j, const char * str);
int     getlong   (long * dest, int * j, const char * str);
void    usage     (int uerr);
#endif


/****************************************************************************/
/*                                                                          */
/*                                 M A I N                                  */
/*                                                                          */
/****************************************************************************/

#if defined(VMS)
main(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif
{
#if defined(WIN32) && defined(KPATHSEA)
   char *enc;
#endif

#if defined(THINK_C)
   argc = process_dvi_command_line(&argv);
#endif

   progname = *argv;
   Argc = argc;
   Argv = argv;
#if defined(WIN32) && defined(KPATHSEA)
   kpse_set_program_name(argv[0], "dvi2tty");
   enc = kpse_var_value("command_line_encoding");
   get_command_line_args_utf8(enc, &Argc, &Argv);
#endif

#ifdef WIN32
   set_enc_string ("sjis", "default");
#else
   set_enc_string (NULL, "default");
#endif
   getargs();                              /* read command line arguments   */
#if defined(THINK_C)
   if (inputfromfile) {
#endif
#if defined(MSDOS) || defined(WIN32)
       if ((DVIfile = fopen(DVIfilename, "rb")) == NULL)
#else
# if defined(VMS)
       if ((DVIfile = fopen(DVIfilename, "r","ctx=rec")) == NULL)
# else
       if ((DVIfile = fopen(DVIfilename, "r")) == NULL)
# endif
#endif
           errorexit(filop);               /* can't open dvifile            */
#if defined(THINK_C)
   }
   else
       DVIfile = stdin;
#endif

   if (outputtofile) {                     /* open the outfile, if needed   */
       if ((output = fopen(OUTfilename, "w")) == NULL)
           errorexit(filcr);
#if defined(THINK_C)
       else
           set_creator((unsigned char*) OUTfilename);
#endif

#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C)
       pager = FALSE;
#endif
   }
   else {
       output = stdout;
#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C)
       if (pager && isatty(fileno(output))) {   /* try to pipe to a pager   */
           if ((output = popen(path, "w")) == NULL) /* get pipe to pager    */
               errorexit(pipcr);                /* make output to output    */
       }
       else
           pager = FALSE;
#endif
   }

   dvimain();

#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C)
   if (pager)
       pclose(output);                     /* close pipe to pager            */
#endif

   exit(0);

} /* main */



/*
* GETARGS -- Process options from command line and from environment.
*/

void getargs(void)
{
   const char *str;
   char *envp;
   bool DVIfound;                      /* if a dvi filename found           */

#if !defined(THINK_C)
   if (Argc <= 1)
       usage(ign);
#endif

   pageswitchon = FALSE;       /* show all pages                            */
   sequenceon   = FALSE;       /* selected pages are TeX-numbered           */
   outputtofile = FALSE;       /* write to stdout                           */
#if defined(THINK_C)
   inputfromfile = FALSE;      /* read from stdin                           */
#endif
#if !defined(MSDOS) && !defined(VMS) && !defined (THINK_C) && !defined(AMIGA)
   pager        = WANTPAGER;   /* want paging, compile time option          */
#endif
   accent       = TRUE;        /* show all accent etc. as extra char        */
   ttfont       = FALSE;       /* assume tt font (verbatim mode)            */
   noffd        = FALSE;       /* print formfeed between pages              */
   scascii      = DEFSCAND;    /* scandinavian, compile time option         */
   latin1       = DEFLATIN1;   /* latin1 support, compile time option       */
   utf8         = FALSE;       /* print by utf encoding                     */
   noligaturefi = FALSE;       /* do not use ligature for ff,fi,fl,ffi,ffl  */
   ttywidth     = 80;          /* default terminal width                    */
   espace       = 0;           /* to fake ttywith calcs                     */
   DVIfound     = FALSE;
   printfont    = FALSE;       /* do not print font switches                */
   compose      = TRUE;        /* try to compose a combining character sequence */
   allchar      = FALSE;       /* do not put out all characters             */

#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C) && !defined(AMIGA)
   if ((path = getenv("PAGER")) == NULL)   /* find default pathname of page */
           path = DEFPAGER;             /* program in case paging is wanted */
#endif

   /*
    *
    * With VAX-C under VMS getenv normally searches the environment array
    * looking for the variables HOME, TERM, PATH, and USER.  In certain
    * situations getenv attempts to first perform a logical name translation
    * if none of the environment array strings are matched and then trying
    * to translate a CLI symbol.  Unfortunately we need a CLI symbol defined
    * as;
    *
    *     dvi2tty :== $path:dvi2tty.exe
    *
    * to invoke dvi2tty with command line arguments as it would be invoked
    * under Unix.  So we use the logical DVI$DVI2TYY as the environment
    * variable from which options may be set.
    *
    */

   /*
    * First process environment variable.
    */

#if defined(VMS)
   if ((envp = getenv("DVI$DVI2TTY")) != NULL) {
#else
   if ((envp = getenv("DVI2TTY")) != NULL) { /* } keep vi happy */
#endif
       while (*envp == ' ')
            envp++;
       while (*envp) {                     /* environment var args          */
           if (strchr(OPTSET, optch = *envp++) != NULL) {
               /*
                * we always pass one option, and arrange for optarg ourselfes,
                * so setoption does not mesh up Argv
                */
               if (strchr(OPTWARG, optch) != NULL) {
                   while (*envp == ' ')
                       envp++;
                   if (*envp == '\0')
                       usage(noarg);
                   str = envp;             /* str points to optarg          */
                   while ((*envp != ' ') && (*envp != '\0'))
                       envp++;             /* set envp just after optarg    */
                   if (*envp != '\0')
                       *envp++ = '\0';     /* end optarg string             */
               }
               else
                   str = "";
               setoption(str);
           }
           else
               usage(bdopt);
           while (*envp == ' ')
                envp++;
       }
   }

   /*
    * Now process command line options.
    */

   while (--Argc > 0) {                    /* command line args             */
       str = *++Argv;
       if (*str != '-') {                  /* argument is not an option     */
           if (DVIfound)                   /* only one dvi file allowed     */
               usage(onef);
           getfname(str);
#if defined(THINK_C)
           inputfromfile =
#endif
           DVIfound = TRUE;
       }
       else if (strchr(OPTSET, optch = *++str) != NULL) {
           str++;                      /* point to rest of argument if any  */
           if ((strchr(OPTWARG, optch) != NULL) && (*str == '\0')) {
               if (--Argc <= 0)
                   usage(noarg);
               str = *++Argv;
           }
           setoption(str);
       }
       else
           usage(bdopt);
   }

   if (!DVIfound)
#if defined(THINK_C)                             /* Allow use of stdin for   */
       if (isatty(fileno(stdin)))
           usage(nored);                        /*   Mac, if redirected     */
#else
       usage(ign);
#endif

   return;

} /* getargs */



/*
* SETOPTION -- Process an option.
*/

void setoption(const char *optarg)
{
   int j = 0;

   while (strchr(OPTSET, optch) != NULL) {
       switch (optch) {
           case 'h' : usage(ign); break;
#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C) && !defined(AMIGA)
           case 'q' : pager = FALSE; break;
           case 'f' : pager = TRUE; break;
           case 'F' : pager = TRUE;
                      path = optarg;
                      j = strlen(optarg);
                      break;
#endif
           case 'J' : jautodetect  = TRUE; break;
           case 'U' : uptex   = TRUE; japan = TRUE;    /* upTeX */
                      jautodetect = FALSE;
                      enable_UPTEX(true);
                      set_enc_string (NULL, UPTEX_INTERNAL_ENC);
                      break;
           case 'A' : asciip  = TRUE; japan = TRUE;    /* ASCII pTeX */
                      jautodetect = FALSE;
                      set_enc_string (NULL, PTEX_INTERNAL_ENC);
                      break;
           case 'N' : nttj    = TRUE; japan = TRUE;    /* NTT jTeX */
                      jautodetect = FALSE;
                      set_enc_string (NULL, JTEX_INTERNAL_ENC);
                      break;
           case 'E' :
               switch (optarg[0]) {
                      case 'e' :
                          set_enc_string ("euc", NULL);  break;
                      case 's' :
                          set_enc_string ("sjis", NULL); break;
                      case 'j' :
                          set_enc_string ("jis", NULL);  break;
                      case 'u' :
                          utf8 = TRUE;
                          set_enc_string ("utf8", NULL);
                          if (optarg[1]=='1') {
                              noligaturefi = TRUE; j++;
                          }
                          break;
                      default :
                          usage(noarg);
               }
                      j++;
                      break;
           case 't' : ttfont  = TRUE; break;
           case 'l' : noffd   = TRUE; break;
           case 's' : scascii ^= 1; break;
           case 'u' : latin1  ^= 1; break;
           case 'a' : accent  = FALSE; break;
           case 'C' : compose = FALSE; break;
           case 'c' : allchar = TRUE; break;
           case 'P' : sequenceon = TRUE;     /* fall through */
           case 'p' : if (pageswitchon)
                          usage(onepp);
                      getpages(j, optarg);
                      break;
           case 'w' : if (getinteger(&ttywidth, &j, optarg))
                          usage(nan);
                      if (optarg[j] != '\0')
                          usage(gae);
                      if ((ttywidth < 16) || (ttywidth > MAXTERMWIDTH))
                          usage(wrnge);
                      break;
           case 'e' : if (getinteger(&espace, &j, optarg))
                          usage(nan);
                      if (optarg[j] != '\0')
                          usage(gae);
                      break;
           case 'v' : if (getlong(&lineheight, &j, optarg))
                          usage(nan);
                      if (optarg[j] != '\0')
                          usage(gae);
                      /* lineheight *= 65536L; */
                         /* want to specify in pt, but have no getfloat */
                      break;
           case 'o' : OUTfilename = optarg;
                      outputtofile = TRUE;
                      j = strlen(optarg);
                      break;
           case 'b' : printfont = TRUE;
                      delim = optarg;
                      if (!strlen(optarg))
                          printfont = FALSE;
                      break;
           default  : usage(bdopt);
       }
       if ((optch = optarg[j++]) == '\0')
           break;
       if ( (optarg[j] == '\0') && (strchr(OPTWARG, optch) != NULL) ) {
               if (--Argc <= 0)
                   usage(noarg);
               optarg = *++Argv;
               j = 0;
           }
   }

   /* Option conflict */
   if ((asciip && uptex) ||
       (nttj && (asciip || uptex)) ||
       (jautodetect && (nttj || asciip || uptex))) {
       usage(confl);
   }
   if (((jautodetect || asciip || uptex || nttj || utf8)
         && (scascii || latin1)) ||
       (scascii && latin1)) {
       usage(incone);
   }

   return;

} /* setoption */



/*
* GETPAGES -- Getr a list of pages to print.
*/

void getpages(int j, const char *str)
{
   int i, c;
   int num;

   pageswitchon = TRUE;
   if ((firstpage = (printlisttype *) malloc(sizeof(printlisttype))) == NULL) {
       perror("firstpage");
       exit(1);
   }
   firstpage->all = FALSE;
   firstpage->nxt = nil;
   firstpage->pag = 0;
   lastpage = firstpage;
   currentpage = firstpage;
   if (getinteger(&num, &j, str))
       usage(nan);
   plcnxt((int) num);
   while (str[j]) {
       c = str[j];
       if (c == ',' || c == ':') {
           j++;
           if (getinteger(&num, &j, str))
               usage(nan);
       }
       else
           break;
       if (c == ',')
           plcnxt(num);
       else {
           if (currentpage->pag < 0) {
               if (num > 0) {
                   currentpage->all = TRUE;
                   plcnxt(num);
               }
               else if (num < currentpage->pag)
                   for (i = currentpage->pag - 1; i >= num; i--)
                       plcnxt(i);
               else
                   usage(bdlst);
           }
           else {
               if (num < currentpage->pag)
                   usage(bdlst);
               for (i = currentpage->pag + 1; i <= num; i++)
                   plcnxt(i);
           }
       }
   }
   if ((str[j] != ' ') && (str[j] != '\0')) {
       usage(gae);
   }
   currentpage = firstpage;

   return;

} /* getpages */



/*
* PLCNXT -- Place page-nr next in list.
*/

void plcnxt(int pagnr)
{

   currentpage = lastpage;
   currentpage->pag = pagnr;
   if ((lastpage = (printlisttype *) malloc(sizeof(printlisttype))) == NULL) {
       perror("lastpage");
       exit(1);
   }
   lastpage->all = FALSE;
   lastpage->nxt = nil;
   lastpage->pag = 0;
   currentpage->nxt = lastpage;

   return;

} /* plcnxt */



/*
* GETFNAME -- {Make sure we have a .dvi filename.
*/

void getfname(const char *str)
{
   int   i;

   i = strlen(str);
   if (i == 0)
       usage(ign);
   if ((DVIfilename = (char *) malloc(i+5)) == NULL) {
       perror("DVIfilename");
       exit(1);
   }
   strcpy(DVIfilename, str);
#ifdef KPATHSEA
   if (!kpse_readable_file(DVIfilename))
#else
   if ((i < 5) || strcmp(str+i-4, ".dvi"))
#endif
       strcat(DVIfilename, ".dvi");

   return;

} /* getfname */




/*
* GETINTEGER -- Convert ascii to an integer. I'm sure there is a library
*               call for it.
*/

int getinteger(int *dest, int *j, const char *str)
{
   int  cum;
   int  sgn;
   char ch;

   ch = str[*j];
   if (ch == '-') {
       sgn = -1;
       ch  = str[++(*j)];
   }
   else
       sgn = 1;

   if ((ch >= '0') && (ch <= '9')) {
       cum = 0;
       while ((ch >= '0') && (ch <= '9')) {
           cum = cum*10 + ch - '0';
           ch = str[++(*j)];
       }
       *dest = sgn * cum;

       return 0;                   /* return ok */
   }

   return 1;                       /* return error */

}   /* getinteger */



/*
* GETLONG -- Convert ascii to a long. I'm sure there is a library
*            call for it.
*/

int getlong(long *dest, int *j, const char *str)
{
   long  cum;
   int  sgn;
   char ch;

   ch = str[*j];
   if (ch == '-') {
       sgn = -1;
       ch  = str[++(*j)];
   }
   else
       sgn = 1;

   if ((ch >= '0') && (ch <= '9')) {
       cum = 0;
       while ((ch >= '0') && (ch <= '9')) {
           cum = cum*10L + ch - '0';
           ch = str[++(*j)];
       }
       *dest = (long) sgn * cum;

       return 0;                   /* return ok */
   }

   return 1;                       /* return error */

}   /* getinteger */



/*
* ERROREXIT -- Exit program with an erro message.
*/

void errorexit(int errorcode)
{

   fprintf(stderr, "%s: ", progname);
   switch (errorcode) {
       case  illop : fprintf(stderr, "Illegal op-code found: %d\n", opcode);
                     break;
       case  stkof : fprintf(stderr, "Stack overflow\n");
                     break;
       case  stkuf : fprintf(stderr, "Stack underflow\n");
                     break;
       case  stkrq : fprintf(stderr, "Cannot create dvi stack\n");
                     break;
       case  lnerq : fprintf(stderr, "Cannot allocate memory\n");
                     break;
       case  badid : fprintf(stderr, "Id-byte is not correct: %d\n ", opcode);
                     break;
       case  bdsgn : fprintf(stderr, "Bad signature: %d (not 223)\n",
                                     (int) foo);
                     break;
       case  fwsgn : fprintf(stderr, "%d signature bytes (min. 4)\n",
                                     (int) foo);
                     break;
       case  nopre : fprintf(stderr, "Missing preamble\n");
                     break;
       case  nobop : fprintf(stderr, "Missing beginning-of-page command\n");
                     break;
       case  nopp  : fprintf(stderr, "Missing post-post command\n");
                     break;
       case  bdpre : fprintf(stderr, "Preamble occured inside a page\n");
                     break;
       case  bdbop : fprintf(stderr, "BOP-command occured inside a page\n");
                     break;
       case  bdpst : fprintf(stderr, "Postamble occured before end-of-page\n");
                     break;
       case  bdpp  : fprintf(stderr, "Postpost occured before post-command\n");
                     break;
       case  nopst : fprintf(stderr, "Missing postamble\n");
                     break;
       case  illch : fprintf(stderr, "Character code out of range, 0..127\n");
                     break;
       case  filop : fprintf(stderr, "Cannot open dvifile\n");
                     break;
       case  filcr : fprintf(stderr, "Cannot create outfile\n");
                     break;
#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C) && !defined(AMIGA)
       case  pipcr : fprintf(stderr, "Cannot create pipe to pager\n");
                     break;
#endif
       default     : fprintf(stderr, "Unkown error code\n");
                     break;
   };
   if (outputtofile)
#if defined(VMS)
       remove(OUTfilename);
#else
       unlink(OUTfilename);
#endif

   exit(errorcode);

}  /* errorexit */



/*
* USAGE -- Print the usage info. Also print a warning/error message
*          if needed.
*/

void usage(int uerr)
{

   if (jautodetect || nttj || asciip || uptex)
       fprintf(stderr, "%s (%s) %s", Progname, get_enc_string(), Copyright);
   else
       fprintf(stderr, "%s  %s", Progname, Copyright);

   if (uerr != ign) {
       fprintf(stderr,"\n%s: ", progname);
       switch (uerr) {
           case   wrnge  : fprintf(stderr, "width arg out of range:16-%d",
                                           MAXTERMWIDTH);
                           break;
           case   nan    : fprintf(stderr,
                                   "numeric argument expected for option %c",
                                           optch);
                           break;
           case   gae    : fprintf(stderr, "garbage in argument for option %c",
                                           optch);
                           break;
           case   bdlst  : fprintf(stderr, "mal-formed list of pagenumbers");
                           break;
           case   onef   : fprintf(stderr, "only one infile argument allowed");
                           break;
           case   noarg  : fprintf(stderr,
                                   "option argument expected for option %c",
                                           optch);
                           break;
           case   bdopt  : fprintf(stderr, "bad option %c", optch);
                           break;
           case   onepp  : fprintf(stderr, "only one pagelist allowed");
                           break;
           case   confl  : fprintf(stderr, "-J, -N, -A, and -U are mutually exclusive");
                           break;
           case   incone : fprintf(stderr, "output encoding is not consistent");
                           break;
#if defined(THINK_C)
           case   nored  : fprintf(stderr, "\nIf no input file is given in\
command string,\n\Standard Input must be redirected with the radio button.");
                           break;
#endif
           default       : fprintf(stderr, "unknown usage error");
                           break;
       }
       fprintf(stderr, "\n");
   }

   fprintf(stderr, "\n%s\n\n", dvi2tty);
#if defined(THINK_C)
   fprintf(stderr, "Usage: %s [ options ] [<dvi-file>[.dvi]]\n", progname);
   fprintf(stderr, "Read input from <dvi-file>, else read from Standard Input,\
\nwhich must be redirected by means of the radio button.\n");
#else
   fprintf(stderr, "Usage: %s [ options ] <dvi-file>[.dvi]\n", progname);
#endif
   fprintf(stderr, "Options are:\n");
   fprintf(stderr,
           " -ofile   Write output to file, else write to stdout.\n");
   fprintf(stderr,
           " -plist   Print pages whose TeX-page-number are in list.\n");
   fprintf(stderr,
           " -Plist   Print pages whose sequential number are in list.\n");
   fprintf(stderr,
           " -wn      Print the lines with width n characters, default 80.\n");
   fprintf(stderr,
           " -vn      Use n for vertical line height, default 450000.\n");
   fprintf(stderr,
           " -evalue  Add/Substract this value for spacing (-20..20)\n");
#if !defined(MSDOS) && !defined(VMS) && !defined(THINK_C) && !defined(AMIGA)
   fprintf(stderr, " -f       Try to pipe to a pager if output is a tty");
   if (WANTPAGER)
       fprintf(stderr, " (default).\n");
   else
       fprintf(stderr, ".\n");
   fprintf(stderr, " -q       Don't try to pipe to a pager");
   if (WANTPAGER)
       fprintf(stderr, ".\n");
   else
       fprintf(stderr, " (default).\n");
   fprintf(stderr, " -Fprog   Pipe output to pager prog.\n");
#endif
   fprintf(stderr,
           " -a       Remove accents grave etc. from output: \\'{e} -> e.\n");
   fprintf(stderr,
           " -t       Assuming that document was made with tt fonts\n");
   fprintf(stderr,
           " -l       Write ''^L'' instead of formfeed between pages.\n");
   fprintf(stderr,
           " -s       Toggle National Swedish/Finnish characters printed as aaoAAO (default %s).\n", DEFSCAND ? "off" : "on");
   fprintf(stderr,
           " -u       Toggle latin1 support (default %s).\n", DEFLATIN1 ? "on" : "off");
   fprintf(stderr,
           " -J       Enable auto detect for NTT JTeX, ASCII pTeX, and upTeX (japanese fonts).\n");
   fprintf(stderr,
           " -N       Support NTT JTeX dvi.\n");
   fprintf(stderr,
           " -A       Support ASCII pTeX dvi.\n");
   fprintf(stderr,
           " -U       Support upTeX dvi.\n");
   fprintf(stderr,
           " -Eenc    Output multibyte encoding. u:UTF8, e:EUC-JP s:Shift_JIS j:JIS\n"
           "                             u1:UTF8 (do not use ligature for ff,fi,fl,ffi,ffl).\n");
   fprintf(stderr,
           " -C       Don't try to compose a combining character sequence.\n");
   fprintf(stderr,
           " -c       Override -a -u -s and print all characters 0-255.\n");
   fprintf(stderr,
           " -bdelim  Print font switch as text: delimcmr10miled\n");
   fprintf(stderr, " -h       This help message.\n");
   fprintf(stderr, "\n If you like this code and want to support is feel free\n to donate at Paypal [email protected]. Thanks.\n\n");


   exit(uerr);

} /* usage */