Compare commits
9 Commits
sm-lastmai
...
AFTER_OPEN
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46a32dd3ee | ||
|
|
ecb4dc57b4 | ||
|
|
89d426470b | ||
|
|
23c7a1b5b7 | ||
|
|
3b21e9434f | ||
|
|
d4a4428e64 | ||
|
|
2dfc057135 | ||
|
|
a25eebef9b | ||
|
|
741c4ca15a |
@@ -322,6 +322,9 @@ sglog()
|
||||
# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl
|
||||
#endif
|
||||
|
||||
#define SG_STRINGIFY(x) #x
|
||||
#define SG_TOSTRING(x) SG_STRINGIFY(x)
|
||||
#define SG_ORIGIN __FILE__ ":" SG_TOSTRING(__LINE__)
|
||||
|
||||
#endif // _LOGSTREAM_H
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Visual environment helper class
|
||||
//
|
||||
// Written by Harald JOHNSEN, started April 2005.
|
||||
// Minor changes/additions by Vivian Meazza Apr- May 2007
|
||||
//
|
||||
// Ported to OSG by Tim Moore Jun 2007
|
||||
//
|
||||
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
|
||||
//
|
||||
@@ -334,7 +331,7 @@ void SGEnviro::setLight(sgVec4 adj_fog_color) {
|
||||
}
|
||||
}
|
||||
|
||||
void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family, float dist, int cloudId) {
|
||||
void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
|
||||
// send data to wx radar
|
||||
// compute turbulence
|
||||
// draw precipitation
|
||||
@@ -409,7 +406,7 @@ void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family
|
||||
|
||||
// add to the list for the wxRadar instrument
|
||||
if( LWC > 0.0 )
|
||||
radarEcho.push_back( SGWxRadarEcho ( bearing, alt, radius, dist, 0.0 , LWC, false, cloudId, false ) );
|
||||
radarEcho.push_back( SGWxRadarEcho ( heading, alt, radius, dist, LWC, false, cloudId ) );
|
||||
|
||||
// NB:data valid only from cockpit view
|
||||
|
||||
@@ -422,7 +419,7 @@ void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family
|
||||
orig.setlon(last_lon * SG_DEGREES_TO_RADIANS );
|
||||
orig.setelev(0.0);
|
||||
dist = sgSqrt(dist);
|
||||
dest = calc_gc_lon_lat(orig, bearing, dist);
|
||||
dest = calc_gc_lon_lat(orig, heading, dist);
|
||||
lon = dest.lon() * SG_RADIANS_TO_DEGREES;
|
||||
lat = dest.lat() * SG_RADIANS_TO_DEGREES;
|
||||
addLightning( lon, lat, alt );
|
||||
@@ -714,7 +711,7 @@ void SGLightning::lt_Render(void) {
|
||||
|
||||
glTranslatef( ax, ay, -sgEnviro.last_alt );
|
||||
|
||||
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, 0.0, age, true, 0, false ) );
|
||||
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, age, true, 0 ) );
|
||||
|
||||
for( int n = 0 ; n < nb_tree ; n++ ) {
|
||||
if( lt_tree[n].prev < 0 )
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Visual environment helper class
|
||||
//
|
||||
// Written by Harald JOHNSEN, started April 2005.
|
||||
// Minor changes/additions by Vivian Meazza Apr- May 2007
|
||||
//
|
||||
// Ported to OSG by Tim Moore Jun 2007
|
||||
//
|
||||
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
|
||||
//
|
||||
@@ -43,32 +40,24 @@ class SGSoundMgr;
|
||||
*/
|
||||
class SGWxRadarEcho {
|
||||
public:
|
||||
SGWxRadarEcho(float _bearing, float _alt, float _radius, float _dist, float _heading,
|
||||
double _LWC, bool _lightning, int _cloudId, bool _aircraft) :
|
||||
bearing (_bearing),
|
||||
SGWxRadarEcho(float _heading, float _alt, float _radius, float _dist,
|
||||
double _LWC, bool _lightning, int _cloudId ) :
|
||||
heading( _heading ),
|
||||
alt ( _alt ),
|
||||
radius ( _radius ),
|
||||
dist ( _dist ),
|
||||
LWC ( _LWC ),
|
||||
lightning ( _lightning ),
|
||||
aircraft ( _aircraft ),
|
||||
cloudId ( _cloudId )
|
||||
{}
|
||||
|
||||
/** the heading and bearing in radian are versus north */
|
||||
float bearing, heading;
|
||||
/** the heading in radian is versus north */
|
||||
float heading;
|
||||
float alt, radius, dist;
|
||||
|
||||
/** reflectivity converted to liquid water content. */
|
||||
double LWC;
|
||||
|
||||
/** if true then this data is for a lightning else it is for water echo. */
|
||||
bool lightning;
|
||||
|
||||
/** if true then this data is for an aircraft */
|
||||
bool aircraft;
|
||||
|
||||
bool lightning;
|
||||
/** Unique identifier of cloud */
|
||||
int cloudId;
|
||||
};
|
||||
|
||||
@@ -116,7 +116,7 @@ parse_name (const string &path, int &i)
|
||||
name = ".";
|
||||
}
|
||||
if (i < max && path[i] != '/')
|
||||
throw string("Illegal character after " + name);
|
||||
throw string("illegal character after " + name);
|
||||
}
|
||||
|
||||
else if (isalpha(path[i]) || path[i] == '_') {
|
||||
@@ -295,7 +295,7 @@ find_node (SGPropertyNode * current,
|
||||
else if (components[position].name == "..") {
|
||||
SGPropertyNode * parent = current->getParent();
|
||||
if (parent == 0)
|
||||
throw string("Attempt to move past root with '..'");
|
||||
throw string("attempt to move past root with '..'");
|
||||
else
|
||||
return find_node(parent, components, position + 1, create);
|
||||
}
|
||||
@@ -739,7 +739,11 @@ SGPropertyNode::SGPropertyNode (const char * name,
|
||||
_attr(READ|WRITE),
|
||||
_listeners(0)
|
||||
{
|
||||
_name = name;
|
||||
int i = 0;
|
||||
_name = parse_name(name, i);
|
||||
if (i != int(strlen(name)) || name[0] == '.')
|
||||
throw string("plain name expected instead of '") + name + '\'';
|
||||
|
||||
_local_val.string_val = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,13 +32,10 @@
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
|
||||
#include <simgear/route/waypoint.hxx>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
// Constructor
|
||||
SGWayPoint::SGWayPoint( const double lon, const double lat, const double alt,
|
||||
const modetype m, const string s, const string n ) {
|
||||
const modetype m, const string& s, const string& n ) {
|
||||
target_lon = lon;
|
||||
target_lat = lat;
|
||||
target_alt = alt;
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
*/
|
||||
SGWayPoint( const double lon = 0.0, const double lat = 0.0,
|
||||
const double alt = 0.0, const modetype m = WGS84,
|
||||
const string s = "", const string n = "" );
|
||||
const string& s = "", const string& n = "" );
|
||||
|
||||
/** Destructor */
|
||||
~SGWayPoint();
|
||||
|
||||
@@ -75,12 +75,17 @@ SGSoundSample::SGSoundSample() :
|
||||
reference_dist(500.0),
|
||||
max_dist(3000.),
|
||||
loop(AL_FALSE),
|
||||
playing(false)
|
||||
#ifdef USE_SOFTWARE_DOPPLER
|
||||
doppler_pitch_factor(1),
|
||||
doppler_volume_factor(1),
|
||||
#endif
|
||||
playing(false),
|
||||
no_Doppler_effect(true)
|
||||
{
|
||||
}
|
||||
|
||||
// constructor
|
||||
SGSoundSample::SGSoundSample( const char *path, const char *file) :
|
||||
SGSoundSample::SGSoundSample( const char *path, const char *file, bool _no_Doppler_effect ) :
|
||||
buffer(0),
|
||||
source(0),
|
||||
pitch(1.0),
|
||||
@@ -88,7 +93,12 @@ SGSoundSample::SGSoundSample( const char *path, const char *file) :
|
||||
reference_dist(500.0),
|
||||
max_dist(3000.),
|
||||
loop(AL_FALSE),
|
||||
playing(false)
|
||||
#ifdef USE_SOFTWARE_DOPPLER
|
||||
doppler_pitch_factor(1),
|
||||
doppler_volume_factor(1),
|
||||
#endif
|
||||
playing(false),
|
||||
no_Doppler_effect(_no_Doppler_effect)
|
||||
{
|
||||
SGPath samplepath( path );
|
||||
if ( strlen(file) ) {
|
||||
@@ -145,7 +155,7 @@ SGSoundSample::SGSoundSample( const char *path, const char *file) :
|
||||
}
|
||||
|
||||
// constructor
|
||||
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq ) :
|
||||
SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq, bool _no_Doppler_effect ) :
|
||||
buffer(0),
|
||||
source(0),
|
||||
pitch(1.0),
|
||||
@@ -153,7 +163,12 @@ SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq ) :
|
||||
reference_dist(500.0),
|
||||
max_dist(3000.),
|
||||
loop(AL_FALSE),
|
||||
playing(false)
|
||||
#ifdef USE_SOFTWARE_DOPPLER
|
||||
doppler_pitch_factor(1),
|
||||
doppler_volume_factor(1),
|
||||
#endif
|
||||
playing(false),
|
||||
no_Doppler_effect(_no_Doppler_effect)
|
||||
{
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" );
|
||||
|
||||
@@ -247,14 +262,23 @@ SGSoundSample::bind_source() {
|
||||
}
|
||||
|
||||
alSourcei( source, AL_BUFFER, buffer );
|
||||
#ifndef USE_SOFTWARE_DOPPLER
|
||||
alSourcef( source, AL_PITCH, pitch );
|
||||
alSourcef( source, AL_GAIN, volume );
|
||||
#else
|
||||
print_openal_error("bind_sources return");
|
||||
alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
|
||||
alGetError(); // ignore if the pitch is clamped by the driver
|
||||
alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
|
||||
#endif
|
||||
alSourcefv( source, AL_POSITION, source_pos );
|
||||
alSourcefv( source, AL_DIRECTION, direction );
|
||||
alSourcef( source, AL_CONE_INNER_ANGLE, inner );
|
||||
alSourcef( source, AL_CONE_OUTER_ANGLE, outer );
|
||||
alSourcef( source, AL_CONE_OUTER_GAIN, outergain);
|
||||
#ifdef USE_OPEN_AL_DOPPLER
|
||||
alSourcefv( source, AL_VELOCITY, source_vel );
|
||||
#endif
|
||||
alSourcei( source, AL_LOOPING, loop );
|
||||
|
||||
alSourcei( source, AL_SOURCE_RELATIVE, AL_TRUE );
|
||||
@@ -273,8 +297,13 @@ SGSoundSample::set_pitch( double p ) {
|
||||
if ( p > 2.0 ) { p = 2.0; }
|
||||
pitch = p;
|
||||
if (playing) {
|
||||
#ifndef USE_SOFTWARE_DOPPLER
|
||||
alSourcef( source, AL_PITCH, pitch );
|
||||
print_openal_error("set_pitch");
|
||||
#else
|
||||
alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
|
||||
alGetError(); // ignore if the pitch is clamped by the driver
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,7 +311,11 @@ void
|
||||
SGSoundSample::set_volume( double v ) {
|
||||
volume = v;
|
||||
if (playing) {
|
||||
#ifndef USE_SOFTWARE_DOPPLER
|
||||
alSourcef( source, AL_GAIN, volume );
|
||||
#else
|
||||
alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
|
||||
#endif
|
||||
print_openal_error("set_volume");
|
||||
}
|
||||
}
|
||||
@@ -313,6 +346,7 @@ SGSoundSample::set_source_pos( ALfloat *pos ) {
|
||||
sgAddVec3( final_pos, source_pos, offset_pos );
|
||||
|
||||
alSourcefv( source, AL_POSITION, final_pos );
|
||||
print_openal_error("set_source_pos");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,6 +361,7 @@ SGSoundSample::set_offset_pos( ALfloat *pos ) {
|
||||
sgAddVec3( final_pos, source_pos, offset_pos );
|
||||
|
||||
alSourcefv( source, AL_POSITION, final_pos );
|
||||
print_openal_error("set_offset_pos");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,13 +385,85 @@ SGSoundSample::set_orientation( ALfloat *dir, ALfloat inner_angle,
|
||||
}
|
||||
|
||||
void
|
||||
SGSoundSample::set_source_vel( ALfloat *vel ) {
|
||||
source_vel[0] = vel[0];
|
||||
source_vel[1] = vel[1];
|
||||
source_vel[2] = vel[2];
|
||||
SGSoundSample::set_source_vel( ALfloat *vel, ALfloat *listener_vel ) {
|
||||
if (no_Doppler_effect) {
|
||||
source_vel[0] = listener_vel[0];
|
||||
source_vel[1] = listener_vel[1];
|
||||
source_vel[2] = listener_vel[2];
|
||||
} else {
|
||||
source_vel[0] = vel[0];
|
||||
source_vel[1] = vel[1];
|
||||
source_vel[2] = vel[2];
|
||||
}
|
||||
#ifdef USE_OPEN_AL_DOPPLER
|
||||
if (playing) {
|
||||
alSourcefv( source, AL_VELOCITY, source_vel );
|
||||
}
|
||||
#elif defined (USE_OPEN_AL_DOPPLER_WITH_FIXED_LISTENER)
|
||||
if (playing) {
|
||||
sgVec3 relative_vel;
|
||||
sgSubVec3( relative_vel, source_vel, listener_vel );
|
||||
alSourcefv( source, AL_VELOCITY, relative_vel );
|
||||
}
|
||||
#else
|
||||
if (no_Doppler_effect) {
|
||||
doppler_pitch_factor = 1;
|
||||
doppler_volume_factor = 1;
|
||||
return;
|
||||
}
|
||||
double doppler, mfp;
|
||||
sgVec3 final_pos;
|
||||
sgAddVec3( final_pos, source_pos, offset_pos );
|
||||
mfp = sgLengthVec3(final_pos);
|
||||
if (mfp > 1e-6) {
|
||||
double vls = -sgScalarProductVec3( listener_vel, final_pos ) / mfp;
|
||||
double vss = -sgScalarProductVec3( source_vel, final_pos ) / mfp;
|
||||
if (fabs(340 - vss) > 1e-6)
|
||||
{
|
||||
doppler = (340 - vls) / (340 - vss);
|
||||
doppler = ( doppler > 0) ? ( ( doppler < 10) ? doppler : 10 ) : 0;
|
||||
}
|
||||
else
|
||||
doppler = 0;
|
||||
}
|
||||
else
|
||||
doppler = 1;
|
||||
/* the OpenAL documentation of the Doppler calculation
|
||||
SS: AL_SPEED_OF_SOUND = speed of sound (default value 343.3)
|
||||
DF: AL_DOPPLER_FACTOR = Doppler factor (default 1.0)
|
||||
vls: Listener velocity scalar (scalar, projected on source-to-listener vector)
|
||||
vss: Source velocity scalar (scalar, projected on source-to-listener vector)
|
||||
SL = source to listener vector
|
||||
SV = Source Velocity vector
|
||||
LV = Listener Velocity vector
|
||||
vls = DotProduct(SL, LV) / Mag(SL)
|
||||
vss = DotProduct(SL, SV) / Mag(SL)
|
||||
Dopper Calculation:
|
||||
vss = min(vss, SS/DF)
|
||||
vls = min(vls, SS/DF)
|
||||
f' = f * (SS - DF*vls) / (SS - DF*vss)
|
||||
*/
|
||||
if (doppler > 0.1) {
|
||||
if (doppler < 10) {
|
||||
doppler_pitch_factor = doppler;
|
||||
doppler_volume_factor = 1;
|
||||
}
|
||||
else {
|
||||
doppler_pitch_factor = (doppler < 11) ? doppler : 11;
|
||||
doppler_volume_factor = (doppler < 11) ? 11-doppler : 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
doppler_pitch_factor = 0.1;
|
||||
doppler_volume_factor = (doppler > 0) ? doppler * 10 : 0;
|
||||
}
|
||||
if (playing) {
|
||||
alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
|
||||
print_openal_error("set_source_vel: volume");
|
||||
alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
|
||||
alGetError(); //ignore if the pitch is clamped
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -52,6 +52,17 @@
|
||||
# include <AL/alut.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WINDOWS_H
|
||||
#ifdef AL_VERSION_1_2
|
||||
#define USE_OPEN_AL_DOPPLER should work
|
||||
#else
|
||||
#define USE_OPEN_AL_DOPPLER_WITH_FIXED_LISTENER better than nothing
|
||||
#endif
|
||||
#else
|
||||
// the Open_AL Doppler calculation seems to be buggy on windows
|
||||
#define USE_SOFTWARE_DOPPLER seem to be necessary
|
||||
#endif
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
/**
|
||||
@@ -90,12 +101,17 @@ private:
|
||||
|
||||
double pitch;
|
||||
double volume;
|
||||
#ifdef USE_SOFTWARE_DOPPLER
|
||||
double doppler_pitch_factor;
|
||||
double doppler_volume_factor;
|
||||
#endif
|
||||
double reference_dist;
|
||||
double max_dist;
|
||||
ALboolean loop;
|
||||
|
||||
bool playing;
|
||||
bool bind_source();
|
||||
bool no_Doppler_effect;
|
||||
|
||||
public:
|
||||
|
||||
@@ -112,7 +128,7 @@ public:
|
||||
should usually be true unless you want to manipulate the data
|
||||
later.)
|
||||
*/
|
||||
SGSoundSample( const char *path, const char *file );
|
||||
SGSoundSample( const char *path, const char *file, bool no_Doppler_effect = true );
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -123,7 +139,7 @@ public:
|
||||
should usually be true unless you want to manipulate the data
|
||||
later.)
|
||||
*/
|
||||
SGSoundSample( unsigned char *_data, int len, int _freq );
|
||||
SGSoundSample( unsigned char *_data, int len, int _freq, bool no_Doppler_effect = true );
|
||||
|
||||
~SGSoundSample();
|
||||
|
||||
@@ -208,7 +224,7 @@ public:
|
||||
/**
|
||||
* Set velocity of sound source (uses same coordinate system as opengl)
|
||||
*/
|
||||
void set_source_vel( ALfloat *vel );
|
||||
void set_source_vel( ALfloat *vel, ALfloat *listener_vel );
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -345,6 +345,6 @@ void SGSoundMgr::set_source_vel_all( ALfloat *vel ) {
|
||||
sample_map_iterator sample_end = samples.end();
|
||||
for ( ; sample_current != sample_end; ++sample_current ) {
|
||||
SGSoundSample *sample = sample_current->second;
|
||||
sample->set_source_vel( vel );
|
||||
sample->set_source_vel( vel, listener_vel );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +206,9 @@ public:
|
||||
listener_vel[0] = vel[0];
|
||||
listener_vel[1] = vel[1];
|
||||
listener_vel[2] = vel[2];
|
||||
#ifdef USE_OPEN_AL_DOPPLER
|
||||
alListenerfv( AL_VELOCITY, listener_vel );
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -272,7 +272,8 @@ SGXmlSound::init(SGPropertyNode *root, SGPropertyNode *node, SGSoundMgr *sndmgr,
|
||||
// "alSource". The semantics of what is going on here seems
|
||||
// confused and needs to be thought through more carefully.
|
||||
_sample = new SGSoundSample( path.c_str(),
|
||||
node->getStringValue("path", "") );
|
||||
node->getStringValue("path", ""),
|
||||
false );
|
||||
|
||||
_mgr->add( _sample, _name );
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include "lowleveltime.h"
|
||||
|
||||
|
||||
@@ -331,19 +334,18 @@ static void fgtzset_internal (int always, const char *tz)
|
||||
fgtzfile_read (tz);
|
||||
if (use_fgtzfile)
|
||||
return;
|
||||
// The default behaviour of the originale tzset_internal (int always, char* tz)
|
||||
// function is to set up a default timezone, in any casetz file_read() fails
|
||||
// Currently this leads to problems, because it modidifies the system timezone
|
||||
// The default behaviour of the original tzset_internal (int always, char* tz)
|
||||
// function is to set up a default timezone, in any case file_read() fails
|
||||
// Currently this leads to problems, because it modifies the system timezone
|
||||
// and not the local aircraft timezone, contained in FlightGear. I could adapt
|
||||
// this in future versions of this code, but doubt whether this is what we really
|
||||
// want. So right now, exit when timezone information reading failed.
|
||||
// want. So right now, throw an exception when timezone information reading failed.
|
||||
// Guess I'll change that to something like 12 * (FG_LON / 180.0)
|
||||
//
|
||||
// For now, I'll leave it like this.
|
||||
else
|
||||
{
|
||||
printf ("Timezone reading failed\n");
|
||||
exit(1);
|
||||
throw sg_exception("Timezone reading failed");
|
||||
}
|
||||
// this emacs "comment out" function is cool!
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include "timezone.h"
|
||||
|
||||
SGTimeZone::SGTimeZone(float la, float lo, char* cc, char* desc) :
|
||||
@@ -126,8 +129,9 @@ SGTimeZoneContainer::SGTimeZoneContainer(const char *filename)
|
||||
char buffer[256];
|
||||
FILE* infile = fopen(filename, "rb");
|
||||
if (!(infile)) {
|
||||
fprintf(stderr, "Unable to open file %s\n", filename);
|
||||
exit(1);
|
||||
string e = "Unable to open time zone file '";
|
||||
throw sg_exception(e + filename + '\'');
|
||||
|
||||
} else {
|
||||
errno = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user