/*
 * config - configuration routines
 *
 * Copyright (C) 1999-2007,2014,2021,2023  Landon Curt Noll and David I. Bell
 *
 * Primary author:  Landon Curt Noll
 *
 * Calc is open software; you can redistribute it and/or modify it under
 * the terms of the version 2.1 of the GNU Lesser General Public License
 * as published by the Free Software Foundation.
 *
 * Calc 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 Lesser General
 * Public License for more details.
 *
 * A copy of version 2.1 of the GNU Lesser General Public License is
 * distributed with calc under the filename COPYING-LGPL.  You should have
 * received a copy with calc; if not, write to Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * Under source code control:   1995/11/01 22:20:17
 * File existed as early as:    1995
 *
 * chongo <was here> /\oo/\     http://www.isthe.com/chongo/
 * Share and enjoy!  :-)        http://www.isthe.com/chongo/tech/comp/calc/
 */


#if !defined(INCLUDE_CONFIG_H)
#define INCLUDE_CONFIG_H


#if defined(CALC_SRC)   /* if we are building from the calc source tree */
# include "calc/decl.h"
# include "calc/nametype.h"
# include "calc/qmath.h"
#else
# include <calc/decl.h>
# include <calc/nametype.h>
# include <calc/qmath.h>
#endif


/*
 * configuration element types
 */
#define CONFIG_ALL      0       /* not a real configuration parameter */
#define CONFIG_MODE     1       /* types of configuration parameters */
#define CONFIG_DISPLAY  2
#define CONFIG_EPSILON  3
#define CONFIG_EPSILONPREC 3    /* not a real type -- tied to CONFIG_EPSILON */
#define CONFIG_TRACE    4
#define CONFIG_MAXPRINT 5
#define CONFIG_MUL2     6
#define CONFIG_SQ2      7
#define CONFIG_POW2     8
#define CONFIG_REDC2    9
#define CONFIG_TILDE    10
#define CONFIG_TAB      11
#define CONFIG_QUOMOD   12
#define CONFIG_QUO      13
#define CONFIG_MOD      14
#define CONFIG_SQRT     15
#define CONFIG_APPR     16
#define CONFIG_CFAPPR   17
#define CONFIG_CFSIM    18
#define CONFIG_OUTROUND 19
#define CONFIG_ROUND    20
#define CONFIG_LEADZERO 21
#define CONFIG_FULLZERO 22
#define CONFIG_MAXSCAN  23
#define CONFIG_PROMPT   24
#define CONFIG_MORE     25
#define CONFIG_BLKMAXPRINT 26
#define CONFIG_BLKVERBOSE 27
#define CONFIG_BLKBASE  28
#define CONFIG_BLKFMT   29
#define CONFIG_RESOURCE_DEBUG 30
#define CONFIG_LIB_DEBUG CONFIG_RESOURCE_DEBUG
#define CONFIG_CALC_DEBUG 31
#define CONFIG_USER_DEBUG 32
#define CONFIG_VERBOSE_QUIT 33
#define CONFIG_CTRL_D   34
#define CONFIG_PROGRAM  35
#define CONFIG_BASENAME 36
#define CONFIG_VERSION  37
#define CONFIG_WINDOWS  38
#define CONFIG_MODE2    39
#define CONFIG_CYGWIN   40
#define CONFIG_COMPILE_CUSTOM   41
#define CONFIG_ALLOW_CUSTOM     42
#define CONFIG_BASEB    43
#define CONFIG_REDECL_WARN      44
#define CONFIG_DUPVAR_WARN      45
#define CONFIG_HZ       46
#define CONFIG_TILDE_SPACE      47
#define CONFIG_FRACTION_SPACE   48
#define CONFIG_COMPLEX_SPACE    49
#define CONFIG_TRIGROUND        50


/*
 * config default symbols
 */
#define DISPLAY_DEFAULT 20      /* default digits for float display */
#define EPSILON_DEFAULT "1e-20" /* allowed error for float calculations */
#define EPSILONPREC_DEFAULT 67  /* 67 ==> 2^-67 <= EPSILON_DEFAULT < 2^-66 */
#define MAXPRINT_DEFAULT 16     /* default number of elements printed */
#define MAXSCANCOUNT 20         /* default max scan errors before an abort */


/*
 * configuration object
 *
 * If you add elements to this structure, you need to also update:
 *
 *      quickhash.c     - config_hash()
 *      hash.c          - hash_value()
 *      config.c        - configs[], oldstd, newstd, setconfig(),
 *                        config_value(), config_cmp(),
 *                        and perhaps config_copy(), config_free()
 *      config.h        - CONFIG_XYZ_SYMBOL (see above)
 *      help/config     - document new config option
 */
struct config {
        int outmode;            /* current output mode */
        int outmode2;           /* current secondary output mode */
        LEN outdigits;          /* current output digits for float or exp */
        NUMBER *epsilon;        /* default error for real functions */
        long epsilonprec;       /* epsilon binary precision (tied to epsilon) */
        FLAG traceflags;        /* tracing flags */
        LEN maxprint;           /* number of elements to print */
        LEN mul2;               /* size of number to use multiply algorithm 2 */
        LEN sq2;                /* size of number to use square algorithm 2 */
        LEN pow2;               /* size of modulus to use REDC for powers */
        LEN redc2;              /* size of modulus to use REDC algorithm 2 */
        bool tilde_ok;          /* OK to print a tilde on approximations */
        bool tilde_space;       /* print space after tilde on approximations */
        bool fraction_space;    /* true => print spaces around / in fractions */
        bool complex_space;     /* true => print spaces around + or - in complex values */
        bool tab_ok;            /* OK to print tab before numeric values */
        LEN quomod;             /* quomod() default rounding mode */
        LEN quo;                /* quotient // default rounding mode */
        LEN mod;                /* mod % default rounding mode */
        LEN sqrt;               /* sqrt() default rounding mode */
        LEN appr;               /* appr() default rounding mode */
        LEN cfappr;             /* cfappr() default rounding mode */
        LEN cfsim;              /* cfsim() default rounding mode */
        LEN outround;           /* output default rounding mode */
        LEN round;              /* round()/bround() default rounding mode */
        LEN triground;          /* trigonometric and hyperbolic function rounding mode */
        bool leadzero;          /* OK to print leading 0 before decimal pt */
        bool fullzero;          /* OK to print trailing 0's */
        long maxscancount;      /* max scan errors before abort */
        char *prompt1;          /* normal prompt */
        char *prompt2;          /* prompt when inside multi-line input */
        int blkmaxprint;        /* octets of a block to print, 0 => all */
        bool blkverbose;        /* true => print all lines if a block */
        int blkbase;            /* block output base */
        int blkfmt;             /* block output style */
        long calc_debug;        /* internal debug, see CALC_DEBUG_XYZ below */
        long resource_debug;    /* resource debug, see RSCDBG_XYZ below */
        long user_debug;        /* user defined debug value: 0 default */
        bool verbose_quit;      /* true => print Quit or abort executed msg */
        int ctrl_d;             /* see CTRL_D_xyz below */
        char *program;          /* our name */
        char *base_name;        /* basename of our name */
        bool windows;           /* true => running under MS windows */
        bool cygwin;            /* true => compiled with cygwin */
        bool compile_custom;    /* true => compiled with -DCUSTOM */
        bool *allow_custom;     /* ptr to if custom functions are allowed */
        char *version;          /* calc version string */
        int baseb;              /* base for calculations */
        bool redecl_warn;       /* true => warn of redeclaring variables */
        bool dupvar_warn;       /* true => warn of var name collisions */
};
typedef struct config CONFIG;


/*
 * resource_debug bit masks
 */
#define RSCDBG_STDIN_FUNC   (0x00000001)    /* interactive func define debug */
#define RSCDBG_FILE_FUNC    (0x00000002)    /* file read func define debug */
#define RSCDBG_FUNC_INFO    (0x00000004)    /* print extra info for show func */
#define RSCDBG_PRINT_DBG    (0x00000008)    /* print debug messages */
#define RSCDBG_MASK         (0x0000000f)


/*
 * calc_debug bit masks
 */
#define CALCDBG_SYSTEM      (0x00000001)    /* print system cmd prior to exec */
#define CALCDBG_FUNC_QUIT   (0x00000002)    /* active functions when quit */
#define CALCDBG_HASH_STATE  (0x00000004)    /* hash state details */
#define CALCDBG_BLOCK       (0x00000008)    /* block debug */
#define CALCDBG_TTY         (0x00000010)    /* report TTY state changes */
#define CALCDBG_RUNSTATE    (0x00000020)    /* report run_state changes */
#define CALCDBG_RAND        (0x00000040)    /* report rand() activity */
#define CALCDBG_CUSTOM      (0x00000080)    /* custom function debug */
#define CALCDBG_MASK        (0x000000ff)

/*
 * ctrl-d meanings
 */
#define CTRL_D_VIRGIN_EOF  (0)  /* ^D only exits on virgin command lines */
#define CTRL_D_NEVER_EOF   (1)  /* ^D never exits, emacs binding meaning only */
#define CTRL_D_EMPTY_EOF   (2)  /* ^D always exits at start of line */


/*
 * global configuration states and aliases
 */
EXTERN CONFIG *conf;    /* current configuration */
EXTERN CONFIG oldstd;   /* old classic standard configuration */
EXTERN CONFIG newstd;   /* default compatible configuration */
E_FUNC char *calc_debug;        /* !=NULL => value of config("calc_debug") */
E_FUNC char *resource_debug; /* !=NULL => config("resource_debug") value */
E_FUNC char *user_debug;        /* !=NULL => value of config("user_debug") */


/*
 * configuration externals
 */
E_FUNC CONFIG *config_copy(CONFIG *src);
E_FUNC void config_free(CONFIG *cfg);
E_FUNC void config_print(CONFIG *cfg);
E_FUNC int configtype(char*);
E_FUNC void config_print(CONFIG*);
E_FUNC bool config_cmp(CONFIG*, CONFIG*);


#endif /* !INCLUDE_CONFIG_H */
