                        /* global.h, 29 Mar 13 */

#include "../config.h"

#if __MINGW32__
#define MS_DOS 1
#undef HAVE_FNMATCH_H
#endif

#include <limits.h>

#if HAVE_GMP 
    #include <gmp.h>
    typedef mpf_t fp_t;    
    #define FP_ARITHMETIC  "multiple-precision arithmetic"
#elif HAVE_LONG_DOUBLE
    typedef long double fp_t;
    #define FP_ARITHMETIC  "long double-precision arithmetic"
#else
    typedef double fp_t;   
    #define FP_ARITHMETIC  "double-precision arithmetic"
#endif

#if HAVE_ARCHIVE_H
  #define ARCHIVE_STR "with archive support"
#else
  #define ARCHIVE_STR "no archive support"
#endif

#if defined(FULL_POSIX)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/* check file is:
        a regular file (not a directory etc)
        accessible for execution
*/
#define ISEXECUTABLE(file)      (stat(file,&ISexec),                    \
                                        (S_ISREG(ISexec.st_mode)) &&    \
                                        (access(file, X_OK) == 0))
#endif

#define GETVAR(var)      getenv(var)

#define MAX_WORD_LEN 80

// We want this to be no more than the maximum number of
// digits usually stored in the interesting number database.
#define MAX_NUM_DIGITS 40
#define MAX_MSG_LEN 120
#define DFLT_NEED_SIZE 15

#define FALSE 0
#define TRUE 1

#ifndef MAX_PATHNAME_LEN
#define MAX_PATHNAME_LEN 256      /* Maximum length of a path */
#endif

#ifdef NAME_MAX /* chars in the base filename */
   #define MAX_BASE_FILE_LEN (NAME_MAX)
#elif defined _POSIX_NAME_MAX
   #define MAX_BASE_FILE_LEN (_POSIX_NAME_MAX)
#else
   #define MAX_BASE_FILE_LEN 64
#endif

#define MAX_FILENAME_LEN (MAX_PATHNAME_LEN+MAX_BASE_FILE_LEN)

#if MS_DOS
#define path_separator      ";"  /* string to separate several paths */
#define directory_separator "\\"  /* string to separate directories */
#define Cur_Dir_Str         ".\\"
#else
#define path_separator      ":"  /* string to separate several paths */
#define directory_separator "/"  /* string to separate directories */
#define Cur_Dir_Str         "./"
#endif

#define DSEP_LEN 1
#define extension_separator "."  /* obvious ! */
#define device_separator    ":"  /* separate device from path */

/* environment variable used to find path information (prior to reading cfg) */
#ifndef PATHVAR
#define PATHVAR         "PATH"
#endif

#define NULL_CHAR '\0'
#define DP_CHAR '.'

#define DB_DIR "ndb/"
#define DEFAULT_DB "default.txt"


#if HAVE__BOOL
typedef _Bool BOOL;
#else
typedef unsigned char BOOL;
#endif

typedef char DIGIT_CHAR;
typedef char CHAR;

enum match_enum {NOT_SEEN = 0x00,
		 NO_MATCH = 0x01,
		 NDB_MATCH = 0x02,
		 EXACT_SIGNIF = 0x04,
		 LEV_SIGNIF = 0x10,
		 VALUE_MATCH = 0x20,
		 NEED_MATCH = 0x40};

#define enum_eq(numeric_val, enum_val)  (((numeric_val) & enum_val) == enum_val)
#define enum_ne(numeric_val, enum_val)  (((numeric_val) & enum_val) != enum_val)

/*
 * Information on a numeric value read from a ndb file.
 * Multiple occurrences of the same numeric value each have a unique num_db_rec.
 */
struct num_db_rec {
	short need_num; // the n'th number in a given need sequence
	short len_mantissa;
	short simp_mant_len;
	DIGIT_CHAR *mantissa;
	DIGIT_CHAR *simp_mant;
	DIGIT_CHAR *exponent;
	fp_t num_valu;
	fp_t match_fuzz;  // fuzz value used when matching this value
	CHAR *msg;
	CHAR *ndb_title;
	struct need_num_rec *need_info;
	struct num_db_rec *next;
	};

struct num_db {
	struct num_db_rec *num_info[10];
	};

struct need_num_rec {
	short list_len;     // Number of values in need list
	short max_list_len; // Current entries + free space
	short num_mantissa_matches; // Mantissa only matches
	int need_id;        // Value common to all numbers in a need sequence
	int notify_level;   // TODO
	CHAR *msg;          // Message belongs to need sequence
	CHAR *ndb_title;
	short *seen_need_num;
	struct num_db_rec **num_list;
	};

/*
 * Information on literal values we have encountered
 */
struct num_seen_rec {
	short len_mantissa;
	enum match_enum  match_kind;
	int need_id; // Value common to all numbers in a need sequence
	int total_occurrences;
	int file_occurrences; // Occurrences in the current file
	DIGIT_CHAR *mantissa;
	DIGIT_CHAR *exponent;
	fp_t seen_valu;
	struct num_db_rec *matched_num; // pointer to matched ndb value
	struct num_seen_rec *next; // linked list of all seen recs
	};

struct num_seen {
	struct num_seen_rec *num_info[10];
	};

extern BOOL do_trace_input;
extern BOOL do_trace_progress;
extern int match_signif_digits;
extern int ndb_signif_digits;
extern int print_signif_digits;
extern int max_words;
extern struct num_db special_numbers;

