Changeset 247 for cpp/common


Ignore:
Timestamp:
11/07/14 17:51:01 (9 years ago)
Author:
Maciej Komosinski
Message:

Sources support both 32-bit and 64-bit, and more compilers

Location:
cpp/common
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • cpp/common/Convert.cpp

    r197 r247  
    88
    99#if defined __ANDROID__ || defined __BORLANDC__
    10  #include <ctype.h> //toupper, tolower
     10#include <ctype.h> //toupper, tolower
    1111#endif
    1212
    1313#ifdef SHP
    14  #include <cstdlib>
     14#include <cstdlib>
    1515#else
    16  #include <stdlib.h>
     16#include <stdlib.h>
    1717#endif
    1818
     
    2020
    2121
    22 int Convert::toInt(string s) {return atoi(s.c_str());}
    23 float Convert::toFloat(string s) {return (float)atof(s.c_str());}
    24 #ifndef __BORLANDC__ //the borland compiler compiles this file in GUI and CLI, but not in the theater app. Somehow it cannot find ::tolower and ::toupper; maybe this is because of various #defines in <cctype>, but why only in the theater app??
    25 string Convert::toLowerCase(string s) {std::transform(s.begin(), s.end(), s.begin(), ::tolower);  return s;}
    26 string Convert::toUpperCase(string s) {std::transform(s.begin(), s.end(), s.begin(), ::toupper);  return s;}
    27 #endif
    28 char Convert::toLowerCase(char c) {return (char)tolower(c);}
    29 char Convert::toUpperCase(char c) {return (char)toupper(c);}
     22int Convert::toInt(string s) { return atoi(s.c_str()); }
     23float Convert::toFloat(string s) { return (float)atof(s.c_str()); }
     24string Convert::toLowerCase(string s) { std::transform(s.begin(), s.end(), s.begin(), ::tolower);  return s; }
     25string Convert::toUpperCase(string s) { std::transform(s.begin(), s.end(), s.begin(), ::toupper);  return s; }
     26char Convert::toLowerCase(char c) { return (char)tolower(c); }
     27char Convert::toUpperCase(char c) { return (char)toupper(c); }
    3028
    31 template<class T> const char* printf_format_for(const T& value) {return "unknown type";}
    32 template<> const char* printf_format_for(const unsigned int& value) {return "%u";}
    33 template<> const char* printf_format_for(const int& value) {return "%d";}
    34 template<> const char* printf_format_for(const short& value) {return "%d";}
    35 template<> const char* printf_format_for(const float& value) {return "%g";}
    36 template<> const char* printf_format_for(const double& value) {return "%g";}
     29template<class T> const char* printf_format_for(const T& value) { return "unknown type"; }
     30template<> const char* printf_format_for(const unsigned int& value) { return "%u"; }
     31template<> const char* printf_format_for(const int& value) { return "%d"; }
     32template<> const char* printf_format_for(const short& value) { return "%d"; }
     33template<> const char* printf_format_for(const float& value) { return "%g"; }
     34template<> const char* printf_format_for(const double& value) { return "%g"; }
    3735
    3836template<class T> string Convert::_toString(const T& value)
    3937{
    40 char buf[30];
    41 sprintf(buf,printf_format_for(value),value);
    42 return string(buf);
    43 /*
    44 #ifndef MULTITHREADED
     38        char buf[30];
     39        sprintf(buf, printf_format_for(value), value);
     40        return string(buf);
     41        /*
     42        #ifndef MULTITHREADED
    4543        static
    46 #endif
     44        #endif
    4745        std::ostringstream oss; //pod VS tworzenie go trwa dlugo nawet w wersji release (szczegolnie jak np konwertuje sie cos setki tysiecy razy)
    4846        //dlatego robimy go raz (static) i potem tylko czyscimy
     
    5149        oss.clear(); //clear error flag
    5250        oss.str(""); //set empty string
    53   oss << value;
    54   return oss.str();
    55 */
     51        oss << value;
     52        return oss.str();
     53        */
    5654}
    5755
    58 string Convert::toString(unsigned int v) {return _toString(v);}
    59 string Convert::toString(int v) {return _toString(v);}
    60 string Convert::toString(short v) {return _toString(v);}
    61 string Convert::toString(float v) {return _toString(v);}
    62 string Convert::toString(double v) {return _toString(v);}
     56string Convert::toString(unsigned int v) { return _toString(v); }
     57string Convert::toString(int v) { return _toString(v); }
     58string Convert::toString(short v) { return _toString(v); }
     59string Convert::toString(float v) { return _toString(v); }
     60string Convert::toString(double v) { return _toString(v); }
     61
     62uint32_t Convert::hexToInt(const string& col)
     63{
     64        uint32_t value;
     65        std::istringstream iss(col);
     66        iss >> std::hex >> value;
     67        return value;
     68}
    6369
    6470#ifdef MULTITHREADED
     
    6975//z mutexa gdy drugi dalej by go inicjalizowal
    7076#include "threads.h"
    71 static pthread_mutex_t fix_unsafe_mutex=PTHREAD_MUTEX_INITIALIZER;
     77static pthread_mutex_t fix_unsafe_mutex = PTHREAD_MUTEX_INITIALIZER;
    7278#endif
    7379
     
    7682#ifndef MULTITHREADED
    7783
    78 return *::localtime(&timep);
     84        return *::localtime(&timep);
    7985
    8086#else
    8187
    82 struct tm ret;
     88        struct tm ret;
    8389
    8490#if defined LINUX // || android?
    85 return *::localtime_r(&timep,&ret);
     91        return *::localtime_r(&timep,&ret);
    8692#elif defined _WIN32 && !defined __BORLANDC__ // and not bada?
    87 ::localtime_s(&ret,&timep);
    88 return ret;
     93        ::localtime_s(&ret, &timep);
     94        return ret;
    8995#else //borland?
    90 pthread_mutex_lock(&fix_unsafe_mutex);
    91 ret=*::localtime(&timep);
    92 pthread_mutex_unlock(&fix_unsafe_mutex);
    93 return ret;
     96        pthread_mutex_lock(&fix_unsafe_mutex);
     97        ret=*::localtime(&timep);
     98        pthread_mutex_unlock(&fix_unsafe_mutex);
     99        return ret;
    94100#endif
    95101
     
    99105string Convert::asctime(const struct tm &tm)
    100106{
    101 char *ret;
     107        char *ret;
    102108#ifndef MULTITHREADED
    103109
    104 ret=::asctime(&tm);
     110        ret=::asctime(&tm);
    105111
    106112#else //MULTITHREADED
    107113
    108 char buf[26];
     114        char buf[26];
    109115#if defined LINUX // || android?
    110 ret=::asctime_r(&tm,buf);
     116        ret=::asctime_r(&tm,buf);
    111117#elif defined _WIN32 && !defined __BORLANDC__ // and not bada?
    112 asctime_s(buf,sizeof(buf),&tm);
    113 ret=buf;
     118        asctime_s(buf, sizeof(buf), &tm);
     119        ret = buf;
    114120#else //borland?
    115 pthread_mutex_lock(&fix_unsafe_mutex);
    116 strcpy(buf,::asctime(&tm));
    117 ret=buf;
    118 pthread_mutex_unlock(&fix_unsafe_mutex);
     121        pthread_mutex_lock(&fix_unsafe_mutex);
     122        strcpy(buf,::asctime(&tm));
     123        ret=buf;
     124        pthread_mutex_unlock(&fix_unsafe_mutex);
    119125#endif
    120126#endif
    121127
    122 return string(ret,24); //24 znaki z pominieciem ostatniego \n
     128        return string(ret, 24); //24 znaki z pominieciem ostatniego \n
    123129}
    124 
  • cpp/common/Convert.h

    r197 r247  
    1010#include "nonstd_stl.h"
    1111#include "2d.h"
     12#include <stdint.h>
     13
    1214
    1315typedef XY<double> Pt2D;
     
    1719{
    1820public:
    19   static int toInt(string s);
    20   static float toFloat(string s);
    21   static string toLowerCase(string s);
    22   static string toUpperCase(string s);
    23   static char toLowerCase(char c);
    24   static char toUpperCase(char c);
    25   template<class T> static string _toString(const T& value);
    26   static string toString(unsigned int v);
    27   static string toString(int v);
    28   static string toString(short v);
    29   static string toString(float v);
    30   static string toString(double v);// ze niby w badzie ma nie byc? ale w frams na pewno ma byc bo tu same double
    31   static string zeroPad(string s,int l) {while((int)s.length()<l) s=string("0")+s; return s;}
     21        static int toInt(string s);
     22        static float toFloat(string s);
     23        static string toLowerCase(string s);
     24        static string toUpperCase(string s);
     25        static char toLowerCase(char c);
     26        static char toUpperCase(char c);
     27        template<class T> static string _toString(const T& value);
     28        static string toString(unsigned int v);
     29        static string toString(int v);
     30        static string toString(short v);
     31        static string toString(float v);
     32        static string toString(double v);
     33        static string zeroPad(string s, int l) { while ((int)s.length() < l) s = string("0") + s; return s; }
     34        static uint32_t hexToInt(const string& col);
    3235
    33   static double toRadians(double kat) {return kat*M_PI/180;}
    34   static double toDegrees(double kat) {return kat/M_PI*180;}
    35   static double atan_2(double y,double x) {if (x==0 && y==0) return 0; else return atan2(y,x);} //needed by borland 5/6 only?
     36        static double toRadians(double angle) { return angle*M_PI / 180; }
     37        static double toDegrees(double angle) { return angle / M_PI * 180; }
     38        static double atan_2(double y, double x) { if (x == 0 && y == 0) return 0; else return atan2(y, x); } //needed by borland 5/6 only?
    3639
    37         static double odleglosc_sq(double x1,double y1,double x2,double y2) //odleglosc do kwadratu, wystarczy do porownywania
    38         {double dx=x2-x1, dy=y2-y1; return dx*dx+dy*dy;}
    39         static double odleglosc_sq(const Pt2D& p1,const Pt2D& p2) //odleglosc do kwadratu
    40         {return odleglosc_sq(p1.x,p1.y,p2.x,p2.y);}
     40        static double odleglosc_sq(double x1, double y1, double x2, double y2) //odleglosc do kwadratu, wystarczy do porownywania
     41        {
     42                double dx = x2 - x1, dy = y2 - y1; return dx*dx + dy*dy;
     43        }
     44        static double odleglosc_sq(const Pt2D& p1, const Pt2D& p2) //odleglosc do kwadratu
     45        {
     46                return odleglosc_sq(p1.x, p1.y, p2.x, p2.y);
     47        }
    4148
    42         static double odleglosc(double x1,double y1,double x2,double y2)        {return sqrt(odleglosc_sq(x1,y1,x2,y2));}
    43         static double odleglosc(const Pt2D& p1,const Pt2D& p2)
    44         {return sqrt(odleglosc_sq(p1,p2));}
    45        
    46   //static float odleglosc(int x1,int y1,int x2,int y2) {float dx=x1-x2; float dy=y1-y2; return sqrt(dx*dx+dy*dy);}
    47   //static float odleglosc(float x1,float y1,float x2,float y2) {return sqrt(odleglosc_sq(x1,y1,x2,y2));}
    48   //static float odleglosc_sq(float x1,float y1,float x2,float y2) {float dx=x1-x2; float dy=y1-y2; return dx*dx+dy*dy;}
     49        static double odleglosc(double x1, double y1, double x2, double y2)     { return sqrt(odleglosc_sq(x1, y1, x2, y2)); }
     50        static double odleglosc(const Pt2D& p1, const Pt2D& p2)
     51        {
     52                return sqrt(odleglosc_sq(p1, p2));
     53        }
    4954
    50   static struct tm localtime(const time_t &timep);//jak ::localtime ale zwraca strukture zamiast wskaznika, ref w parametrze dla wygodnego wywolywania
    51   static string asctime(const struct tm &tm);//jak ::asctime ale thread safe i bez glupiego \n na koncu, ref w parametrze dla wygodnego wywolywania
     55        //static float odleglosc(int x1,int y1,int x2,int y2) {float dx=x1-x2; float dy=y1-y2; return sqrt(dx*dx+dy*dy);}
     56        //static float odleglosc(float x1,float y1,float x2,float y2) {return sqrt(odleglosc_sq(x1,y1,x2,y2));}
     57        //static float odleglosc_sq(float x1,float y1,float x2,float y2) {float dx=x1-x2; float dy=y1-y2; return dx*dx+dy*dy;}
     58
     59        static struct tm localtime(const time_t &timep);//jak ::localtime ale zwraca strukture zamiast wskaznika, ref w parametrze dla wygodnego wywolywania
     60        static string asctime(const struct tm &tm);//jak ::asctime ale thread safe i bez glupiego \n na koncu, ref w parametrze dla wygodnego wywolywania
     61
     62        static std::wstring strTOwstr(const char *s)
     63        {
     64                string str(s);
     65                return std::wstring(str.begin(), str.end());
     66        }
     67
     68        static string wstrTOstr(const wchar_t *s)
     69        {
     70                wstring str(s);
     71                return string(str.begin(), str.end());
     72        }
     73
     74        static string wstrTOutf8(const wchar_t *s)
     75        {
     76                if (s == NULL) return "";
     77                string res;
     78                wchar_t *wcp = (wchar_t*)s;
     79                while (*wcp != 0)
     80                {
     81                        int c = *wcp;
     82                        if (c < 0x80) res += c;
     83                        else if (c < 0x800) { res += 192 + c / 64; res += 128 + c % 64; }
     84                        else if (c - 0xd800u < 0x800) res += "<ERR-CHAR>";
     85                        else if (c < 0x10000) { res += 224 + c / 4096; res += 128 + c / 64 % 64; res += 128 + c % 64; }
     86                        else if (c < 0x110000) { res += 240 + c / 262144; res += 128 + c / 4096 % 64; res += 128 + c / 64 % 64; res += 128 + c % 64; }
     87                        else res += "<ERR-CHAR>";
     88                        wcp++;
     89                }
     90                return res;
     91        }
     92        //#endif
    5293};
    5394
    5495
    5596
    56 struct Kat //znormalizowany k¹t w radianach [0,2pi) i stopniach [0,360) z obliczonymi sinus i cosinus oraz intem [0,359]
     97struct Angle //normalized angle in radians [0,2pi) and degrees [0,360) with pre-computed sine and cosine and degree as integer [0,359]
    5798{
    5899private:
    59         double kat; //w radianach, read-only
     100        double angle; //in radians, read-only
    60101public:
    61         double kat_stopnie; //read-only
    62         int kat_stopnie_int; //read-only
     102        double angle_deg; //read-only
     103        int angle_deg_int; //read-only
    63104
    64         Kat() {set(0);}
    65         Kat(double k) {set(k);}
    66         Kat(Kat &kt) {set(kt.get());}
    67         Kat(double dy,double dx) {set(dy,dx);}
    68         void set(double k) {k=fmod(k,M_PI*2); if (k<0) k+=M_PI*2; kat=k; sinus=sin(k); cosinus=cos(k); kat_stopnie=Convert::toDegrees(kat); kat_stopnie_int=roundToInt(kat_stopnie); kat_stopnie_int%=360; }
    69         void set(double dy,double dx) {set(Convert::atan_2(dy,dx));}
    70         void add(double dk) {set(kat+dk);}
    71         void add(Kat &kt) {set(kat+kt.get());}
    72         double get() {return kat;}
    73         double sinus,cosinus;
     105        Angle() { set(0); }
     106        Angle(double k) { set(k); }
     107        Angle(Angle &kt) { set(kt.get()); }
     108        Angle(double dy, double dx) { set(dy, dx); }
     109        void set(double k) { k = fmod(k, M_PI * 2); if (k < 0) k += M_PI * 2; angle = k; sine = sin(k); cosine = cos(k); angle_deg = Convert::toDegrees(angle); angle_deg_int = roundToInt(angle_deg); angle_deg_int %= 360; }
     110        void set(double dy, double dx) { set(Convert::atan_2(dy, dx)); }
     111        void add(double dk) { set(angle + dk); }
     112        void add(Angle &kt) { set(angle + kt.get()); }
     113        double get() { return angle; }
     114        double sine, cosine;
    74115};
    75116
  • cpp/common/nonstd.h

    r244 r247  
    5757#endif
    5858
    59 #if defined MACOS || defined __ANDROID__
     59#if defined MACOS || defined __ANDROID__ || defined IPHONE
    6060 #define stricmp(a,b) strcasecmp(a,b)
    6161#endif
     
    8686#ifdef LINUX
    8787 #define GET_APP_HOME "./"
     88 #define GET_APP_RESOURCES "./"
     89#endif
     90
     91#ifdef MACOS
     92#ifdef MACOS_APP_DIR //separate home/resources
     93 #include <string>
     94 std::string getAppHome();
     95 #define GET_APP_HOME getAppHome()
     96#else //old style
     97 #define GET_APP_HOME "./"
     98#endif
    8899 #define GET_APP_RESOURCES "./"
    89100#endif
  • cpp/common/nonstd_math.cpp

    r227 r247  
    2222
    2323
     24#ifdef IPHONE
     25//TODO! -> ? http://stackoverflow.com/questions/12762418/how-to-enable-sigfpe-signal-on-division-by-zero-in-ios-app
     26void fpExceptInit()
     27{}
     28
     29void fpExceptEnable()
     30{}
     31
     32void fpExceptDisable()
     33{}
     34#endif
    2435
    2536
    26 #if defined LINUX || defined TIZEN || defined __ANDROID__ || defined IPHONE
     37#if defined LINUX || defined TIZEN || defined __ANDROID__
    2738
    2839#include <fenv.h>
  • cpp/common/nonstd_stdio.cpp

    r227 r247  
    55#include "nonstd_stdio.h"
    66#include "nonstd.h"
     7#include "Convert.h" //strTOwstr()
     8#include <common/stl-util.h>
    79
    810#if defined _WIN32 && !defined SHP
    911 //<unistd.h> not needed for unlink()
    1012 #include "Shlwapi.h" //PathIsRelative()
    11  #include "Util.h" //strTOwstr()
     13 #include <sys/stat.h> //_stat
    1214#else
    1315 #include <unistd.h>
     
    2325}
    2426
     27bool directoryExists(const char* path)
     28{
     29struct _stat s;
     30if (_stat(path,&s)!=0) return false;
     31return S_ISDIR(s.st_mode);
     32}
     33
     34bool makeDirectory(const char* path)
     35{
     36#ifdef _WIN32
     37return mkdir(path)==0;
     38#else
     39return mkdir(path,0777)==0;
     40#endif
     41}
     42
     43bool makeDirectories(const char* path)
     44{
     45if (directoryExists(path)) return true;
     46string parentdir=getFileDir(path);
     47if (!makeDirectories(parentdir.c_str())) return false;
     48return makeDirectory(path);
     49}
     50
     51int getFileSize(const char* path)
     52{
     53int size;
     54MFILE *f=mfopen(path,FOPEN_READ_BINARY);
     55if (f==NULL) return -1;
     56size=getFileSize(f);
     57mfclose(f);
     58return size;
     59}
     60
     61int getFileSize(MFILE *f)
     62{
     63  int saved_pos = mftell(f);
     64  mfseek(f, 0, SEEK_END);
     65  int size = mftell(f);
     66  mfseek(f, saved_pos, SEEK_SET);
     67  return size;
     68}
     69
    2570bool removeFile(const char* path)
    2671{
     
    3580        return PathIsRelative(fname) == FALSE; //no wide char for old borland compiler
    3681 #else
    37         return PathIsRelative(Util::strTOwstr(fname).c_str()) == FALSE; //http://msdn.microsoft.com/en-us/library/bb773660%28v=vs.85%29.aspx
     82        return PathIsRelative(Convert::strTOwstr(fname).c_str()) == FALSE; //http://msdn.microsoft.com/en-us/library/bb773660%28v=vs.85%29.aspx
    3883 #endif
    3984#else
  • cpp/common/nonstd_stdio.h

    r227 r247  
    77
    88bool fileExists(const char* path);
     9bool directoryExists(const char* path);
     10bool makeDirectory(const char* path);
     11bool makeDirectories(const char* path);
    912bool removeFile(const char* path);
    1013bool isAbsolutePath(const char* fname);
     14int getFileSize(const char* path);
    1115
    1216#ifdef _WIN32
     
    2428#ifndef MOBILE2D
    2529 #include <io.h> //borland compiler: include <io.h> before <dir.h> causes the SimWorld class in "simul.h" be unrecognized, for unknown reason :O moreover, this problem is only pertinent to the CLI project, not GUI. Maybe this is caused by global defines like NOVCL, NO_STRICT etc.?
    26  #define makeDirectory(name) mkdir(name)
     30// #define makeDirectory(name) mkdir(name)
    2731#endif
    2832
     33 #define S_ISDIR(x) ((x & _S_IFDIR)==_S_IFDIR)
    2934
    3035#else
     
    3237 #include <unistd.h>
    3338 #include <sys/stat.h>
    34  #define makeDirectory(name) mkdir(name,0777)
     39// #define makeDirectory(name) mkdir(name,0777)
    3540 #define _unlink unlink //_unlink jest ISO-conformant, unlink jest POSIX-deprecated
    36 
     41 #define _stat stat
    3742#endif
    3843
     
    95100#endif
    96101
     102int getFileSize(MFILE *f);
     103
    97104#endif
  • cpp/common/random.h

    r197 r247  
    1212 #include <sys/stat.h>
    1313 #include <fcntl.h>
     14#endif
     15#ifdef __BORLANDC__
     16 #include <stdint.h> //uintptr_t in borland
    1417#endif
    1518#ifdef _WIN32
     
    7679                {
    7780                        counter++;
    78                         seed = time(NULL);              //time (seconds); could use hi-res timer but then we would depend on common/timer.h
    79                         seed ^= counter;                //incremented value, possibly randomly initialized
    80                         seed ^= (unsigned int)&counter; //memory address
     81                        seed = time(NULL);                         //time (seconds); could use hi-res timer but then we would depend on common/timer.h
     82                        seed ^= counter;                           //incremented value, possibly randomly initialized
     83                        seed ^= (unsigned int)(uintptr_t)&counter; //memory address
    8184                }
    8285#ifdef _WIN32 //add more randomness from uuid
  • cpp/common/stl-util.cpp

    r246 r247  
    1010#include "framsg.h"
    1111#include <assert.h>
     12#ifdef USE_VIRTFILE
     13 #include <frams/virtfile/virtfile.h>
     14#endif
     15#ifdef __BORLANDC__
     16 #define va_copy(to,from) to=from //borland does not have va_copy() at all; va_list is just a pointer in borland
     17#endif
    1218
    1319string ssprintf_va(const char* format, va_list ap)
     
    1622        long size = 256;
    1723        char* buf;
     24        va_list ap_copy; // "va_list ap" can only by used once by printf-type functions as they advance the current argument pointer (crashed on linux x86_64)
     25        // (does not apply to SString::sprintf, it does not have the va_list variant)
    1826
    1927        //almost like SString::sprintf, but there is no common code to share because SString can use its directWrite to avoid double allocating/copying
    2028#ifdef USE_VSCPRINTF
    21         size = _vscprintf(format, ap) + 1; //+1 for terminating null character
     29        va_copy(ap_copy,ap);
     30        size = _vscprintf(format, ap_copy) + 1; //+1 for terminating null character
     31        va_end(ap_copy);
    2232#endif
    2333
     
    2636                buf = (char*)malloc(size);
    2737                assert(buf != NULL);
    28                 int n = vsnprintf(buf, size, format, ap);
     38                va_copy(ap_copy,ap);
     39                int n = vsnprintf(buf, size, format, ap_copy);
     40                va_end(ap_copy);
    2941                if (n > -1 && n < size)
    3042                {
     
    5466bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file)
    5567{
     68    bool ok=false;
     69#ifdef USE_VIRTFILE
     70        if (!isAbsolutePath(filename))
     71                {
     72                VirtFILE *f=Vfopen(filename,FOPEN_READ_BINARY);
     73                if (f)
     74                        {
     75                        int size=f->getSize();
     76                        data.resize(size);
     77                        int przeczytane = f->Vread(&data[0], size, 1);
     78                        ok = przeczytane == 1;
     79                        delete f;
     80                        }
     81                }
     82        else
     83#endif
     84        {
    5685        MFILE *f = mfopen(filename, FOPEN_READ_BINARY);
    57         bool ok = f != NULL;
    5886        if (f)
    5987        {
    60                 mfseek(f, 0, SEEK_END);
    61                 long size = mftell(f);
    62                 mfseek(f, 0, SEEK_SET);
     88                int size=getFileSize(f);
    6389                data.resize(size);
    6490                int przeczytane = mfread(&data[0], size, 1, f);
    6591                mfclose(f);
    66                 ok &= przeczytane == 1;
     92                ok = przeczytane == 1;
     93        }
    6794        }
    6895        if (warn_on_missing_file && !ok)
Note: See TracChangeset for help on using the changeset viewer.