dl-fldigi/src/config_script/script_parsing.h

471 wiersze
20 KiB
C++

//======================================================================
// script_parsing.h (FLDIGI)
//
// Author(s):
//
// Robert Stiles, KK5VD, Copyright (C) 2014
//
// This 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 3 of the License, or
// (at your option) any later version.
//
// This software 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, see <http://www.gnu.org/licenses/>.
// =====================================================================
#ifndef __script_parsing__
#define __script_parsing__
#include <string>
#include <stdio.h>
#ifdef __WIN32__
#define PATH_SEPERATOR "\\"
#define PATH_CHAR_SEPERATOR '\\'
#include <direct.h>
#define get_current_dir _getcwd
#else
#define PATH_SEPERATOR "/"
#define PATH_CHAR_SEPERATOR '/'
#include <unistd.h>
#define get_current_dir getcwd
#endif
#define MAX_CMD_PARAMETERS 5
#define MAX_COMMAND_LENGTH 128
#define MAX_PARAMETER_LENGTH FILENAME_MAX
#define MAX_READLINE_LENGTH (FILENAME_MAX+FILENAME_MAX)
#define MAX_SUB_SCRIPTS 5
#define SCRIPT_FILE_TAG ((char *)"FLDIGI_CONFIG")
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
#define RESET_ALL 0x01
#define RESET_PARTIAL 0X02
#undef __LOCALIZED_SCRIPT_COMMANDS
#ifdef __LOCALIZED_SCRIPT_COMMANDS
#pragma message ( \
"\n" \
"************************************************************************\n" \
"* Defining __LOCALIZED_SCRIPT_COMMANDS breaks script compatibility. In *\n" \
"* doing so, FLDIGI development team does not assume responsibility for *\n" \
"* maintaining the code sections that are altered/effected as a result. *\n" \
"************************************************************************\n" )
#define F_LOC(a) _(a)
#else
#define F_LOC(a) a
#endif
#define CMD_OPERATOR F_LOC("OPERATOR")
#define CMD_CALLSIGN F_LOC("CALLSIGN")
#define CMD_NAME F_LOC("NAME")
#define CMD_QTH F_LOC("QTH")
#define CMD_LOCATOR F_LOC("LOC")
#define CMD_ANTENNA F_LOC("ANT")
#define CMD_AUDIO_DEVICE F_LOC("AUDIO DEVICE")
#define CMD_OSS_AUDIO F_LOC("OSS")
#define CMD_OSS_AUDIO_DEV_PATH F_LOC("OSS DEV")
#define CMD_PORT_AUDIO F_LOC("PA")
#define CMD_PORTA_CAP F_LOC("PA CAPTURE")
#define CMD_PORTA_PLAY F_LOC("PA PLAYBACK")
#define CMD_PULSEA F_LOC("PUA")
#define CMD_PULSEA_SERVER F_LOC("PUA SERVER")
#define CMD_AUDIO_SETTINGS F_LOC("AUDIO SETTINGS")
#define CMD_CAPTURE_SAMPLE_RATE F_LOC("CAPTURE")
#define CMD_PLAYBACK_SAMPLE_RATE F_LOC("PLAYBACK")
#define CMD_AUDIO_CONVERTER F_LOC("CONVERTER")
#define CMD_RX_PPM F_LOC("RX PPM")
#define CMD_TX_PPM F_LOC("TX PPM")
#define CMD_TX_OFFSET F_LOC("TX OFFSET")
#define CMD_AUDIO_RT_CHANNEL F_LOC("AUDIO RT CHANNEL")
#define CMD_MONO_AUDIO F_LOC("MONO AUDIO")
#define CMD_AUDIO_L_R F_LOC("MODEM LR")
#define CMD_AUDIO_REV_L_R F_LOC("REV LR")
#define CMD_PTT_RIGHT_CHAN F_LOC("PTT RT CHAN")
#define CMD_CW_QSK_RT_CHAN F_LOC("QSK RT CHAN")
#define CMD_PSEUDO_FSK_RT_CHAN F_LOC("FSK RT CHAN")
#define CMD_AUDIO_WAVE F_LOC("AUDIO WAVE")
#define CMD_WAVE_SR F_LOC("SRATE")
#define CMD_HRDWR_PTT F_LOC("RIG HRDWR PTT")
#define CMD_HPPT_PTT_RT F_LOC("PTT RT CHAN")
#define CMD_HPTT_SP2 F_LOC("SERIAL PORT")
#define CMD_HPTT_SP2_PATH F_LOC("DEVICE")
#define CMD_HPTT_SP2_RTS F_LOC("RTS")
#define CMD_HPTT_SP2_DTR F_LOC("DTR")
#define CMD_HPTT_SP2_RTS_V F_LOC("RTSV")
#define CMD_HPTT_SP2_DTR_V F_LOC("DTRV")
#define CMD_HPTT_SP2_START_DELAY F_LOC("START PTT DELAY")
#define CMD_HPTT_SP2_END_DELAY F_LOC("END PTT DELAY")
#define CMD_HPTT_UHROUTER F_LOC("UHROUTER")
#define CMD_HPTT_PARALLEL F_LOC("PARALLEL")
#define CMD_HPTT_SP2_INITIALIZE F_LOC("INIT")
#define CMD_RIGCAT F_LOC("RIGCAT")
#define CMD_RIGCAT_STATE F_LOC("STATE")
#define CMD_RIGCAT_DESC_FILE F_LOC("DESC FILE")
#define CMD_RIGCAT_DEV_PATH F_LOC("DEV PATH")
#define CMD_RIGCAT_RETRIES F_LOC("RETRIES")
#define CMD_RIGCAT_RETRY_INTERVAL F_LOC("RETRY INT")
#define CMD_RIGCAT_WRITE_DELAY F_LOC("WDELAY")
#define CMD_RIGCAT_INTIAL_DELAY F_LOC("IDELAY")
#define CMD_RIGCAT_BAUD_RATE F_LOC("BRATE")
#define CMD_RIGCAT_STOP_BITS F_LOC("SBITS")
#define CMD_RIGCAT_ECHO F_LOC("ECHO")
#define CMD_RIGCAT_TOGGLE_RTS_PTT F_LOC("TOGGLE RTS PTT")
#define CMD_RIGCAT_TOGGLE_DTR_PTT F_LOC("TOGGLE DTR PTT")
#define CMD_RIGCAT_RESTORE F_LOC("RESTORE")
#define CMD_RIGCAT_PTT_COMMAND F_LOC("PTT COMMAND")
#define CMD_RIGCAT_RTS_12V F_LOC("RTS 12V")
#define CMD_RIGCAT_DTR_12V F_LOC("DTR 12V")
#define CMD_RIGCAT_HRDWR_FLOW F_LOC("HRDWR FC")
#define CMD_RIGCAT_VSP F_LOC("VSP")
#define CMD_RIGCAT_INITIALIZE F_LOC("INIT")
#define CMD_HAMLIB F_LOC("HAMLIB")
#define CMD_HAMLIB_STATE F_LOC("STATE")
#define CMD_HAMLIB_RIG F_LOC("RIG")
#define CMD_HAMLIB_DEV_PATH F_LOC("DEV PATH")
#define CMD_HAMLIB_RETRIES F_LOC("RETRIES")
#define CMD_HAMLIB_RETRY_INTERVAL F_LOC("RETRY INT")
#define CMD_HAMLIB_WRITE_DELAY F_LOC("WDELAY")
#define CMD_HAMLIB_POST_WRITE_DELAY F_LOC("PWDELAY")
#define CMD_HAMLIB_BAUD_RATE F_LOC("BRATE")
#define CMD_HAMLIB_STOP_BITS F_LOC("SBITS")
#define CMD_HAMLIB_SIDE_BAND F_LOC("SBAND")
#define CMD_HAMLIB_PTT_COMMAND F_LOC("PTT COMMAND")
#define CMD_HAMLIB_DTR_12V F_LOC("DTR 12V")
#define CMD_HAMLIB_RTS_12V F_LOC("RTS 12V")
#define CMD_HAMLIB_HRDWR_FLOW F_LOC("HRDWR FC")
#define CMD_HAMLIB_SFTWR_FLOW F_LOC("SFTWR FC")
#define CMD_HAMLIB_ADV_CONFIG F_LOC("ADV CONF")
#define CMD_HAMLIB_INITIALIZE F_LOC("INIT")
#define CMD_RC_XMLRPC F_LOC("XMLRPC RC")
#define CMD_RC_XMLRPC_STATE F_LOC("STATE")
#define CMD_RC_XMLRPC_BW_DELAY F_LOC("BWDELAY")
#define CMD_RC_XMLRPC_INITIALIZE F_LOC("INIT")
#define CMD_FLDIGI F_LOC("FLDIGI")
#define CMD_FLDIGI_FREQ F_LOC("FREQ")
#define CMD_FLDIGI_MODE F_LOC("MODE")
#define CMD_FLDIGI_WFHZ F_LOC("WFHZ")
#define CMD_FLDIGI_RXID F_LOC("RXID")
#define CMD_FLDIGI_TXID F_LOC("TXID")
#define CMD_FLDIGI_SPOT F_LOC("SPOT")
#define CMD_FLDIGI_REV F_LOC("REV")
#define CMD_FLDIGI_LOCK F_LOC("LOCK")
#define CMD_FLDIGI_AFC F_LOC("AFC")
#define CMD_FLDIGI_SQL F_LOC("SQL")
#define CMD_FLDIGI_KPSQL F_LOC("KPSQL")
#define CMD_FLDIGI_MODEM F_LOC("MODEM")
#define CMD_IO F_LOC("IO")
#define CMD_IO_LOCK F_LOC("LOCK")
#define CMD_IO_ACT_PORT F_LOC("PORT")
#define CMD_IO_AX25_DECODE F_LOC("AX25D")
#define CMD_IO_CSMA F_LOC("CSMA")
#define CMD_IO_KISS F_LOC("KISS")
#define CMD_IO_KISS_IPA F_LOC("IPA")
#define CMD_IO_KISS_IOPN F_LOC("IOPN")
#define CMD_IO_KISS_OPN F_LOC("OPN")
#define CMD_IO_KISS_DP F_LOC("DP")
#define CMD_IO_KISS_BUSY F_LOC("BUSY")
#define CMD_IO_KISS_CONT F_LOC("CONT")
#define CMD_IO_KISS_ATTEN F_LOC("ATTEN")
#define CMD_IO_ARQ F_LOC("ARQ")
#define CMD_IO_ARQ_IPA F_LOC("IPA")
#define CMD_IO_ARQ_IOPN F_LOC("IOPN")
#define CMD_IO_XMLRPC F_LOC("XMLRPC")
#define CMD_IO_XMLRPC_IPA F_LOC("IPA")
#define CMD_IO_XMLRPC_IOPN F_LOC("IOPN")
#define CMD_NBEMS F_LOC("MISC NBEMS")
#define CMD_NBEMS_STATE F_LOC("STATE")
#define CMD_NBEMS_MSG F_LOC("OPEN MSG")
#define CMD_NBEMS_FLMSG F_LOC("OPEN FLMSG")
#define CMD_NBEMS_FLMSG_PATH F_LOC("PATH")
#define CMD_NBEMS_BRWSR F_LOC("OPEN BRWSR")
#define CMD_NBEMS_TIMEOUT F_LOC("TIMEOUT")
#define CMD_ID F_LOC("ID")
#define CMD_ID_RSID F_LOC("RSID")
#define CMD_ID_RSID_NOTIFY F_LOC("NOTIFY")
#define CMD_ID_RSID_SRCH_BP F_LOC("SRCH BP")
#define CMD_ID_RSID_MARK_PREV F_LOC("MARK PREV")
#define CMD_ID_RSID_DETECTOR F_LOC("DETECTOR")
#define CMD_ID_RSID_ALRT_DIALOG F_LOC("ALRT DIALOG")
#define CMD_ID_RSID_TX_FREQ_LOCK F_LOC("TX FREQ LOCK")
#define CMD_ID_RSID_FREQ_CHANGE F_LOC("FREQ CHANGE")
#define CMD_ID_RSID_ALLOW_ERRORS F_LOC("ALLOW ERRORS")
#define CMD_ID_RSID_SQL_OPEN F_LOC("SQL OPEN")
#define CMD_ID_RSID_PRETONE F_LOC("PRETONE")
#define CMD_ID_RSID_END_XMT_ID F_LOC("END XMT ID")
#define CMD_ID_VIDEO F_LOC("VIDEO")
#define CMD_ID_VIDEO_TX_ID_MODE F_LOC("ID MODE")
#define CMD_ID_VIDEO_TX_VIDEO_TXT F_LOC("VIDEO TXT")
#define CMD_ID_VIDEO_TX_TXT_INP F_LOC("TEXT INPUT")
#define CMD_ID_VIDEO_SMALL_FONT F_LOC("SMALL FONT")
#define CMD_ID_VIDEO_500_HZ F_LOC("500HZ")
#define CMD_ID_VIDEO_WIDTH_LIMIT F_LOC("WIDTH LIMIT")
#define CMD_ID_VIDEO_CHAR_ROW F_LOC("CHAR ROW")
#define CMD_ID_CW F_LOC("CW")
#define CMD_ID_CW_TX_CALLSIGN F_LOC("TX CALL")
#define CMD_ID_CW_SPEED F_LOC("SPEED")
#define CMD_LOAD_MACRO F_LOC("MACRO")
#define CMD_END_CMD F_LOC("END")
// Parameters localized - no restrictions.
#define PARM_ENABLE _("ENABLE")
#define PARM_YES _("YES")
#define PARM_DISABLE _("DISABLE")
#define PARM_NO _("NO")
#define PARM_KISS _("KISS")
#define PARM_ARQ _("ARQ")
#define SCRIPT_COMMAND 0x0001
#define SCRIPT_DOT_NOTATION_ONLY 0x0002
#define SCRIPT_STRUCTURED_ONLY 0x0004
#define RECURSIVE_LIMIT 3
#define MAX_DELETE_LIST_COUNT 100
//! @enum script_codes
//! Error codes.
//! @typedef SCRIPT_CODES
//! @see script_codes
typedef enum script_codes {
script_recursive_limit_reached = -100, //!< Reached command recursive limit.
script_command_not_found = -100, //!< Script command not found.
script_unexpected_eof, //!< Unexspected end of file reached.
script_file_read_error, //!< File read error
script_errors_reported, //!< Script Errors found during parsing of file.
script_file_not_found, //!< Script file not found.
script_path_not_found, //!< Script directory path not found.
script_device_path_not_found, //!< Script device path not found.
script_non_script_file, //!< Opened file not a Script file.
script_max_sub_script_reached, //!< Maximum open subscripts reached.
script_subscript_exec_fail, //!< Subscript execution fail (internal).
script_incorrectly_assigned_value, //!< Incorrect parameter type.
script_invalid_parameter, //!< Parameter is not valid.
script_parameter_error, //!< Script parameter invalid.
script_function_parameter_error, //!< Function parameter error (internal, non script error).
script_mismatched_quotes, //!< Opening or closing quotes missing prior to reaching end if line.
script_command_seperator_missing, //!< Command missing ':'
script_args_eol, //!< Reached end of args list sooner then expected
script_param_check_eol, //!< Reached end of parameter check list sooner then expected
script_paramter_exceeds_length, //!< Data length exceeds expectations
script_memory_allocation_error, //!< Memory Allocation Error (Non-Script internal Error).
script_general_error = -1, //!< General purpose error (undefined erros).
script_no_errors, //!< No Errors
script_char_match_not_found, //!< Search char not found (Warning)
script_end_of_line_reached, //!< End of line reached (Warning)
script_end_of_list_reached, //!< End of list reached (Info)
script_list, //!< List command (Info)
script_command_handled, //!< Command was procedded and handled (Info)
} SCRIPT_CODES;
//! @enum paramter_types
//! Parameter type flags. Used to validate the informarion.
//! @typedef PARAM_TYPES
//! @see paramter_types
typedef enum paramter_types {
p_null = 0,
p_void,
p_bool,
p_char,
p_int,
p_unsigned_int,
p_long,
p_unsigned_long,
p_float,
p_double,
p_string,
p_path,
p_filename,
p_dev_path,
p_dev_name,
p_list,
p_list_end
} PARAM_TYPES;
class ScriptParsing;
//! @struct script_cmds
//! Vector table of script command string and executing function member.
//! @typedef SCRIPT_COMMANDS
//! @see script_cmds
typedef struct script_cmds {
char command[MAX_COMMAND_LENGTH]; //!< Command matching string.
int flags; //!< General purpose flags
size_t command_length; //!< Number of chacters in the command string.
int argc; //!< Number of required prarmeters for the command
char *args[MAX_CMD_PARAMETERS+1]; //!< String vector table of parameters
enum paramter_types param_check[MAX_CMD_PARAMETERS+1]; //!< Flags to determine type of parameter.
const char **valid_values; //!< A list of valid paramters.
int valid_value_count; //!< The number of valid paramters.
SCRIPT_CODES (ScriptParsing::*func)(struct script_cmds *); //!< The function (member) to execute on positive match
int (*cb)(ScriptParsing *sp, struct script_cmds *sd); //!< Call back function for script command
struct script_cmds * sub_commands; //!< List of sub commands
size_t sub_command_count; //!< Number of table entires in the sub table.
} SCRIPT_COMMANDS;
//! @class script_parsing_class
class ScriptParsing {
public:
private:
pthread_mutex_t ac; //<! Thread safe data access
int recursive_count;
bool _script_error_detected;
bool _restart_flag;
FILE *fd;
int line_number;
// Storage for each parameter
// Special processing data storage.
std::string _macro_command;
// Internal Class Variables.
std::string _path;
int _file_type;
SCRIPT_COMMANDS *_script_commands; //!< Table of commands and vector functions @see script_cmds
size_t _script_command_count; //!< Number of assigned positions in the table.
ScriptParsing *_parent; //!< Calling ScriptParsing pointer. Primarly used for the reset command on the local 'this' pointer.
// Keep track of what needs to be deleted on exit (deallocation).
SCRIPT_COMMANDS * memory_delete_list[MAX_DELETE_LIST_COUNT];
int delete_list_count; // Number of entries in the table.
char line_buffer[MAX_READLINE_LENGTH + 1]; //!< Line buffer for script read operations.
char error_cmd_buffer[MAX_COMMAND_LENGTH];
char error_string[MAX_COMMAND_LENGTH];
char error_buffer[MAX_COMMAND_LENGTH + MAX_COMMAND_LENGTH + 1];
SCRIPT_COMMANDS *top_cache;
public:
// Aceess methods for special processing data
std::string macro_command(void) { return _macro_command; }
void macro_command(std::string str) { _macro_command.assign(str); }
bool restart_flag(void) { return _restart_flag; }
void restart_flag(bool value) { _restart_flag = value; }
bool script_errors(void) { return _script_error_detected; }
// Parsing/varification routine for each of the commands.
SCRIPT_CODES check_parameters(struct script_cmds *);
SCRIPT_CODES check_filename(char *filename);
SCRIPT_CODES check_path(const char *);
SCRIPT_CODES check_numbers(char *, paramter_types p);
SCRIPT_CODES check_dev_path(const char *path);
SCRIPT_CODES check_bool(const char *value, bool &flag);
void to_uppercase(char *str, int limit);
void to_uppercase(std::string &str);
void trim(char *buffer, size_t size);
std::string &trim(std::string &s);
// Script handling code.
inline SCRIPT_CODES test_on_off_state(bool &state, char *string, char *true_state);
SCRIPT_COMMANDS * script_commands(void) { return _script_commands; }
void script_commands(SCRIPT_COMMANDS *ptr) { if(ptr) _script_commands = ptr; }
size_t script_command_count(void) { return _script_command_count; }
void script_command_count(size_t value) { _script_command_count = value; }
// Internal script fuctions
SCRIPT_CODES parse_commands(char *file_name_path); //!< The calling function to parse a script file.
SCRIPT_CODES read_file(FILE *fd, SCRIPT_COMMANDS *cur_list, size_t limit);
ScriptParsing *parent(void) { return _parent; }
void parent(ScriptParsing *value) { _parent = value; }
int assign_callback(const char *scriptCommand, int (*cb)(ScriptParsing *sp, SCRIPT_COMMANDS *sc));
int assign_valid_parameters(const char *command, const char **array, const int array_count);
void defaults(bool all);
ScriptParsing();
~ScriptParsing();
private:
// Special processing member.
SCRIPT_CODES sc_macros(struct script_cmds *cmd);
// Internal class routines
void add_to_delete_list(SCRIPT_COMMANDS *);
SCRIPT_CODES sc_dummy(struct script_cmds *);
SCRIPT_CODES remove_crlf_comments(char *data, char *limit, size_t &count);
SCRIPT_CODES parse_single_command(FILE *fd, SCRIPT_COMMANDS *cur_list, size_t limit, char *data, size_t buffer_size);
SCRIPT_CODES parse_hierarchy_command(char *data, size_t buffer_size);
int copy_tables(struct script_cmds * subcmds, size_t count);
std::string path(void) { return _path; }
int file_type(void) { return _file_type; }
void file_type(int value) { _file_type = value; }
SCRIPT_COMMANDS * search_command(SCRIPT_COMMANDS * table, size_t limit, const char *command);
SCRIPT_CODES copy_string_uppercase(char *buffer, char *cPtr, char *ePtr, size_t limit);
SCRIPT_CODES parse_parameters(char *s, char *d, SCRIPT_COMMANDS *matching_command);
int call_callback(SCRIPT_COMMANDS *cb_data);
int check_parameters_from_list(SCRIPT_COMMANDS *sc);
int CopyScriptParsingEnv(ScriptParsing *src);
void clear_script_parameters(bool all);
SCRIPT_CODES assign_member_func(char *cmd, SCRIPT_CODES (ScriptParsing::*func)(struct script_cmds *));
void initialize_function_members(void);
int str_cnt(char * str, int count_limit);
char * script_error_string(SCRIPT_CODES error_no, int ln, char *cmd);
char * skip_alpha_numbers(char * data, char *limit, SCRIPT_CODES &error);
char * skip_characters(char * data, char *limit, SCRIPT_CODES &error);
char * skip_numbers(char * data, char *limit, SCRIPT_CODES &error);
char * skip_spaces(char * data, char *limit, SCRIPT_CODES &error);
char * skip_to_character(char c, char * data, char *limit, SCRIPT_CODES &error);
char * skip_white_spaces(char * data, char *limit, SCRIPT_CODES &error);
};
int callback_dummy(ScriptParsing *sp, struct script_cmds *sc);
#endif /* defined(__script_parsing__) */