/* GENERATED by Makefile.in */
/* DO NOT EDIT */
#ifndef UNITY_H_LOADED
#define UNITY_H_LOADED 1
/* From known-syntaxes.h */
#ifndef KNOWN_SYNTAXES_H
#define KNOWN_SYNTAXES_H 1

/**
 * Constants for the various syntaxes which the library knows about.
 */
typedef enum {
    /**
     * Indicates the 'FITS' syntax.
     * Parses unit strings according to the prescriptions in the
     * FITS specification, v3.0, section 4.3
     * (W.D. Pence et al., A&amp;A 524, A42, 2010. 
     * <a href='http://dx.doi.org/10.1051/0004-6361/201015362'
     *    >doi:10.1051/0004-6361/201015362</a>).
     * @see #unity_identify_parser
     */
    UNITY_SYNTAX_FITS,
    /**
     * Indicates the 'OGIP' syntax.
     * The format defined in OGIP memo OGIP/93-001, 1993
     * (<a href='ftp://legacy.gsfc.nasa.gov/fits_info/fits_formats/docs/general/ogip_93_001/ogip_93_001.ps'
     *    >postscript via FTP</a>)
     * @see #unity_identify_parser
     */
    UNITY_SYNTAX_OGIP,
    /**
     * Indicates the 'CDS' syntax.
     * A syntax based on the CDS document
     * <em>Standards for Astronomical Catalogues, Version 2.0</em>, 2000,
     * specifically section 3.2.  
     * See <a href='http://cdsweb.u-strasbg.fr/doc/catstd-3.2.htx'
     *     ><code>http://cdsweb.u-strasbg.fr/doc/catstd-3.2.htx</code></a>
     * @see #unity_identify_parser
     */
    UNITY_SYNTAX_CDS,
    /**
     * Indicates the 'VOUNITS' syntax.
     * This is intended to be
     * as nearly as possible in the intersection of the various
     * other grammars. It is a strict subset of the FITS and CDS
     * grammars (in the sense that any VOUnit unit string is a valid
     * FITS and CDS string, too), and it is almost a subset of the
     * OGIP grammar, except that it uses the dot for multiplication
     * rather than star.  See <a
     * href='http://ivoa.net/Documents/VOUnits/' >IVOA VOUnits
     * Proposed Recommendation</a>.
     * @see #unity_identify_parser
     */
    UNITY_SYNTAX_VOUNITS,
    /**
     * Indicates the 'LaTeX' syntax.
     * This produces output which is intended to be used with the
     * LaTeX 'siunitx' package.
     * This is for writing only.
     */
    UNITY_SYNTAX_LATEX,
    /** 
     * The formatter (not parser) for debugging output.  This is
     * intended to display the results of a parse unambiguously.  The
     * format of the output is not specified, and may change without
     * notice.
     */
    UNITY_SYNTAX_DEBUG,
    /**
     * A non-syntax.  This is an error return value.
     */
    UNITY_SYNTAX_NONE,
} UnitySyntax;

#if 0
/* XXX DELETE */
#ifdef UNITY_INTERNAL
/* Number of syntaxes */
#define U_NSYNTAXES 6
#endif
#endif

#endif /* KNOWN_SYNTAXES_H */

/* From function-definitions.h ... */
#ifndef FUNCTION_DEFINITIONS_H
#define FUNCTION_DEFINITIONS_H 1


/* The functions exported by this module are the only ones which need
 * access to the data structures dumped into this file, which are
 * potentially subject to change.  The implementation of this header
 * file is generated by ../grammar/ParseFunctions.java, using the
 * function-definitions.c.template file in that directory.
 *
 * The structure elements with leading underscores are intended to be internal to
 * this function-definition.c module.
 */

/**
 * Represents the definition of a known function
 */
struct function_definition {
    /** A text description of the function */
    const char* description;
    /** The LaTeX representation of the function (eg "\log") */
    const char* latex_form; 
};
typedef struct function_definition FunctionDef;

const FunctionDef* unity_get_functiondef_from_string(const char* abbrev, UnitySyntax syntax);
const char* unity_get_function_abbreviation(const FunctionDef* def, UnitySyntax syntax);

#endif /* FUNCTION_DEFINITIONS_H */
/* ...end function-definitions.h */

/* From unit-definitions.h ... */
#ifndef UNIT_DEFINITIONS_H
#define UNIT_DEFINITIONS_H 1


/* The functions exported by this module are the only ones which need
 * access to the data structures dumped into this file, which are
 * potentially subject to change.  The implementation of this header
 * file is generated by ../grammar/ParseUnits.java, using the
 * unit-definitions.c.template file in that directory.
 *
 * The structure elements with leading underscores are intended to be internal to
 * this unit-definition.c module.
*/

/**
 * Encapsulates per-syntax information about a unit.  This should be
 * regarded as an opaque type, and instances of it, and its contents,
 * should be obtained using the various <code>unity_get_unit...</code>
 * functions.
 */
typedef struct {
    const char* uri;            /* the name for this unit, as a URI */
    int _idx;                   /* the internal index for this unit, in the list of unit_definition entries */
    const char* name; /* the name of the unit, such as 'Metre' -- not the abbreviation 'm' */
    const char* type; /* type such as 'length', as a URI */
    const char* dimension; /* the dimensions of this unit, as a string, eg "M L-2" */
    const char* description; /* for example 'Hz = s-1', NULL if no notes present */
    const char* latex_form; /* an abbrev suitable for LaTeX, if different from a preferred syntax */
} UnitDef;

//typedef struct unit_definition UnitDef;

#if UNITY_INTERNAL
/* A unit_representation indicates how a particular unit may be used in a particular syntax. */
struct unit_representation {
    const char* symbol;         /* a symbol for this unit, in one syntax */
    int _unit_index;            /* the index in the array of unit_definition entries */
    int si_prefixes_p;          /* true if this unit may be given SI prefixes */
    int binary_prefixes_p;      /* true if this unit may be given binary prefixes */
    int is_deprecated_p;        /* true if this unit is deprecated */
    int is_preferred_p;         /* true if this unit is the preferred unit amongst some alternatives */
};
typedef struct unit_representation UnitRep;
UnitRep* u_get_unit_representation(const UnitDef*, UnitySyntax syntax);
UnitRep* u_get_unit_representation_any(const UnitDef*);
#endif

const UnitDef* unity_get_unitdef_from_string(const char* abbrev, UnitySyntax syntax);
const char* unity_get_syntax_name(UnitySyntax syntax);
const char* unity_get_unit_uri(const UnitDef*);
const char* unity_get_unit_name(const UnitDef*);
const char* unity_get_unit_type(const UnitDef*);
const char* unity_get_unit_dimension(const UnitDef*);
const char* unity_get_unit_description(const UnitDef*);
const char* unity_get_unit_latex_form(const UnitDef*);
#endif /* UNIT_DEFINITIONS_H */
/* ...end unit-definitions.h */

/* From unitylib.h ... */
#ifndef UNITYLIB_H_LOADED
#define UNITYLIB_H_LOADED 1

/**
 * @file unity.h
 */


/** @struct UnitExpression
 * The parsed version of a unit string.
 */
typedef struct {
    /**
     * The base-10 log of the numerical factor at the head of the string.
     * For some parsers, this is restricted to round powers of ten.
     */
    float log_factor;
    /**
     * The sequence of units which comprise the parsed units specification.
     */
    const struct unit_struct* unit_sequence;

    /* a sorted version of the unit_sequence */
    struct unit_struct** sorted_unit_sequence;
    int nunits;
} UnitExpression;

/** @struct FunctionApplication
 * A unit corresponding to an application of a function to a unit
 * sequence.  In the case of <code>log(V^2/Hz)</code>, for example, the function
 * is ‘log’ and the operand is the parsed units corresponding to
 * ‘V^2/Hz’.
 */
typedef struct {
    /** The definition of the function used.
     * Precisely one of definition and name should be non-null */
    const struct function_definition* definition;
    /** The name of an unrecognised function used.
     * Precisely one of definition and name should be non-null */
    const char* name;
    /** The parsed units to which the function is applied. */
    //const struct unit_struct* operand;
    UnitExpression operand;
} FunctionApplication;

/** @struct SimpleUnit
 * A simple unit, corresponding to, for example, ‘MHz’.
 */
typedef struct {
    /**
     * The base-10 logarithm of the prefix in front of the unit.  For
     * example, this will be ‘-3’ for the ‘m’ (milli-) prefix.
     */
    int prefix_power;           /* -24 to +24 */
    /**
     * True (non-zero) if the prefix is a power of 10;
     * false if it's a power of 2.
     */
    char base10_p;
    /**
     * The base unit of this unit specification, as a known unit.  If
     * this is not a known unit (in the syntax which parsed the
     * associated expression) then this will be NULL.
     */
    const UnitDef* base_unit_def;
    /**
     * The base unit of this unit specification.  This might be ‘m’
     * for metres, ‘Hz’ for Hertz, and so on.
     */
    char* base_unit_string;     /* eg Hz or aangstrom */
} SimpleUnit;

/** An enumeration indicating the two types of unit possible in
 *  {@link unit_struct}
 */
typedef enum {
    /** Simple unit type (eg ‘MHz’) */
    simple_unit_type,
    /** Function-of unit type (eg <code>log(MHz)</code>) */
    function_application_type
} UnitTypes;

/** @struct unit_struct
 * A single parsed unit.  This can be either a simple unit
 * (corresponding to, for example, ‘MHz’) or a function of a sequence
 * of units (corresponding to, for example, <code>log(V^2/mHz)</code>).
 *
 * <p>A unit can be ‘quoted’, indicating that it is to be parsed
 * as an ‘unknown’ unit even if its name matches that of a ‘known’ unit
 * (for example, <code>'B'</code> is a unit of ‘B’, and neither byte
 * nor Bel, and the <code>'furlong'</code> is a ‘furlong’ and not, as
 * it would otherwise be parsed, a femto-urlong).
 * This mechanism is syntactically permitted only in the VOUnits syntax,
 * and is used only for output and validity checks
 * (see {@link unity_check_unit}), and not for processing.
 * All ‘quoted’ units are classed as not ‘recognised’.
 */
struct unit_struct {
    /**
     * The power to which the unit is raised.  The specification
     * <code>mm^(-2)</code> will result in a power of ‘-2’.
     */
    float power;
    /**
     * Indicates which type of unit this is.
     * If this is of type <code>simple_unit_type</code>, then the ‘u’ struct will be valid;
     * if it is of type <code>function_application_type</code>, then ‘f’ will be valid.
     */
    UnitTypes type;
    union {
        /** A contained simple unit */
        SimpleUnit u;
        /** A contained function-of unit */
        FunctionApplication f;
    };
    /** A pointer to the next unit in the sequence */
    struct unit_struct *next;

    /**
     * True (non-zero) if this unit was a ‘quoted’ unit.
     * This only makes sense for VOUnits units, and is used only when
     * writing out units rather than in any processing.
     */
    char is_quoted_unit;
};


/** A clearer name for struct unit_struct */
typedef struct unit_struct Unit;

const UnitExpression* unity_parse_string(const char* unit_string, const UnitySyntax syntax);

/* The function unity_parse_error is declared (and documented) here,
   and defined in lex.lex */
/**
 * Retrieve the most recent lexing or parsing error.  Immediately after
 * the parser has returned with an error (that is function
 * {@link #unity_parse_string} has returned NULL) this function can be called
 * to obtain an explanation.  However, a non-null response from this
 * function does not imply that the most recent call to `unity_parse_string' failed.
 *
 * <p>The returned string should not be freed by the caller.
 * @return a static string containing an explanation of a parse error
 */
const char* unity_parse_error(void);

const char** unity_parser_names(void);

UnitySyntax unity_identify_parser(const char* parser_name);
const char* unity_parser_name(const UnitySyntax parser_id);
void unity_free_expression(const UnitExpression* u);
const char* unity_version_string();
int unity_version_number();

/* Selecting units (convenience functions, since the UnitExpression struct is open */
const Unit* unity_get_unit_by_index(const UnitExpression*, int i);
const UnitDef* unity_get_unitdef_from_unit(const Unit*);
const FunctionDef* unity_get_functiondef_from_unit(const Unit*);

/* Checking units */
/** Flag: check whether the unit is recognised.  See {@link #unity_check_unit} */
#define UNITY_CHECK_RECOGNISED 1
/** Flag: check whether the unit is recommended.  See {@link #unity_check_unit} */
#define UNITY_CHECK_RECOMMENDED 2
/** Flag: check whether the unit is used in a way which satisfies constraints.  See {@link #unity_check_unit} */
#define UNITY_CHECK_CONSTRAINTS 4
/** Flag: perform all checks.
 * Do not rely on the numerical value of this or its related constants,
 * which may change between library versions without notice.
 * See {@link #unity_check_unit}
 */
#define UNITY_CHECK_ALL UNITY_CHECK_RECOGNISED | UNITY_CHECK_RECOMMENDED | UNITY_CHECK_CONSTRAINTS
int unity_check_unit(const Unit* u, const UnitySyntax syntax, const int flags);
int unity_check_expression(const UnitExpression* ue, const UnitySyntax syntax, const int flags);
int unity_equal_unit_p(const Unit*, const Unit*);
int unity_equal_expression_p(const UnitExpression*, const UnitExpression*);

#ifdef UNITY_INTERNAL
/* Internal functions */
Unit* u_new_unit(const char* unitString, const float power, const UnitySyntax syntax);
Unit* u_quoted_unit(const char* pfx, const char* unitString,
                    const float power, UnitySyntax syntax);
Unit* u_power_of_unit(Unit* u0, const float power);
Unit* u_function_application(const char* functionName,
                             const Unit* unit_sequence,
                             const UnitySyntax syntax);
Unit* u_unit_append(Unit* u1, const Unit* u2);
void u_receive_result(float, const Unit* unit_sequence);
int u_prefix_to_power(const char pfx);
Unit* u_divide_units(Unit* num, Unit* den);
Unit* u_unit_reciprocal(Unit* u);
void u_free_unit(const Unit* u);
Unit** u_get_sorted_unit_sequence(UnitExpression*, int*);
#endif

#endif
/* ...end unitylib.h */

/* From writers.h ... */
#ifndef WRITERS_H_LOADED
#define WRITERS_H_LOADED 1

#include <stdio.h>

#ifdef UNITY_INTERNAL
typedef struct {
    int nwritten;
    int len;
    char* buf;
} Buf;
typedef Buf* (*writef_ptr) (Buf*, const UnitExpression*);
#endif

char* unity_write_formatted(char* buf, int buflen, const UnitExpression*, UnitySyntax);
const char** unity_formatter_names(void);

#endif
/* ...end writers.h */
#endif
