<commit_before>// -*- C++ -*-
/**
 * @file parse.yy
 *
 * Parser for %MaRC input files.  Requires GNU Bison 1.35 or greater.
 *
 * Copyright (C) 1999, 2004, 2017-2018  <NAME>
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * @author <NAME>
 */

%{
// SourceImage factories
#include "PhotoImageFactory.h"
#include "MosaicImageFactory.h"
#include "MuImageFactory.h"
#include "Mu0ImageFactory.h"
#include "CosPhaseImageFactory.h"
#include "LatitudeImageFactory.h"
#include "LongitudeImageFactory.h"

// BodyData strategies
#include <marc/OblateSpheroid.h>

// Image parameters
#include <marc/PhotoImageParameters.h>
#include <marc/ViewingGeometry.h>

// Map Strategies
#include <marc/Mercator.h>
#include <marc/Orthographic.h>
#include <marc/PolarStereographic.h>
#include <marc/SimpleCylindrical.h>

#include <marc/Constants.h>
#include <marc/DefaultConfiguration.h>

#include <marc/Log.h>
#include <marc/utility.h>

#include "parse_scan.h"
#include "parse.hh"
#include "lexer.hh"
#include "calc.h"
#include "strerror.h"
#include "MapCommand.h"
#include "FITS_traits.h"

#include <stdexcept>
#include <limits>
#include <memory>
#include <cstring>
#include <cerrno>
#include <cmath>
#include <sstream>


YY_DECL;

namespace
{
    void yyerror(YYLTYPE * locp,
                 yyscan_t /* scanner */,
                 MaRC::ParseParameter & pp,
                 char const * msg)
    {
        /**
         * @bug The line number is off when the parser explicitly
         *      calls @c yyerror().  For example, if a negative
         *      KM_PER_PIXEL value is set in an input file the
         *      reported line is actually the first line that isn't
         *      solely whitespace after the line containing the
         *      invalid KM_PER_PIXEL value.  Line numbers in syntax
         *      errors, on the other hand, are correct
         */
        MaRC::error("{}:{}:{}: {}",
                    pp.filename,
                    locp->first_line,
                    locp->first_column,
                    msg);
    }

    static constexpr double not_a_number =
        std::numeric_limits<double>::signaling_NaN();

    /**
     * @brief Get angle within 360 degree (circle) range.
     *
     * Determine the angle in the [0,360) (circle) range equivalent to
     * the provided @a angle.  For example, given an @a angle of -365
     * degrees, the equivalent angle in the [0,360) range would be 355
     * degrees.
     *
     * @param[in] angle Angle in degrees to be placed in 360 degree
     *                  range.
     *
     * @return Angle in [0,360) degree range equivalent to the
     *         provided @a angle.
     *
     * @todo Merge this function with similar generalized code used in
     *       @c MaRC::LongitudeImage::read_data_i().
     */
    inline double
    circle_angle(double angle)
    {
        constexpr int circle = 360;  // degrees

        // Place in the range [-360, 360].
        angle = std::fmod(angle, circle);

        // The sign of the first argument to std::fmod(), angle in
        // this case, is retained.  Shift to the [0, 360] range if
        // negative.
        return angle >= 0 ? angle : angle + circle;
    }

    /**
     * @brief Verify that the provided %FITS @c BLANK value actually
     *        fits within the chosen map data type.
     *
     * @tparam    T         Map data type.
     * @param[in] blank     %FITS @c BLANK value explicitly provided
     *                      by the user.  While it is of type
     *                      @c double here, it is ultimately stored as
     *                      an integer.
     * @param[in] data_type %MaRC map data type name (e.g. "BYTE",
     *                      "SHORT", etc).
     */
    template <typename T>
    bool
    verify_data_blank(MaRC::blank_type::value_type blank,
                      char const * data_type)
    {
        constexpr auto minimum = std::numeric_limits<T>::lowest();
        constexpr auto maximum = std::numeric_limits<T>::max();

        bool const verified = (blank >= minimum && blank <= maximum);

        if (!verified)
            MaRC::error("DATA_BLANK {} does not fit within "
                        "map data type {}",
                        blank,
                        data_type);

        return verified;
    }

    /**
     * @brief Convert string to integer.
     *
     * @param[in]  str String containing integer to be converted.
     * @param[out] end Pointer to first invalid character.
     * @param[out] num Integer converted from string @a str.
     *<commit_msg>parse: No need to verify blank for 64 bit int map.<commit_after>// -*- C++ -*-
/**
 * @file parse.yy
 *
 * Parser for %MaRC input files.  Requires GNU Bison 1.35 or greater.
 *
 * Copyright (C) 1999, 2004, 2017-2018  <NAME>
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * @author <NAME>
 */

%{
// SourceImage factories
#include "PhotoImageFactory.h"
#include "MosaicImageFactory.h"
#include "MuImageFactory.h"
#include "Mu0ImageFactory.h"
#include "CosPhaseImageFactory.h"
#include "LatitudeImageFactory.h"
#include "LongitudeImageFactory.h"

// BodyData strategies
#include <marc/OblateSpheroid.h>

// Image parameters
#include <marc/PhotoImageParameters.h>
#include <marc/ViewingGeometry.h>

// Map Strategies
#include <marc/Mercator.h>
#include <marc/Orthographic.h>
#include <marc/PolarStereographic.h>
#include <marc/SimpleCylindrical.h>

#include <marc/Constants.h>
#include <marc/DefaultConfiguration.h>

#include <marc/Log.h>
#include <marc/utility.h>

#include "parse_scan.h"
#include "parse.hh"
#include "lexer.hh"
#include "calc.h"
#include "strerror.h"
#include "MapCommand.h"
#include "FITS_traits.h"

#include <stdexcept>
#include <limits>
#include <memory>
#include <cstring>
#include <cerrno>
#include <cmath>
#include <sstream>


YY_DECL;

namespace
{
    void yyerror(YYLTYPE * locp,
                 yyscan_t /* scanner */,
                 MaRC::ParseParameter & pp,
                 char const * msg)
    {
        /**
         * @bug The line number is off when the parser explicitly
         *      calls @c yyerror().  For example, if a negative
         *      KM_PER_PIXEL value is set in an input file the
         *      reported line is actually the first line that isn't
         *      solely whitespace after the line containing the
         *      invalid KM_PER_PIXEL value.  Line numbers in syntax
         *      errors, on the other hand, are correct
         */
        MaRC::error("{}:{}:{}: {}",
                    pp.filename,
                    locp->first_line,
                    locp->first_column,
                    msg);
    }

    static constexpr double not_a_number =
        std::numeric_limits<double>::signaling_NaN();

    /**
     * @brief Get angle within 360 degree (circle) range.
     *
     * Determine the angle in the [0,360) (circle) range equivalent to
     * the provided @a angle.  For example, given an @a angle of -365
     * degrees, the equivalent angle in the [0,360) range would be 355
     * degrees.
     *
     * @param[in] angle Angle in degrees to be placed in 360 degree
     *                  range.
     *
     * @return Angle in [0,360) degree range equivalent to the
     *         provided @a angle.
     *
     * @todo Merge this function with similar generalized code used in
     *       @c MaRC::LongitudeImage::read_data_i().
     */
    inline double
    circle_angle(double angle)
    {
        constexpr int circle = 360;  // degrees

        // Place in the range [-360, 360].
        angle = std::fmod(angle, circle);

        // The sign of the first argument to std::fmod(), angle in
        // this case, is retained.  Shift to the [0, 360] range if
        // negative.
        return angle >= 0 ? angle : angle + circle;
    }

    /**
     * @struct blank_verifier
     *
     * @brief 32-bit, or smaller, blank integer value verifier.
     *
     * @tparam T Map integer data type.
     *
     * @see verify_data_blank()
     */
    template<typename T>
    struct blank_verifier
    {
        /**
         * @brief Verify that the provided %FITS @c BLANK value actually
         *        fits within the chosen map integer data type.
         *
         * @param[in] blank     %FITS @c BLANK value explicitly
         *                      provided by the user.
         * @param[in] data_type %MaRC map data type name (e.g. "BYTE",
         *                      "SHORT", or "LONG").
         *
         * @retval true  @a blank fits within chosen map integer data
         *               type.
         * @retval false @a blank is too large for chosen map integer
         *               data type.
         */
        static bool verify(MaRC::blank_type::value_type blank,
                           char const * data_type)
        {
            constexpr auto minimum = std::numeric_limits<T>::lowest();
            constexpr auto maximum = std::numeric_limits<T>::max();

            bool const verified = (blank >= minimum && blank <= maximum);

            if (!verified)
                MaRC::error("DATA_BLANK {} does not fit within "
                            "map data type {}",
                            blank,
                            data_type);

            return verified;
        }
    };

    /**
     * @struct blank_verifier<MaRC::FITS::longlong_type>
     *
     * @brief 64-bit blank integer value verifier specialization.
     *
     * In this case the 64-bit blank value always verifies since the
     * largest integer value supported by the %FITS standard is 64
     * bits wide.
     *
     * @see verify_data_blank()
     */
    template<>
    struct blank_verifier<MaRC::FITS::longlong_type>
    {
        /**
         * @brief Verify that the provided %FITS @c BLANK value actually
         *        fits within the chosen map integer data type.
         *
         * @param[in] blank     %FITS @c BLANK value explicitly
         *                      provided by the user.
         * @param[in] data_type %MaRC map data type name (e.g. "BYTE",
         *                      "SHORT", or "LONG").
         *
         * @retval true Verification always succeeds for the 64-bit
         *              integer typed maps.
         */

        static bool verify(MaRC::blank_type::value_type /* blank */,
                           char const * /* data_type */)
        {
            return true;
        }
    };

    /**
     * @brief Verify that the provided %FITS @c BLANK value actually
     *        fits within the chosen map data type.
     *
     * @tparam    T         Map data type.
     * @param[in] blank     %FITS @c BLANK value explicitly provided
     *                      by the user.  While it is of type
     *                      @c double here, it is ultimately stored as
     *                      an integer.
     * @param[in] data_type %MaRC map data type name (e.g. "BYTE",
     *                      "SHORT", etc).
     *
     * @retval true  @a blank fits within chosen map data type.
     * @retval false @a blank is too large for chosen map data type.
     */
    template<typename T>
    bool
    verify_data_blank(MaRC::blank_type::value_type blank,
                      char const * data_type)
    {
        return blank_verifier<T>::verify(blank, data_type);
    }

    /**
     * @brief Convert string to integer.
     *
     * @param[in]  str String containing integer to be converted.
     * @param[out] end Pointer to first invalid character.
     * @param[out] num Integer converted from string @a str.
     *
{'fraction_non_alphanumeric': 0.09816520863977704, 'fraction_numerical': 0.011767438259657816, 'mean_word_length': 2.0203413607668925, 'pattern_counts': {'":': 0, '<': 58, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4757189', 'n_tokens_mistral': 3832, 'n_tokens_neox': 3638, 'n_words': 1298}