New FGCom standalone re-wrote from scratch
- positions.txt and special.txt are integrated in the binary - Reduce CPU load - New mode: OBS for listening a frequency - Source code ready to be used with another library - Support for COM1 and COM2 - Fix bug where frequencies conflict avoid switching between similar frequency in range - Better logging information and debug information - Range depends on altitude
This commit is contained in:
parent
a4b0be3d8a
commit
b0b272e4d2
15 changed files with 56882 additions and 13163 deletions
|
@ -1,56 +1,34 @@
|
||||||
# 20130904 - build of fgcom standalone - geoff
|
set(name fgcom)
|
||||||
|
|
||||||
if (MSVC)
|
# Copy positions.txt content in const char* _positionsData[];
|
||||||
set( RESOURCE_FILE fgcom.rc )
|
file(READ utils/positions.txt POSITIONS_DATA)
|
||||||
endif (MSVC)
|
string(REGEX REPLACE "\n" "\"%
|
||||||
|
\"" POSITIONS_DATA ${POSITIONS_DATA})
|
||||||
|
string(REGEX REPLACE "%" "," POSITIONS_DATA ${POSITIONS_DATA})
|
||||||
|
file(WRITE positions.hxx "const char* _positionsData[] = {
|
||||||
|
\"")
|
||||||
|
file(APPEND positions.hxx ${POSITIONS_DATA})
|
||||||
|
file(APPEND positions.hxx "\"
|
||||||
|
};")
|
||||||
|
|
||||||
if (NOT FGCOM_DATA_PATH)
|
if(MSVC)
|
||||||
# use relative paths (for standalone and custom installation)
|
set(RESOURCE_FILE fgcom.rc)
|
||||||
set(FGCOM_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/flightgear")
|
endif(MSVC)
|
||||||
if (APPLE)
|
|
||||||
# on Mac "share" directory doesn't exist
|
|
||||||
# .txt files are moved in the Resources directory because of Mac convention
|
|
||||||
# This movement is handled by the fgmeta.git/hudson_mac_package_release.rb line 139
|
|
||||||
set(DEFAULT_POSITIONS_FILE "../Resources/positions.txt")
|
|
||||||
set(SPECIAL_FREQUENCIES_FILE "../Resources/special_frequencies.txt")
|
|
||||||
else (APPLE)
|
|
||||||
set(DEFAULT_POSITIONS_FILE "../share/flightgear/positions.txt")
|
|
||||||
set(SPECIAL_FREQUENCIES_FILE "../share/flightgear/special_frequencies.txt")
|
|
||||||
endif (APPLE)
|
|
||||||
else()
|
|
||||||
# use absolute paths, useful for package creation (e.g -DFGCOM_DATA_PATH=/usr/share/fgcom)
|
|
||||||
set(DEFAULT_POSITIONS_FILE "${FGCOM_DATA_PATH}/positions.txt")
|
|
||||||
set(SPECIAL_FREQUENCIES_FILE "${FGCOM_DATA_PATH}/special_frequencies.txt")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# pass these to the compiler
|
set(SOURCES fgcom.cxx)
|
||||||
add_definitions( -DDEFAULT_POSITIONS_FILE="${DEFAULT_POSITIONS_FILE}" )
|
set(HEADERS fgcom.hxx positions.hxx)
|
||||||
add_definitions( -DSPECIAL_FREQUENCIES_FILE="${SPECIAL_FREQUENCIES_FILE}" )
|
|
||||||
|
|
||||||
# Project fgcom, type Console Application
|
add_executable(${name}
|
||||||
set(name fgcom)
|
${SOURCES}
|
||||||
set( ${name}_SOURCES fgcom.cxx fgcom_init.cxx position.cxx utils.cxx ${RESOURCE_FILE} )
|
${HEADERS}
|
||||||
set( ${name}_HEADERS fgcom.hxx fgcom_init.hxx position.hxx utils.hxx )
|
${RESOURCE_FILE}
|
||||||
if(WIN32)
|
)
|
||||||
list(APPEND ${name}_SOURCES fgcom_getopt.c)
|
|
||||||
list(APPEND ${name}_HEADERS fgcom_getopt.h)
|
target_link_Libraries(${name}
|
||||||
endif()
|
iaxclient_lib
|
||||||
add_executable( ${name} ${${name}_SOURCES} ${${name}_HEADERS} )
|
${OPENAL_LIBRARY}
|
||||||
if(WIN32)
|
${SIMGEAR_CORE_LIBRARIES}
|
||||||
set_target_properties( ${name} PROPERTIES DEBUG_POSTFIX d )
|
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
|
||||||
endif()
|
)
|
||||||
target_link_libraries( ${name} iaxclient_lib )
|
|
||||||
# this could be just on a target basis, but for now
|
install(TARGETS ${name} RUNTIME DESTINATION bin)
|
||||||
include_directories( ${CMAKE_SOURCE_DIR}/3rdparty/iaxclient/lib ) # for iaxclient.h
|
|
||||||
# Now include simgear libraries
|
|
||||||
target_link_Libraries( ${name}
|
|
||||||
${OPENAL_LIBRARY}
|
|
||||||
${SIMGEAR_CORE_LIBRARIES}
|
|
||||||
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES} )
|
|
||||||
# deal with install
|
|
||||||
install(TARGETS ${name} RUNTIME DESTINATION bin)
|
|
||||||
# then install, from their source to install destination
|
|
||||||
set( inst_FILES utils/positions.txt
|
|
||||||
utils/special_frequencies.txt )
|
|
||||||
install(FILES ${inst_FILES} DESTINATION ${FGCOM_DATA_PATH})
|
|
||||||
# eof
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* fgcom - VoIP-Client for the FlightGear-Radio-Infrastructure
|
* fgcom - VoIP-Client for the FlightGear-Radio-Infrastructure
|
||||||
*
|
*
|
||||||
|
* This program realizes the usage of the VoIP infractructure based
|
||||||
|
* on flight data which is send from FlightGear with an external
|
||||||
|
* protocol to this application.
|
||||||
|
*
|
||||||
|
* Clement de l'Hamaide - Jan 2014
|
||||||
|
* Re-writting of FGCom standalone
|
||||||
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
@ -21,58 +28,12 @@
|
||||||
#ifndef __FGCOM_H__
|
#ifndef __FGCOM_H__
|
||||||
#define __FGCOM_H__
|
#define __FGCOM_H__
|
||||||
|
|
||||||
#include <stdlib.h>
|
// avoid name clash with winerror.h
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <iaxclient.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning ( disable : 4244 ) // from double to float
|
|
||||||
#pragma warning ( disable : 4996 ) // depreciaed, really
|
|
||||||
#include <io.h> // for open. read, ...
|
|
||||||
#else
|
|
||||||
#include <signal.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_USER "guest"
|
|
||||||
#define DEFAULT_PASSWORD "guest"
|
|
||||||
#define DEFAULT_FG_SERVER "localhost"
|
|
||||||
#define DEFAULT_FG_PORT 16661
|
|
||||||
#define DEFAULT_CODE 1
|
|
||||||
#define ATIS_CODE 99
|
|
||||||
#define DEFAULT_VOIP_SERVER "fgcom.flightgear.org"
|
|
||||||
#define DEFAULT_CODEC 'u'
|
|
||||||
#define DEFAULT_IAX_CODEC IAXC_FORMAT_ULAW
|
|
||||||
#define DEFAULT_IAX_AUDIO AUDIO_INTERNAL
|
|
||||||
#define DEFAULT_MAX_CALLS 2
|
|
||||||
#define DEFAULT_MILLISLEEP 100
|
|
||||||
#define DEFAULT_RANGE 100.0
|
|
||||||
#define DEFAULT_LOWER_FRQ_LIMIT 108.0
|
|
||||||
#define DEFAULT_UPPER_FRQ_LIMIT 140.0
|
|
||||||
#define MAXBUFLEN 1024
|
|
||||||
#define DEFAULT_ALARM_TIMER 5
|
|
||||||
#define ALLOC_CHUNK_SIZE 5 //Size of a memory chunk to allocate
|
|
||||||
#define MX_REPORT_BUF 1024
|
|
||||||
#define MX_PATH_SIZE 2000
|
|
||||||
|
|
||||||
|
|
||||||
/* avoid name clash with winerror.h */
|
|
||||||
#define FGC_SUCCESS(__x__) (__x__ == 0)
|
#define FGC_SUCCESS(__x__) (__x__ == 0)
|
||||||
#define FGC_FAILED(__x__) (__x__ < 0)
|
#define FGC_FAILED(__x__) (__x__ < 0)
|
||||||
|
|
||||||
#ifndef SPECIAL_FREQUENCIES_FILE
|
|
||||||
#define SPECIAL_FREQUENCIES_FILE "fgcom-data\\special_frequencies.txt"
|
|
||||||
#endif
|
|
||||||
#ifndef DEFAULT_POSITIONS_FILE
|
|
||||||
#define DEFAULT_POSITIONS_FILE "fgcom-data\\positions.txt"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#define inline __inline
|
|
||||||
#ifdef WIN64
|
#ifdef WIN64
|
||||||
typedef __int64 ssize_t;
|
typedef __int64 ssize_t;
|
||||||
#else
|
#else
|
||||||
|
@ -80,87 +41,84 @@ typedef int ssize_t;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#ifndef FGCOM_VERSION
|
#ifndef FGCOM_VERSION
|
||||||
#ifndef FLIGHTGEAR_VERSION
|
#ifdef FLIGHTGEAR_VERSION
|
||||||
#define FGCOM_VERSION FLIGHTGEAR_VERSION
|
#define FGCOM_VERSION FLIGHTGEAR_VERSION
|
||||||
#else
|
#else
|
||||||
#define FGCOM_VERSION "2.99"
|
#define FGCOM_VERSION "unknown"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct airport
|
#define MAXBUFLEN 1024
|
||||||
{
|
|
||||||
char icao[5];
|
enum Modes {
|
||||||
float frequency;
|
ATC,
|
||||||
double lat;
|
PILOT,
|
||||||
double lon;
|
OBS,
|
||||||
char type[33];
|
TEST
|
||||||
char text[129];
|
|
||||||
struct airport *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pos
|
enum ActiveComm {
|
||||||
{
|
COM1,
|
||||||
double lon;
|
COM2
|
||||||
double lat;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fgdata
|
struct Data
|
||||||
{
|
{
|
||||||
float COM1_FRQ;
|
int ptt;
|
||||||
float COM2_FRQ;
|
float com1;
|
||||||
float NAV1_FRQ;
|
float com2;
|
||||||
float NAV2_FRQ;
|
double lon;
|
||||||
int COM1_SRV;
|
double lat;
|
||||||
int COM2_SRV;
|
double alt;
|
||||||
int NAV1_SRV;
|
float outputVol;
|
||||||
int NAV2_SRV;
|
float silenceThd;
|
||||||
int PTT;
|
std::string callsign;
|
||||||
int TRANSPONDER;
|
|
||||||
float IAS;
|
|
||||||
float GS;
|
|
||||||
double LON;
|
|
||||||
double LAT;
|
|
||||||
int ALT;
|
|
||||||
float HEAD;
|
|
||||||
float OUTPUT_VOL;
|
|
||||||
float SILENCE_THD;
|
|
||||||
char* CALLSIGN;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* function declaratons */
|
struct Airport
|
||||||
void quit (int signal);
|
{
|
||||||
void alarm_handler (int signal);
|
double frequency;
|
||||||
void strtoupper (const char *str, char *buf, size_t len);
|
double latitude;
|
||||||
void usage (char *prog);
|
double longitude;
|
||||||
int create_socket (int port);
|
double distanceNm;
|
||||||
void fatal_error (const char *err);
|
std::string icao;
|
||||||
int iaxc_callback (iaxc_event e);
|
std::string type;
|
||||||
void event_state (int state, char *remote, char *remote_name, char *local,
|
std::string name;
|
||||||
char *local_context);
|
};
|
||||||
void event_text (int type, char *message);
|
|
||||||
void event_register (int id, int reply, int count);
|
// Internal functions
|
||||||
void report (char *text);
|
int usage();
|
||||||
const char *map_state (int state);
|
int version();
|
||||||
void event_unknown (int type);
|
void quit(int state);
|
||||||
void event_netstats (struct iaxc_ev_netstats stat);
|
bool isInRange(std::string icao, double acftLat, double acftLon, double acftAlt);
|
||||||
void event_level (double in, double out);
|
std::string computePhoneNumber(double freq, std::string icao, bool atis = false);
|
||||||
void icao2number (char *icao, float frequency, char *buf);
|
std::string getClosestAirportForFreq(double freq, double acftLat, double acftLon, double acftAlt);
|
||||||
void icao2atisnumber (char *icao, float frequency, char *buf);
|
std::multimap<int, Airport> getAirportsData();
|
||||||
void ptt (int mode);
|
|
||||||
double distance (double lat1, double lon1, double lat2, double lon2);
|
// Library functions
|
||||||
int split (char *string, char *fields[], int nfields, const char *sep);
|
bool lib_init();
|
||||||
char *readln (FILE * fp, char *buf, int len);
|
bool lib_hangup();
|
||||||
double *read_special_frequencies(const char *file);
|
bool lib_shutdown();
|
||||||
struct airport *read_airports (const char *file);
|
bool lib_call(std::string icao, double freq);
|
||||||
const char *icaobypos (struct airport *airports, double frequency,
|
bool lib_directCall(std::string icao, double freq, std::string num);
|
||||||
double plane_lat, double plane_lon, double range);
|
|
||||||
void vor (char *icao, double frequency, int mode);
|
int lib_registration();
|
||||||
char *report_devices (int in);
|
int iaxc_callback(iaxc_event e);
|
||||||
int set_device (const char *name, int out);
|
|
||||||
struct pos posbyicao (struct airport *airports, char *icao);
|
void lib_setSilenceThreshold(double thd);
|
||||||
void parse_fgdata (struct fgdata *data, char *buf);
|
void lib_setCallerId(std::string callsign);
|
||||||
int check_special_frq (double frq);
|
void lib_setVolume(double input, double output);
|
||||||
void do_iaxc_call (const char *username, const char *password,
|
|
||||||
const char *voipserver, char *number);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,186 +0,0 @@
|
||||||
/* getopt.h */
|
|
||||||
/* Declarations for getopt.
|
|
||||||
Copyright (C) 1989-1994, 1996-1999, 2001 Free Software
|
|
||||||
Foundation, Inc. This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute
|
|
||||||
it and/or modify it under the terms of the GNU Lesser
|
|
||||||
General Public License as published by the Free Software
|
|
||||||
Foundation; either version 2.1 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
The GNU C Library 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.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General
|
|
||||||
Public License along with the GNU C Library; if not, write
|
|
||||||
to the Free Software Foundation, Inc., 59 Temple Place,
|
|
||||||
Suite 330, Boston, MA 02111-1307 USA. */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _GETOPT_H
|
|
||||||
|
|
||||||
#ifndef __need_getopt
|
|
||||||
# define _GETOPT_H 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If __GNU_LIBRARY__ is not already defined, either we are being used
|
|
||||||
standalone, or this is the first header included in the source file.
|
|
||||||
If we are being used with glibc, we need to include <features.h>, but
|
|
||||||
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
|
||||||
not defined, include <ctype.h>, which will pull in <features.h> for us
|
|
||||||
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
|
|
||||||
doesn't flood the namespace with stuff the way some other headers do.) */
|
|
||||||
#if !defined __GNU_LIBRARY__
|
|
||||||
# include <ctype.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* For communication from `getopt' to the caller.
|
|
||||||
When `getopt' finds an option that takes an argument,
|
|
||||||
the argument value is returned here.
|
|
||||||
Also, when `ordering' is RETURN_IN_ORDER,
|
|
||||||
each non-option ARGV-element is returned here. */
|
|
||||||
|
|
||||||
extern char *optarg;
|
|
||||||
|
|
||||||
/* Index in ARGV of the next element to be scanned.
|
|
||||||
This is used for communication to and from the caller
|
|
||||||
and for communication between successive calls to `getopt'.
|
|
||||||
|
|
||||||
On entry to `getopt', zero means this is the first call; initialize.
|
|
||||||
|
|
||||||
When `getopt' returns -1, this is the index of the first of the
|
|
||||||
non-option elements that the caller should itself scan.
|
|
||||||
|
|
||||||
Otherwise, `optind' communicates from one call to the next
|
|
||||||
how much of ARGV has been scanned so far. */
|
|
||||||
|
|
||||||
extern int optind;
|
|
||||||
|
|
||||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
|
||||||
for unrecognized options. */
|
|
||||||
|
|
||||||
extern int opterr;
|
|
||||||
|
|
||||||
/* Set to an option character which was unrecognized. */
|
|
||||||
|
|
||||||
extern int optopt;
|
|
||||||
|
|
||||||
#ifndef __need_getopt
|
|
||||||
/* Describe the long-named options requested by the application.
|
|
||||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
|
||||||
of `struct option' terminated by an element containing a name which is
|
|
||||||
zero.
|
|
||||||
|
|
||||||
The field `has_arg' is:
|
|
||||||
no_argument (or 0) if the option does not take an argument,
|
|
||||||
required_argument (or 1) if the option requires an argument,
|
|
||||||
optional_argument (or 2) if the option takes an optional argument.
|
|
||||||
|
|
||||||
If the field `flag' is not NULL, it points to a variable that is set
|
|
||||||
to the value given in the field `val' when the option is found, but
|
|
||||||
left unchanged if the option is not found.
|
|
||||||
|
|
||||||
To have a long-named option do something other than set an `int' to
|
|
||||||
a compiled-in constant, such as set a value from `optarg', set the
|
|
||||||
option's `flag' field to zero and its `val' field to a nonzero
|
|
||||||
value (the equivalent single-letter option character, if there is
|
|
||||||
one). For long options that have a zero `flag' field, `getopt'
|
|
||||||
returns the contents of the `val' field. */
|
|
||||||
|
|
||||||
struct option
|
|
||||||
{
|
|
||||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
|
||||||
const char *name;
|
|
||||||
# else
|
|
||||||
char *name;
|
|
||||||
# endif
|
|
||||||
/* has_arg can't be an enum because some compilers complain about
|
|
||||||
type mismatches in all the code that assumes it is an int. */
|
|
||||||
int has_arg;
|
|
||||||
int *flag;
|
|
||||||
int val;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
|
||||||
|
|
||||||
# define no_argument 0
|
|
||||||
# define required_argument 1
|
|
||||||
# define optional_argument 2
|
|
||||||
#endif /* need getopt */
|
|
||||||
|
|
||||||
|
|
||||||
/* Get definitions and prototypes for functions to process the
|
|
||||||
arguments in ARGV (ARGC of them, minus the program name) for
|
|
||||||
options given in OPTS.
|
|
||||||
|
|
||||||
Return the option character from OPTS just read. Return -1 when
|
|
||||||
there are no more options. For unrecognized options, or options
|
|
||||||
missing arguments, `optopt' is set to the option letter, and '?' is
|
|
||||||
returned.
|
|
||||||
|
|
||||||
The OPTS string is a list of characters which are recognized option
|
|
||||||
letters, optionally followed by colons, specifying that that letter
|
|
||||||
takes an argument, to be placed in `optarg'.
|
|
||||||
|
|
||||||
If a letter in OPTS is followed by two colons, its argument is
|
|
||||||
optional. This behavior is specific to the GNU `getopt'.
|
|
||||||
|
|
||||||
The argument `--' causes premature termination of argument
|
|
||||||
scanning, explicitly telling `getopt' that there are no more
|
|
||||||
options.
|
|
||||||
|
|
||||||
If OPTS begins with `--', then non-option arguments are treated as
|
|
||||||
arguments to the option '\0'. This behavior is specific to the GNU
|
|
||||||
`getopt'. */
|
|
||||||
|
|
||||||
#if (defined __STDC__ && __STDC__) || defined __cplusplus
|
|
||||||
# ifdef __GNU_LIBRARY__
|
|
||||||
/* Many other libraries have conflicting prototypes for getopt, with
|
|
||||||
differences in the consts, in stdlib.h. To avoid compilation
|
|
||||||
errors, only prototype getopt for the GNU C library. */
|
|
||||||
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
|
|
||||||
# else /* not __GNU_LIBRARY__ */
|
|
||||||
extern int getopt ();
|
|
||||||
# endif /* __GNU_LIBRARY__ */
|
|
||||||
|
|
||||||
# ifndef __need_getopt
|
|
||||||
extern int getopt_long (int ___argc, char *const *___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind);
|
|
||||||
extern int getopt_long_only (int ___argc, char *const *___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind);
|
|
||||||
|
|
||||||
/* Internal only. Users should not call this directly. */
|
|
||||||
extern int _getopt_internal (int ___argc, char *const *___argv,
|
|
||||||
const char *__shortopts,
|
|
||||||
const struct option *__longopts, int *__longind,
|
|
||||||
int __long_only);
|
|
||||||
# endif
|
|
||||||
#else /* not __STDC__ */
|
|
||||||
extern int getopt ();
|
|
||||||
# ifndef __need_getopt
|
|
||||||
extern int getopt_long ();
|
|
||||||
extern int getopt_long_only ();
|
|
||||||
|
|
||||||
extern int _getopt_internal ();
|
|
||||||
# endif
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Make sure we later can get all the definitions and declarations. */
|
|
||||||
#undef __need_getopt
|
|
||||||
|
|
||||||
#endif /* getopt.h */
|
|
|
@ -1,690 +0,0 @@
|
||||||
//
|
|
||||||
// fgcom_init.cxx -- FGCOM configuration parsing and initialization
|
|
||||||
// FGCOM: Copyright (C) H. Wirtz <wirtz@dfn.de>
|
|
||||||
//
|
|
||||||
// Adaption of fg_init.cxx from FlightGear
|
|
||||||
// FlightGear: Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
|
|
||||||
//
|
|
||||||
// Huge part rewritten by Tobias Ramforth to fit needs of FGCOM.
|
|
||||||
// <tobias@ramforth.com>
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined( _MSC_VER) || defined(__MINGW32__)
|
|
||||||
# include <direct.h> // for getcwd()
|
|
||||||
# define getcwd _getcwd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include "fgcom_getopt.h"
|
|
||||||
#else
|
|
||||||
#include <pwd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "fgcom_init.hxx"
|
|
||||||
#include "fgcom.hxx"
|
|
||||||
#include "utils.hxx"
|
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using std::string;
|
|
||||||
using std::cerr;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
|
|
||||||
|
|
||||||
// Manipulators
|
|
||||||
istream& skip_eol( istream& in ) {
|
|
||||||
char c = '\0';
|
|
||||||
// skip to end of line.
|
|
||||||
while ( in.get(c) ) {
|
|
||||||
if ( (c == '\n') || (c == '\r') ) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
istream& skip_ws( istream& in ) {
|
|
||||||
char c;
|
|
||||||
while ( in.get(c) ) {
|
|
||||||
if ( ! isspace( c ) ) {
|
|
||||||
// put back the non-space character
|
|
||||||
in.putback(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
istream& skip_comment( istream& in )
|
|
||||||
{
|
|
||||||
while ( in ) {
|
|
||||||
// skip whitespace
|
|
||||||
in >> skip_ws;
|
|
||||||
char c;
|
|
||||||
if ( in.get( c ) && c != '#' ) {
|
|
||||||
// not a comment
|
|
||||||
in.putback(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
in >> skip_eol;
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* program name */
|
|
||||||
extern char *prog;
|
|
||||||
extern const char * default_root;
|
|
||||||
|
|
||||||
static std::string config;
|
|
||||||
|
|
||||||
static OptionEntry *fgcomOptionArray = 0;
|
|
||||||
|
|
||||||
static void _doOptions (int argc, char **argv);
|
|
||||||
static int _parseOption (const std::string & arg, const std::string & next_arg);
|
|
||||||
static void _fgcomParseArgs (int argc, char **argv);
|
|
||||||
static void _fgcomParseOptions (const std::string & path);
|
|
||||||
|
|
||||||
// Read in configuration (file and command line)
|
|
||||||
bool fgcomInitOptions (const OptionEntry * fgcomOptions, int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (!fgcomOptions) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Error! Uninitialized fgcomOptionArray!" );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set option array
|
|
||||||
int n_options;
|
|
||||||
for (n_options = 0; fgcomOptions[n_options].long_option != NULL; n_options++) {}
|
|
||||||
|
|
||||||
fgcomOptionArray = (OptionEntry *) realloc (fgcomOptionArray, sizeof (OptionEntry) * (n_options + 1));
|
|
||||||
memcpy (fgcomOptionArray, fgcomOptions, sizeof (OptionEntry) * (n_options + 1));
|
|
||||||
|
|
||||||
// parse options
|
|
||||||
_doOptions (argc, argv);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create usage information out of fgcomOptionArray
|
|
||||||
void
|
|
||||||
fgcomUsage ()
|
|
||||||
{
|
|
||||||
size_t
|
|
||||||
max_length = 0;
|
|
||||||
|
|
||||||
if (!fgcomOptionArray)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Error! Options need to be initialized by calling 'fgcomInitConfig'!" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// find longest long_option
|
|
||||||
const OptionEntry *
|
|
||||||
currentEntry = &fgcomOptionArray[0];
|
|
||||||
while (currentEntry->long_option != 0)
|
|
||||||
{
|
|
||||||
size_t
|
|
||||||
current_length = strlen (currentEntry->long_option);
|
|
||||||
if (current_length > max_length)
|
|
||||||
{
|
|
||||||
max_length = current_length;
|
|
||||||
}
|
|
||||||
currentEntry++;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_length *= 2;
|
|
||||||
max_length += 10; // for "-o, --option=, -option"
|
|
||||||
|
|
||||||
// print head
|
|
||||||
std::cout << " OPTION" << std::string (max_length - 8,
|
|
||||||
' ') << "\t\t" << "DESCRIPTION" <<
|
|
||||||
std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
// iterate through option array
|
|
||||||
currentEntry = &fgcomOptionArray[0];
|
|
||||||
while (currentEntry->long_option != 0)
|
|
||||||
{
|
|
||||||
size_t
|
|
||||||
current_length = strlen (currentEntry->long_option);
|
|
||||||
|
|
||||||
current_length *= 2;
|
|
||||||
current_length += 10;
|
|
||||||
|
|
||||||
std::string option = std::string (" -")
|
|
||||||
+ std::string (¤tEntry->option);
|
|
||||||
if (option.size() > 4)
|
|
||||||
option = option.substr(0,4);
|
|
||||||
option += std::string (", -")
|
|
||||||
+ std::string (currentEntry->long_option)
|
|
||||||
+ std::string (", --")
|
|
||||||
+ std::string (currentEntry->long_option)
|
|
||||||
+ std::string ("=") + std::string (max_length - current_length, ' ');
|
|
||||||
|
|
||||||
std::cout << option << "\t\t" << currentEntry->description;
|
|
||||||
|
|
||||||
if (currentEntry->has_param && (currentEntry->type != OPTION_NONE)
|
|
||||||
&& (currentEntry->default_value != 0))
|
|
||||||
{
|
|
||||||
std::cout << " (default: '";
|
|
||||||
|
|
||||||
if (currentEntry->type == OPTION_NONE)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (currentEntry->type == OPTION_BOOL)
|
|
||||||
{
|
|
||||||
std::cout << *(bool *) currentEntry->default_value;
|
|
||||||
}
|
|
||||||
else if (currentEntry->type == OPTION_STRING)
|
|
||||||
{
|
|
||||||
std::cout << (char *) currentEntry->default_value;
|
|
||||||
}
|
|
||||||
else if (currentEntry->type == OPTION_FLOAT)
|
|
||||||
{
|
|
||||||
std::cout << *(float *) currentEntry->default_value;
|
|
||||||
}
|
|
||||||
else if (currentEntry->type == OPTION_DOUBLE)
|
|
||||||
{
|
|
||||||
std::cout << *(double *) currentEntry->default_value;
|
|
||||||
}
|
|
||||||
else if (currentEntry->type == OPTION_FREQ)
|
|
||||||
{
|
|
||||||
std::cout << std::setw (7) << std::
|
|
||||||
setprecision (3) << *(double *) currentEntry->default_value;
|
|
||||||
}
|
|
||||||
else if (currentEntry->type == OPTION_INT)
|
|
||||||
{
|
|
||||||
std::cout << *(int *) currentEntry->default_value;
|
|
||||||
}
|
|
||||||
else if (currentEntry->type == OPTION_CHAR)
|
|
||||||
{
|
|
||||||
std::cout << *(char *) currentEntry->default_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "')";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
currentEntry++;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::cout << " Available codecs:" << std::endl;
|
|
||||||
std::cout << " \t" <<
|
|
||||||
"u - ulaw (default and best codec because the mixing is based onto ulaw)"
|
|
||||||
<< std::endl;
|
|
||||||
std::cout << " \t" << "a - alaw" << std::endl;
|
|
||||||
std::cout << " \t" << "g - gsm" << std::endl;
|
|
||||||
std::cout << " \t" << "s - speex" << std::endl;
|
|
||||||
std::cout << " \t" << "7 - G.723" << std::endl;
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::cout << " Mode 1: client for COM1 of flightgear:" << std::endl;
|
|
||||||
std::cout << " \t" << "$ " << prog << std::endl;
|
|
||||||
std::cout << " - connects " << prog << " to fgfs at localhost:" <<
|
|
||||||
DEFAULT_FG_PORT << std::endl;
|
|
||||||
std::cout << " \t" << "$ " << prog << " -sother.host.tld -p23456" <<
|
|
||||||
std::endl;
|
|
||||||
std::cout << " - connects " << prog << " to fgfs at other.host.tld:23456" << std::endl;
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::cout << " Mode 2: client for an ATC at <airport> on <frequency>:" <<
|
|
||||||
std::endl;
|
|
||||||
std::cout << " \t" << "$ " << prog << " -aKSFO -f120.500" << std::endl;
|
|
||||||
std::cout << " - sets up " << prog <<
|
|
||||||
" for an ATC radio at KSFO 120.500 MHz" << std::endl;
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
std::cout << std::endl;
|
|
||||||
|
|
||||||
std::cout << "Note that " << prog <<
|
|
||||||
" starts with a guest account unless you use -U and -P!" << std::endl;
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
get_alternate_home(void)
|
|
||||||
{
|
|
||||||
char *ah = 0;
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
char *app_data = getenv("LOCALAPPDATA");
|
|
||||||
if (app_data) {
|
|
||||||
ah = _strdup(app_data);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct passwd *
|
|
||||||
pwd = getpwent ();
|
|
||||||
ah = strdup (pwd->pw_dir);
|
|
||||||
#endif
|
|
||||||
return ah;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to locate and parse the various non-XML config files in order
|
|
||||||
// from least precidence to greatest precidence
|
|
||||||
static void
|
|
||||||
_doOptions (int argc, char **argv)
|
|
||||||
{
|
|
||||||
char *
|
|
||||||
homedir = getenv ("HOME");
|
|
||||||
|
|
||||||
if (homedir == NULL)
|
|
||||||
{
|
|
||||||
homedir = get_alternate_home();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for ~/.fgfsrc
|
|
||||||
if (homedir != NULL)
|
|
||||||
{
|
|
||||||
config = string (homedir);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
config.append ("\\");
|
|
||||||
#else
|
|
||||||
config.append ("/");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
config.append (".fgcomrc");
|
|
||||||
_fgcomParseOptions (config);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse remaining command line options
|
|
||||||
// These will override anything specified in a config file
|
|
||||||
_fgcomParseArgs (argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
// lookup maps
|
|
||||||
static std::map<string, string> fgcomOptionMap;
|
|
||||||
static std::map<string, size_t> fgcomLongOptionMap;
|
|
||||||
|
|
||||||
// Parse a single option
|
|
||||||
static int
|
|
||||||
_parseOption (const std::string & arg, const std::string & next_arg)
|
|
||||||
{
|
|
||||||
if (fgcomLongOptionMap.size () == 0)
|
|
||||||
{
|
|
||||||
size_t i = 0;
|
|
||||||
const OptionEntry * entry = &fgcomOptionArray[0];
|
|
||||||
while (entry->long_option != 0)
|
|
||||||
{
|
|
||||||
fgcomLongOptionMap.insert (std::pair < std::string,
|
|
||||||
size_t >
|
|
||||||
(std::string (entry->long_option), i));
|
|
||||||
fgcomOptionMap.insert (std::pair < std::string,
|
|
||||||
std::string >
|
|
||||||
(std::string (1, entry->option),
|
|
||||||
std::string (entry->long_option)));
|
|
||||||
i += 1;
|
|
||||||
entry += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// General Options
|
|
||||||
if ((arg == "--help") || (arg == "-h") || (arg == "-?"))
|
|
||||||
{
|
|
||||||
// help/usage request
|
|
||||||
return FGCOM_OPTIONS_HELP;
|
|
||||||
}
|
|
||||||
else if ((arg == "--verbose") || (arg == "-v"))
|
|
||||||
{
|
|
||||||
// verbose help/usage request
|
|
||||||
return FGCOM_OPTIONS_VERBOSE_HELP;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::map < string, size_t >::iterator it;
|
|
||||||
std::string arg_name, arg_value;
|
|
||||||
|
|
||||||
if (arg.find ("--") == 0)
|
|
||||||
{
|
|
||||||
size_t
|
|
||||||
pos = arg.find ('=');
|
|
||||||
if (pos == string::npos)
|
|
||||||
{
|
|
||||||
// did not find a value
|
|
||||||
arg_name = arg.substr (2);
|
|
||||||
|
|
||||||
// now there are two possibilities:
|
|
||||||
// 1: this is an option without a value
|
|
||||||
// 2: the value can be found in next_arg
|
|
||||||
if (next_arg.empty ())
|
|
||||||
{
|
|
||||||
// ok, value cannot be in next_arg
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "option '" << arg_name << "'" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (next_arg.at (0) == '-')
|
|
||||||
{
|
|
||||||
// there is no value, new option starts in next_arg
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "option '" << arg_name << "'" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// the value is in next_arg
|
|
||||||
arg_value = std::string (next_arg);
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "option '" << arg_name << "' with argument '" << arg_value << "'" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// found a value
|
|
||||||
arg_name = arg.substr (2, pos - 2);
|
|
||||||
arg_value = arg.substr (pos + 1);
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "option '" << arg_name << "' with argument '" << arg_value << "'" );
|
|
||||||
}
|
|
||||||
|
|
||||||
it = fgcomLongOptionMap.find (arg_name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::map < string, string >::iterator it_b;
|
|
||||||
arg_name = arg.substr (1, 1);
|
|
||||||
arg_value = arg.substr (2);
|
|
||||||
|
|
||||||
if (arg_name.empty ())
|
|
||||||
{
|
|
||||||
SG_LOG (SG_GENERAL, SG_ALERT, "Unknown option '" << arg << "'");
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "option '" << arg_name << "' with argument '" << arg_value << "'" );
|
|
||||||
|
|
||||||
it_b = fgcomOptionMap.find (arg_name);
|
|
||||||
|
|
||||||
if (it_b != fgcomOptionMap.end ())
|
|
||||||
{
|
|
||||||
it = fgcomLongOptionMap.find (it_b->second);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Unknown option '" << arg << "'" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it != fgcomLongOptionMap.end ())
|
|
||||||
{
|
|
||||||
const OptionEntry *
|
|
||||||
entry = &fgcomOptionArray[it->second];
|
|
||||||
switch (entry->type)
|
|
||||||
{
|
|
||||||
case OPTION_BOOL:
|
|
||||||
*(bool *) entry->parameter = true;
|
|
||||||
break;
|
|
||||||
case OPTION_STRING:
|
|
||||||
if (entry->has_param && !arg_value.empty ())
|
|
||||||
{
|
|
||||||
*(char **) entry->parameter = strdup (arg_value.c_str ());
|
|
||||||
}
|
|
||||||
else if (entry->has_param)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' does not have a parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPTION_FLOAT:
|
|
||||||
if (!arg_value.empty ())
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
float temp = atof(arg_value.c_str ());
|
|
||||||
#else // !_MSC_VER
|
|
||||||
char *
|
|
||||||
end;
|
|
||||||
float
|
|
||||||
temp = strtof (arg_value.c_str (), &end);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if (*end != '\0')
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot parse float value '" << arg_value << "' for option " << arg_name << "!" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
#endif // _MSC_VER y/n
|
|
||||||
|
|
||||||
*(float *) (entry->parameter) = temp;
|
|
||||||
if (*(float *) (entry->parameter) != temp
|
|
||||||
|| errno == ERANGE)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Float value '" << arg_value << "' for option " << arg_name << " out of range!" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPTION_DOUBLE:
|
|
||||||
case OPTION_FREQ:
|
|
||||||
if (!arg_value.empty ())
|
|
||||||
{
|
|
||||||
char *
|
|
||||||
end;
|
|
||||||
double
|
|
||||||
temp = strtod (arg_value.c_str (), &end);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if (*end != '\0')
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot parse double value '" << arg_value << "' for option " << arg_name << "!" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(double *) (entry->parameter) = temp;
|
|
||||||
if (*(double *) (entry->parameter) != temp
|
|
||||||
|| errno == ERANGE)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Double value '" << arg_value << "' for option " << arg_name << " out of range!" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPTION_INT:
|
|
||||||
if (!arg_value.empty ())
|
|
||||||
{
|
|
||||||
char *
|
|
||||||
end;
|
|
||||||
long
|
|
||||||
temp = strtol (arg_value.c_str (), &end, 0);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if (*end != '\0')
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot parse integer value '" << arg_value << "' for option " << arg_name << "!" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(int *) (entry->parameter) = temp;
|
|
||||||
if (*(int *) (entry->parameter) != temp || errno == ERANGE)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Integer value '" << arg_value << "' for option " << arg_name << " out of range!" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPTION_CHAR:
|
|
||||||
if (entry->has_param && !arg_value.empty ())
|
|
||||||
{
|
|
||||||
if (arg_value.length () > 1)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a single char as parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*(char *) entry->parameter = arg_value.c_str ()[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (entry->has_param)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' needs a parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Option '" << arg << "' does not have a parameter" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPTION_NONE:
|
|
||||||
*(bool *) entry->parameter = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Unknown option '" << arg << "'" );
|
|
||||||
return FGCOM_OPTIONS_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FGCOM_OPTIONS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the command line options
|
|
||||||
static void
|
|
||||||
_fgcomParseArgs (int argc, char **argv)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Processing commandline options" );
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++)
|
|
||||||
{
|
|
||||||
std::string arg = std::string (argv[i]);
|
|
||||||
std::string next_arg;
|
|
||||||
if (i < argc - 1)
|
|
||||||
{
|
|
||||||
next_arg = std::string (argv[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg.find ('-') == 0)
|
|
||||||
{
|
|
||||||
if (arg == "--")
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int
|
|
||||||
result = _parseOption (arg, next_arg);
|
|
||||||
|
|
||||||
if (result == FGCOM_OPTIONS_OK)
|
|
||||||
{
|
|
||||||
// that is great
|
|
||||||
}
|
|
||||||
else if (result == FGCOM_OPTIONS_HELP)
|
|
||||||
{
|
|
||||||
fgcomUsage ();
|
|
||||||
exit (0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Error parsing commandline options !" );
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Successfully parsed commandline options" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse config file options
|
|
||||||
static void
|
|
||||||
_fgcomParseOptions (const std::string & path)
|
|
||||||
{
|
|
||||||
if (is_file_or_directory(path.c_str()) != 1) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Error: Unable to open " << path );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::fstream in;
|
|
||||||
std::ios_base::openmode mode = std::ios_base::in;
|
|
||||||
in.open(path.c_str(),mode);
|
|
||||||
if (!in.is_open ()) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "Error: DEBUG: Unable to open " << path );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Processing config file: " << path );
|
|
||||||
|
|
||||||
in >> skip_comment;
|
|
||||||
while (!in.eof ()) {
|
|
||||||
std::string line;
|
|
||||||
getline (in, line, '\n');
|
|
||||||
|
|
||||||
// catch extraneous (DOS) line ending character
|
|
||||||
int i;
|
|
||||||
for (i = line.length(); i > 0; i--) {
|
|
||||||
if (line[i - 1] > 32) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
line = line.substr(0, i);
|
|
||||||
|
|
||||||
std::string next_arg;
|
|
||||||
if (_parseOption (line, next_arg) == FGCOM_OPTIONS_ERROR) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "ERROR: Config file parse error: " << path << " '" << line << "'" );
|
|
||||||
fgcomUsage ();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
in >> skip_comment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eof - fgcom_init.cpp */
|
|
|
@ -1,86 +0,0 @@
|
||||||
//
|
|
||||||
// fgcom_init.hxx -- FGCOM configuration parsing and initialization
|
|
||||||
// FGCOM: Copyright (C) H. Wirtz <wirtz@dfn.de>
|
|
||||||
//
|
|
||||||
// Adaption of fg_init.h from FlightGear
|
|
||||||
// FlightGear: Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
|
|
||||||
//
|
|
||||||
// Huge part rewritten by Tobias Ramforth to fit needs of FGCOM.
|
|
||||||
// <tobias@ramforth.com>
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __INIT_H__
|
|
||||||
#define __INIT_H__
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
FGCOM_OPTIONS_OK = 0,
|
|
||||||
FGCOM_OPTIONS_HELP = 1,
|
|
||||||
FGCOM_OPTIONS_ERROR = 2,
|
|
||||||
FGCOM_OPTIONS_EXIT = 3,
|
|
||||||
FGCOM_OPTIONS_VERBOSE_HELP = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
option has_param type property b_param s_param func
|
|
||||||
|
|
||||||
where:
|
|
||||||
option : name of the option
|
|
||||||
has_param : option is --name=value if true or --name if false
|
|
||||||
type : OPTION_BOOL - property is a boolean
|
|
||||||
OPTION_STRING - property is a string
|
|
||||||
OPTION_FLOAT - property is a float
|
|
||||||
OPTION_DOUBLE - property is a double
|
|
||||||
OPTION_FREQ - property is a double and stands for a frequency
|
|
||||||
OPTION_INT - property is an integer
|
|
||||||
OPTION_INT - property is a char
|
|
||||||
|
|
||||||
For OPTION_FLOAT, OPTION_DOUBLE and OPTION_INT, the parameter value is converted into a
|
|
||||||
float, double or an integer and set to the property.
|
|
||||||
*/
|
|
||||||
enum OptionType
|
|
||||||
{
|
|
||||||
OPTION_NONE,
|
|
||||||
OPTION_BOOL,
|
|
||||||
OPTION_STRING,
|
|
||||||
OPTION_FLOAT,
|
|
||||||
OPTION_DOUBLE,
|
|
||||||
OPTION_FREQ,
|
|
||||||
OPTION_INT,
|
|
||||||
OPTION_CHAR
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _OptionEntry OptionEntry;
|
|
||||||
|
|
||||||
struct _OptionEntry
|
|
||||||
{
|
|
||||||
const char *long_option;
|
|
||||||
char option;
|
|
||||||
bool has_param;
|
|
||||||
enum OptionType type;
|
|
||||||
void *parameter;
|
|
||||||
char property;
|
|
||||||
const char *description;
|
|
||||||
const void *default_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Read in configuration (file and command line)
|
|
||||||
bool fgcomInitOptions (const OptionEntry * fgcomOptions, int argc, char **argv);
|
|
||||||
void fgcomUsage (); // fgcom usage
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
* fgcom - VoIP-Client for the FlightGear-Radio-Infrastructure
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
#include "fgcom.hxx"
|
|
||||||
|
|
||||||
#define EARTHRADIUS 6370.0 //radius of earth
|
|
||||||
#define UF 0.01745329251994329509 //conversion factor pi/180 degree->rad
|
|
||||||
|
|
||||||
double
|
|
||||||
distance (double lat1, double lon1, double lat2, double lon2)
|
|
||||||
{
|
|
||||||
double d;
|
|
||||||
|
|
||||||
d = sin (lat1 * UF) * sin (lat2 * UF);
|
|
||||||
d += cos (lat1 * UF) * cos (lat2 * UF) * cos ((lon2 - lon1) * UF);
|
|
||||||
|
|
||||||
return (acos (d) * EARTHRADIUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
icao2number (char *icao, float frequency, char *buf)
|
|
||||||
{
|
|
||||||
char icao_work[5];
|
|
||||||
|
|
||||||
if (strlen (icao) == 0)
|
|
||||||
strcpy (icao, "ZZZZ");
|
|
||||||
|
|
||||||
sprintf (icao_work, "%4s", icao);
|
|
||||||
sprintf (buf, "%02d%02d%02d%02d%02d%06d", DEFAULT_CODE, icao_work[0],
|
|
||||||
icao_work[1], icao_work[2], icao_work[3],
|
|
||||||
(int) (frequency * 1000 + 0.5));
|
|
||||||
buf[16] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
icao2atisnumber (char *icao, float frequency, char *buf)
|
|
||||||
{
|
|
||||||
char icao_work[5];
|
|
||||||
|
|
||||||
if (strlen (icao) == 0)
|
|
||||||
strcpy (icao, "ZZZZ");
|
|
||||||
|
|
||||||
sprintf (icao_work, "%4s", icao);
|
|
||||||
sprintf (buf, "%02d%02d%02d%02d%02d%06d", ATIS_CODE, icao_work[0],
|
|
||||||
icao_work[1], icao_work[2], icao_work[3],
|
|
||||||
(int) (frequency * 1000 + 0.5));
|
|
||||||
buf[16] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *
|
|
||||||
icaobypos (struct airport *airports, double frequency,
|
|
||||||
double plane_lat, double plane_lon, double range)
|
|
||||||
{
|
|
||||||
double r;
|
|
||||||
int frq = (int) (frequency * 1000 + 0.5);
|
|
||||||
|
|
||||||
if( (frq%10) !=0 && (frq%5) == 0 ){
|
|
||||||
frequency -= 0.005;
|
|
||||||
frequency = ceilf(frequency*1000.0)/1000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frequency >= DEFAULT_LOWER_FRQ_LIMIT
|
|
||||||
&& frequency <= DEFAULT_UPPER_FRQ_LIMIT)
|
|
||||||
{
|
|
||||||
while (airports->next != NULL)
|
|
||||||
{
|
|
||||||
if ( ceilf(airports->frequency*1000.0)/1000.0 == frequency || airports->frequency == frequency)
|
|
||||||
{
|
|
||||||
r = distance(plane_lat, plane_lon, airports->lat, airports->lon);
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "icaobypos() - APT: " << airports->text << " (" << airports->icao << " " << airports->type << ")" );
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "icaobypos() - APT lat: " << airports->lat << " APT lon: " << airports->lon );
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "icaobypos() - Plane lat: " << plane_lat << " Plane lon: " << plane_lon );
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "icaobypos() - Distance to " << airports->icao << ": " << r << " Km" );
|
|
||||||
if (r <= range)
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "Airport " << airports->text << " (" << airports->icao
|
|
||||||
<< " " << airports->type << " at " << frequency << " MHz)"
|
|
||||||
<< " is in range (" << r << " km)" );
|
|
||||||
return (airports->icao);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
airports = airports->next;
|
|
||||||
}
|
|
||||||
return ("");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ("");
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pos
|
|
||||||
posbyicao (struct airport *airports, char *icao)
|
|
||||||
{
|
|
||||||
struct pos p;
|
|
||||||
|
|
||||||
p.lon = 0.0;
|
|
||||||
p.lat = 0.0;
|
|
||||||
|
|
||||||
while (airports->next != NULL)
|
|
||||||
{
|
|
||||||
if (!strcmp (airports->icao, icao))
|
|
||||||
{
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "posbyicao() - APT: " << airports->text << " (" << airports->icao << " " << airports->type << ")" );
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, "posbyicao() - APT lat: " << airports->lat << " APT lon:" << airports->lon );
|
|
||||||
p.lon = airports->lon;
|
|
||||||
p.lat = airports->lat;
|
|
||||||
return (p);
|
|
||||||
}
|
|
||||||
airports = airports->next;
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* fgcom - VoIP-Client for the FlightGear-Radio-Infrastructure
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __POSITION_H__
|
|
||||||
#define __POSITION_H__
|
|
||||||
|
|
||||||
/* Compute distance between two points. */
|
|
||||||
double distance (double lat1, double lon1, double lat2, double lon2);
|
|
||||||
|
|
||||||
/* Build the phone number based on the ICAO code and airport frequency. */
|
|
||||||
void icao2number (char *icao, float frequency, char *buf);
|
|
||||||
void icao2atisnumber (char *icao, float frequency, char *buf);
|
|
||||||
|
|
||||||
/* Search for the closest airport on selected frequency. */
|
|
||||||
const char *
|
|
||||||
icaobypos (struct airport *airports, double frequency, double plane_lat,
|
|
||||||
double plane_lon, double range);
|
|
||||||
|
|
||||||
#endif
|
|
47174
utils/fgcom/positions.hxx
Normal file
47174
utils/fgcom/positions.hxx
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,289 +0,0 @@
|
||||||
/*
|
|
||||||
* fgcom - VoIP-Client for the FlightGear-Radio-Infrastructure
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#include <WinSock2.h> // which included <Windows.h>
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#include <mach-o/dyld.h> /* for _NSGetExecutablePath() */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
#include "fgcom.hxx"
|
|
||||||
|
|
||||||
#ifndef bcopy
|
|
||||||
#define bcopy(from, to, n) memcpy(to, from, n)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int s_index;
|
|
||||||
static int s_file_handle;
|
|
||||||
static char *s_content;
|
|
||||||
static int s_size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* \fn void parser_init(void)
|
|
||||||
*
|
|
||||||
* \brief Starts parser initialization.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int parser_init(const char *filename)
|
|
||||||
{
|
|
||||||
struct stat l_stat;
|
|
||||||
ssize_t l_nbytes;
|
|
||||||
int l_status;
|
|
||||||
int oflag = O_RDONLY;
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
oflag |= _O_BINARY; /* if comparing to stat size then must be binary */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_index = 0;
|
|
||||||
|
|
||||||
if((s_file_handle = open(filename, oflag)) < 0)
|
|
||||||
return (s_file_handle);
|
|
||||||
|
|
||||||
fstat(s_file_handle, &l_stat);
|
|
||||||
|
|
||||||
l_status = -1;
|
|
||||||
if((s_content = (char *)malloc((l_stat.st_size + 1) * sizeof(char))) != NULL)
|
|
||||||
{
|
|
||||||
if((l_nbytes = read(s_file_handle, s_content, l_stat.st_size)) == l_stat.st_size)
|
|
||||||
{
|
|
||||||
l_status = 0;
|
|
||||||
s_size = l_stat.st_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(s_file_handle);
|
|
||||||
|
|
||||||
return(l_status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* \fn void parser_exit(void)
|
|
||||||
*
|
|
||||||
* \brief Exits parser.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void parser_exit(void)
|
|
||||||
{
|
|
||||||
free(s_content);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* \fn int parser_get_next_value(const char *line, float *value)
|
|
||||||
*
|
|
||||||
* \brief Extract a numeric value.
|
|
||||||
*
|
|
||||||
* \param line pointer on the line extracted from the input file.
|
|
||||||
* \param value pointer on the returned value.
|
|
||||||
*
|
|
||||||
* \return Returns 0 if value successfully extracted. Otherwhise, returns
|
|
||||||
* a negative value meaning that an error occured.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int parser_get_next_value(double *value)
|
|
||||||
{
|
|
||||||
int l_status = 0;
|
|
||||||
unsigned int l_j;
|
|
||||||
unsigned int l_size;
|
|
||||||
char *l_buf;
|
|
||||||
|
|
||||||
/* Check if we are already at the end of the string. */
|
|
||||||
if(s_index >= s_size)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
/* Enter main parser loop. */
|
|
||||||
while((s_index < s_size) && (l_status == 0))
|
|
||||||
{
|
|
||||||
/* Search for something different than an espace or tab. */
|
|
||||||
while( (s_content[s_index] == ' ' || s_content[s_index] == '\t') &&
|
|
||||||
(s_index < s_size) )
|
|
||||||
s_index++;
|
|
||||||
|
|
||||||
/* If we have reached end of file, we exit now. */
|
|
||||||
if (s_index >= s_size)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
/* If character is a CR, we restart for next line. */
|
|
||||||
if(s_content[s_index] == '\n')
|
|
||||||
{
|
|
||||||
s_index++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is it a comment ? */
|
|
||||||
if(s_content[s_index] == '#')
|
|
||||||
{
|
|
||||||
/* Yes, go until end of line. */
|
|
||||||
while((s_content[s_index] != '\n') && (s_index < s_size))
|
|
||||||
s_index++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We have found something that is not a comment. */
|
|
||||||
while((s_content[s_index] < '0' || s_content[s_index] > '9') && (s_index < s_size))
|
|
||||||
s_index++;
|
|
||||||
|
|
||||||
if(s_index < s_size)
|
|
||||||
{
|
|
||||||
l_j = s_index + 1;
|
|
||||||
while( ((s_content[l_j] >= '0' && s_content[l_j] <= '9') ||
|
|
||||||
(s_content[l_j] == '.' || s_content[l_j] == ',')) &&
|
|
||||||
((s_content[l_j] != '\n') && (l_j < (unsigned int)s_size)) )
|
|
||||||
l_j++;
|
|
||||||
|
|
||||||
l_size = l_j - s_index + 1;
|
|
||||||
if((l_buf = (char *)malloc(l_size * sizeof(char))) != NULL)
|
|
||||||
{
|
|
||||||
/* Initialize buffer with O. */
|
|
||||||
memset((void *)l_buf, 0, l_size);
|
|
||||||
bcopy((const void *)(s_content + s_index), (void *)l_buf, l_size - 1);
|
|
||||||
/* Convert string into double. */
|
|
||||||
*value = atof(l_buf);
|
|
||||||
/* Buffer is not needed any longer. */
|
|
||||||
free(l_buf);
|
|
||||||
/* Prepare for next value. */
|
|
||||||
s_index = l_j + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* while((s_index < s_size) && (l_status == 0)) */
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cross-platform stat and check if directory or file
|
|
||||||
* return 2 == directory
|
|
||||||
* return 1 == file
|
|
||||||
* return 0 == neither
|
|
||||||
* NOTE: Think this fails in Windows if
|
|
||||||
* the path has a trailing path separator
|
|
||||||
* and in some cases even if the path contains a forward (unix) separator
|
|
||||||
* TODO: Should copy the path, and fix it for stat
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#define M_ISDIR(a) (a & _S_IFDIR)
|
|
||||||
#else
|
|
||||||
#define M_ISDIR S_ISDIR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int is_file_or_directory( const char * path )
|
|
||||||
{
|
|
||||||
struct stat buf;
|
|
||||||
if ( stat(path,&buf) == 0 ) {
|
|
||||||
if (M_ISDIR(buf.st_mode))
|
|
||||||
return 2;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* trim to base binary path IN BUFFER,
|
|
||||||
* essentially removing the executable name
|
|
||||||
*/
|
|
||||||
void trim_base_path_ib( char *path )
|
|
||||||
{
|
|
||||||
size_t len = strlen(path);
|
|
||||||
size_t i, off;
|
|
||||||
int c;
|
|
||||||
off = 0;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
c = path[i];
|
|
||||||
if (( c == '/' ) || ( c == '\\')) {
|
|
||||||
off = i + 1; // get after separator
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
if ( c == '/' )
|
|
||||||
path[i] = '\\';
|
|
||||||
#endif // _MSC_VER
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path[off] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get data path per OS
|
|
||||||
* In Windows and OSX the compiler only supplies a partial data file path,
|
|
||||||
* so this is to get the current binary installed path.
|
|
||||||
* In *nix the full path is supplied, so this does nothing, except zero the path
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int get_data_path_per_os( char *path, size_t len )
|
|
||||||
{
|
|
||||||
#if defined(MACOSX)
|
|
||||||
// if we're running as part of an application bundle, return the bundle's
|
|
||||||
// resources directory
|
|
||||||
// The following code looks for the base package inside the application
|
|
||||||
// bundle, in the standard Contents/Resources location.
|
|
||||||
|
|
||||||
CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
|
|
||||||
if (resourcesUrl) {
|
|
||||||
CFURLGetFileSystemRepresentation(resourcesUrl, true, (UInt8*) path, len);
|
|
||||||
CFRelease(resourcesUrl);
|
|
||||||
// append trailing seperator since CF doesn't
|
|
||||||
len = strlen(path);
|
|
||||||
path[len] = '/';
|
|
||||||
path[len+1] = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're unbundled, simply return the executable path
|
|
||||||
unsigned int size = (unsigned int) len;
|
|
||||||
if (_NSGetExecutablePath(path, &size) == 0) {
|
|
||||||
// success
|
|
||||||
trim_base_path_ib(path);
|
|
||||||
} else {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "ERROR: path buffer too small; need size " << size );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
unsigned int size = GetModuleFileName(NULL,path, len);
|
|
||||||
if (size && (size != len)) {
|
|
||||||
// success
|
|
||||||
trim_base_path_ib(path);
|
|
||||||
} else {
|
|
||||||
if (size) {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "ERROR: GetModuleFileName: path buffer too small; need size more than " << len );
|
|
||||||
} else {
|
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT, "ERROR: GetModuleFileName FAILED!" );
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
path[0] = 0;
|
|
||||||
#endif // MACOSX | _MSC_VER | others
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eof - utils.cpp */
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* fgcom - VoIP-Client for the FlightGear-Radio-Infrastructure
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UTILS_H__
|
|
||||||
#define __UTILS_H__
|
|
||||||
|
|
||||||
/* Initialize the file parser. */
|
|
||||||
int parser_init(const char *filename);
|
|
||||||
|
|
||||||
/* Exits parser. */
|
|
||||||
void parser_exit(void);
|
|
||||||
|
|
||||||
int parser_get_next_value(double *value);
|
|
||||||
|
|
||||||
extern int is_file_or_directory( const char * path ); /* 1=file, 2=dir, else 0 */
|
|
||||||
extern void trim_base_path_ib( char *path ); /* trim to base path IN BUFFER */
|
|
||||||
extern int get_data_path_per_os( char *path, size_t len ); /* get data path per OS - 0=ok, 1=error */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -4,31 +4,6 @@
|
||||||
# 26 sept, 2013 - Clément de l'Hamaide
|
# 26 sept, 2013 - Clément de l'Hamaide
|
||||||
|
|
||||||
|
|
||||||
============================================
|
|
||||||
==== positions.txt =====
|
|
||||||
============================================
|
|
||||||
|
|
||||||
This file is used by fgcom binary, it's a dictionary of
|
|
||||||
available frequency. You can set a specific path with:
|
|
||||||
|
|
||||||
./fgcom --positions=/path/to/positions.txt
|
|
||||||
|
|
||||||
THIS FILE IS REQUIRED TO RUN FGCOM !
|
|
||||||
|
|
||||||
|
|
||||||
============================================
|
|
||||||
==== special_frequencies.txt =====
|
|
||||||
============================================
|
|
||||||
|
|
||||||
This file is used by fgcom binary, it's a dictionary of
|
|
||||||
specific frequency who require to be not associated with
|
|
||||||
and ICAO but use "ZZZZ" instead. You can set a specific path with:
|
|
||||||
|
|
||||||
./fgcom --special=/path/to/special_frequencies.txt
|
|
||||||
|
|
||||||
This file is not required to run FGCom
|
|
||||||
|
|
||||||
|
|
||||||
============================================
|
============================================
|
||||||
==== fgcom.conf =====
|
==== fgcom.conf =====
|
||||||
============================================
|
============================================
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,15 +0,0 @@
|
||||||
#
|
|
||||||
# Special frequencies file. To use any of the frequencies listed here,
|
|
||||||
# there is no need to be closed to an airport.
|
|
||||||
#
|
|
||||||
# Echo test
|
|
||||||
910.000
|
|
||||||
# Radio test
|
|
||||||
911.000
|
|
||||||
700.000
|
|
||||||
# Auto information
|
|
||||||
123.450
|
|
||||||
122.750
|
|
||||||
123.500
|
|
||||||
121.500
|
|
||||||
|
|
Loading…
Reference in a new issue