42 #ifndef _GLS_RUNTIME_UTIL_H 
   43 #define _GLS_RUNTIME_UTIL_H 
   67 #    include <android/asset_manager.h> 
   70 #if defined( _MSC_VER ) 
   72 #    pragma warning( disable : 4786 ) 
   75 const int DIALOG_MAX_DIRECTORY_LENGTH = 1024; 
 
   94 #    define strcasecmp( x, y ) _stricmp( x, y ) 
  102 #define PARSER_CLEARSTRING_DELIMETER_START "#$STRING_START$#" 
  103 #define PARSER_CLEARSTRING_DELIMETER_END "#$STRING_END$#" 
  106 #    define M_PI 3.14159265358979323846 
  111 #define DEG_TO_RAD ( M_PI / 180.0 ) 
  114 #define RAD_TO_DEG ( 180.0 / M_PI ) 
  116 #define HIT_TOLERANCE 5.0 
  120 #define BETWEEN( x, x1, x2 ) ( ( ( ( x ) >= ( x1 ) ) && ( ( x ) <= ( x2 ) ) ) || ( ( ( x ) >= ( x2 ) ) && ( ( x ) <= ( x1 ) ) ) ) 
  123 #define IS_NEGATIVE( x ) ( ( fabs( x ) > 0.0001 ) ? ( x < 0.0 ) : 0 ) 
  126 #define IS_POSITIVE( x ) ( ( fabs( x ) > 0.0001 ) ? ( x > 0.0 ) : 0 ) 
  129 #define CloseToZero( x ) ( fabs( ( x ) ) < 0.1 ) 
  132 #define VeryCloseToZero( x ) ( fabs( ( x ) ) < 0.0001 ) 
  135 #define IS_ZERO( x ) ( fabs( ( x ) ) < 0.001 ) 
  139 #    define MIN( A, B ) ( ( A ) < ( B ) ? ( A ) : ( B ) ) 
  144 #    define MAX( A, B ) ( ( A ) > ( B ) ? ( A ) : ( B ) ) 
  153 GLS_EXPORT 
bool gltIsExtSupported( 
const char* extension );
 
  158 #    define GLSTUDIO_CLAMP_TO_EDGE ( OpenGLVersion() >= 1.2f ? 0x812F : GL_CLAMP ) 
  160 #    define GLSTUDIO_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE 
  192     if( ( index < 0 ) || ( index >= GLS_COLOR_MAX ) )
 
  193         return glsDefinedColors[ 0 ];
 
  195         return glsDefinedColors[ index ];
 
  204     unsigned char                                      alpha )
 
  206     if( ( index >= 0 ) && ( index < GLS_COLOR_MAX ) )
 
  208         glsDefinedColors[ index ][ 0 ] = red;
 
  209         glsDefinedColors[ index ][ 1 ] = green;
 
  210         glsDefinedColors[ index ][ 2 ] = blue;
 
  211         glsDefinedColors[ index ][ 3 ] = alpha;
 
  227 template<
class T1, 
class T2>
 
  228 bool Equal( T1 x, T2 y, 
float precision = 0.001f )
 
  230     return ( x - precision ) <= y && y <= ( x + precision );
 
  239 const T& 
Min( 
const T& x, 
const T& y )
 
  241     return x < y ? x : y;
 
  250 const T& 
Max( 
const T& x, 
const T& y )
 
  252     return x < y ? y : x;
 
  260 template<
class T, 
class Pred>
 
  261 const T& 
Min( 
const T& x, 
const T& y, Pred pr )
 
  263     return pr( x, y ) ? x : y;
 
  271 template<
class T, 
class Pred>
 
  272 const T& 
Max( 
const T& x, 
const T& y, Pred pr )
 
  274     return pr( x, y ) ? y : x;
 
  314 template<
class T, 
bool TypeIsSimple>
 
  321     unsigned int size() { 
return array.
Count(); }
 
  323     void push( 
const T& item )
 
  325         array[ array.
Count() ] = item;
 
  331         return array[ array.
Count() - 1 ];
 
  336         if( array.
Count() > 0 )
 
  370     rotation_scaling( 0, 0 ) = new_i.x;
 
  371     rotation_scaling( 0, 1 ) = new_j.x;
 
  372     rotation_scaling( 0, 2 ) = new_k.x;
 
  373     rotation_scaling( 1, 0 ) = new_i.y;
 
  374     rotation_scaling( 1, 1 ) = new_j.y;
 
  375     rotation_scaling( 1, 2 ) = new_k.y;
 
  376     rotation_scaling( 2, 0 ) = new_i.z;
 
  377     rotation_scaling( 2, 1 ) = new_j.z;
 
  378     rotation_scaling( 2, 2 ) = new_k.z;
 
  381     rotation_scaling.
Invert();
 
  384     return rotation_scaling * transform;
 
  390     GlsMatrixAffine<T> transform;
 
  391     GlsMatrixAffine<T> rotation_scaling;
 
  395     transform.Translate( -new_origin );
 
  399     rotation_scaling( 0, 0 ) = new_i.x;
 
  400     rotation_scaling( 0, 1 ) = new_j.x;
 
  401     rotation_scaling( 0, 2 ) = new_k.x;
 
  402     rotation_scaling( 1, 0 ) = new_i.y;
 
  403     rotation_scaling( 1, 1 ) = new_j.y;
 
  404     rotation_scaling( 1, 2 ) = new_k.y;
 
  405     rotation_scaling( 2, 0 ) = new_i.z;
 
  406     rotation_scaling( 2, 1 ) = new_j.z;
 
  407     rotation_scaling( 2, 2 ) = new_k.z;
 
  410     rotation_scaling.Invert();
 
  413     result = rotation_scaling * transform;
 
  480     int& index1, 
int& index2, 
int& index3,
 
  481     bool isVectorArray = 
true );
 
  504 GLS_EXPORT 
int EncodeString( 
char* dest, 
const char* src, 
const int dest_str_length );
 
  510 GLS_EXPORT std::string 
EncodeString( 
const std::string& src );
 
  523 GLS_EXPORT 
int C_EncodeString( 
char* dest, 
const char* src, 
const int dest_str_length );
 
  537 GLS_EXPORT 
int DecodeString( 
char* dest, 
const char* src, 
const int dest_str_length );
 
  543 GLS_EXPORT std::string 
DecodeString( 
const std::string& src );
 
  552     unsigned char* pixels;
 
  555 GLS_EXPORT 
char* MakeRelativePath( 
const char* originalPath, 
const char* relativePath );
 
  556 GLS_EXPORT 
void  ConvertBackslashToSlash( 
char* str );
 
  557 GLS_EXPORT 
void  ConvertBackslashToSlash( std::string& str );
 
  575 GLS_EXPORT 
int range_check( 
int num, 
double val, ... );
 
  584 GLS_EXPORT 
int Safe_fopen( 
const char* filename, 
char* flags, FILE** f );
 
  586 GLS_EXPORT 
int Safe_fopen( 
const char* filename, 
char* flags, std::fstream& outstr );
 
  595 GLS_EXPORT 
void EnableDirectAssetLoading( 
bool enableDirectAssetLoading );
 
  603 GLS_EXPORT 
bool HasAssetExtension( 
const char* filename );
 
  611 GLS_EXPORT 
bool AssetExists( 
const char* filename );
 
  618 GLS_EXPORT 
void SetAssetManager( AAssetManager* assetManager );
 
  621 #if defined( ANDROID ) || ( defined( LINUX ) && defined( GLES ) ) || defined( QNX ) 
  627 GLS_EXPORT std::string 
ResolvePath( 
const char* filename_ );
 
  633 GLS_EXPORT 
void SetResourcePath( 
const char* resourcePath );
 
  644 GLS_EXPORT FILE* 
gls_fopen( 
const char* filename, 
const char* flags );
 
  669 GLS_EXPORT std::string 
ResolvePath( 
const char* path );
 
  672 inline std::string 
ResolvePath( 
const std::string& path )
 
  683 GLS_EXPORT FILE* 
gls_fopen( 
const char* filename, 
const char* flags );
 
  693 GLS_EXPORT std::string GetAbsolutePathAndFileNameInDefaultResourceBundle( 
const char* fileName );
 
  706 GLS_EXPORT 
bool FileExists( 
const char* filename );
 
  707 GLS_EXPORT 
bool FileExists( 
const std::string& filename );
 
  712 GLS_EXPORT 
bool IsDirectory( 
const char* filename );
 
  713 GLS_EXPORT 
bool IsDirectory( 
const std::string& filename );
 
  718 GLS_EXPORT std::string 
FileExtension( 
const std::string& filepath );
 
  723 GLS_EXPORT std::string 
FileName( 
const std::string& filepath );
 
  729 GLS_EXPORT std::string 
FilePath( 
const std::string& filepath );
 
  737 GLS_EXPORT 
const char* 
GetFilePath( 
const char* name );
 
  763 GLS_EXPORT 
char* 
PathToOS( 
const char* path );
 
  770 GLS_EXPORT std::string 
GetExtension( 
const std::string& filename );
 
  776 GLS_EXPORT 
const char* 
GetBaseName( 
const char* path );
 
  805 GLS_EXPORT 
bool ContainsNonBlank( 
const std::string& val );
 
  807 GLS_EXPORT 
bool GetNoSpaces( FILE* f, 
char* result, 
int maxLen );
 
  808 GLS_EXPORT 
bool GetToEnd( std::istream& instr, std::string& result, 
bool decode );
 
  809 GLS_EXPORT 
bool GetVertex( std::istream& instr, Vertex* vert, 
bool getColor );
 
  814 GLS_EXPORT 
bool GetComponentClassNames( 
const char* dllFileName, DynamicArray<std::string, false>& nameList, 
const char* createClassTag = 
"CreateComponent_" );
 
  830 #if !defined( GLES ) || defined( GLES_ANGLE ) 
  831 GLS_EXPORT 
bool OpenFileDialog( Fl_Window* win, 
char* filePath, 
unsigned int filePathSize,
 
  832     char* directory = NULL, 
const char* filterStr = NULL,
 
  833     const char* defaultExt = NULL, 
const char* title = NULL,
 
  834     bool multiSelect = 
false, 
bool createFile = 
false,
 
  835     bool fileMustExist = 
false, 
bool pathMustExist = 
false,
 
  836     bool noChangeDirectory = 
false );
 
  838 GLS_EXPORT 
bool SaveFileDialog( Fl_Window* win, 
char* filePath, 
unsigned int filePathSize,
 
  839     char* directory = NULL, 
const char* filterStr = NULL,
 
  840     const char* defaultExt = NULL, 
const char* title = NULL,
 
  841     bool createFile    = 
false,
 
  842     bool fileMustExist = 
false, 
bool pathMustExist = 
false,
 
  843     bool noChangeDirectory = 
false );
 
  845 GLS_EXPORT 
void CheckGLError( 
void );
 
  855 GLS_EXPORT std::string 
Uppercase( 
const std::string& str );
 
  857 GLS_EXPORT std::string ReplaceEnvironmentVariables( 
const char* originalPath );
 
  867     GLS_EXPORT 
void ReadCommandLine( 
int argc, 
char** argv );
 
  868     GLS_EXPORT 
void Usage();
 
  873     bool SilentMode( 
void ) { 
return _silentMode; }
 
  875     static GLS_EXPORT glsCommandLine* Instance();
 
  876     static glsCommandLine*            _instance;
 
  890     GLS_EXPORT InterfaceDescriptionClass( 
const InterfaceDescriptionClass& source );
 
  892     GLS_EXPORT ~InterfaceDescriptionClass();
 
  894     GLS_EXPORT InterfaceDescriptionClass( 
const char* code, 
const char* usage, 
const char* comment );
 
  896     GLS_EXPORT 
void        operator=( 
const InterfaceDescriptionClass& source );
 
  897     GLS_EXPORT 
void        Code( 
const char* );
 
  898     GLS_EXPORT 
const char* Code() 
const;
 
  899     GLS_EXPORT 
void        Usage( 
const char* );
 
  900     GLS_EXPORT 
const char* Usage() 
const;
 
  901     GLS_EXPORT 
void        Comment( 
const char* );
 
  902     GLS_EXPORT 
const char* Comment() 
const;
 
  914     typedef std::ostream ostreamType;
 
  915     typedef std::istream istreamType;
 
  917     virtual void StreamOut( ostreamType& outstr ) 
const = 0;
 
  918     virtual void StreamIn( istreamType& instr )         = 0;
 
  952         if( 
typeid( T2 ) != 
typeid( 
void* ) )
 
  956         if( 
typeid( T3 ) != 
typeid( 
void* ) )
 
  960         if( 
typeid( T4 ) != 
typeid( 
void* ) )
 
  964         if( 
typeid( T5 ) != 
typeid( 
void* ) )
 
  968         if( 
typeid( T6 ) != 
typeid( 
void* ) )
 
  972         if( 
typeid( T7 ) != 
typeid( 
void* ) )
 
  976         if( 
typeid( T8 ) != 
typeid( 
void* ) )
 
  980         if( 
typeid( T9 ) != 
typeid( 
void* ) )
 
  984         if( 
typeid( T10 ) != 
typeid( 
void* ) )
 
 1021         : _val1( src._val1 )
 
 1022         , _val2( src._val2 )
 
 1023         , _val3( src._val3 )
 
 1024         , _val4( src._val4 )
 
 1025         , _val5( src._val5 )
 
 1026         , _val6( src._val6 )
 
 1027         , _val7( src._val7 )
 
 1028         , _val8( src._val8 )
 
 1029         , _val9( src._val9 )
 
 1030         , _val10( src._val10 )
 
 1051         const T2&  val2  = T2(),
 
 1052         const T3&  val3  = T3(),
 
 1053         const T4&  val4  = T4(),
 
 1054         const T5&  val5  = T5(),
 
 1055         const T6&  val6  = T6(),
 
 1056         const T7&  val7  = T7(),
 
 1057         const T8&  val8  = T8(),
 
 1058         const T9&  val9  = T9(),
 
 1059         const T10& val10 = T10() )
 
 1082         case 10: rval &= ( _val10 == val._val10 );
 
 1083         case 9: rval &= ( _val9 == val._val9 );
 
 1084         case 8: rval &= ( _val8 == val._val8 );
 
 1085         case 7: rval &= ( _val7 == val._val7 );
 
 1086         case 6: rval &= ( _val6 == val._val6 );
 
 1087         case 5: rval &= ( _val5 == val._val5 );
 
 1088         case 4: rval &= ( _val4 == val._val4 );
 
 1089         case 3: rval &= ( _val3 == val._val3 );
 
 1090         case 2: rval &= ( _val2 == val._val2 );
 
 1092             rval &= ( _val1 == val._val1 );
 
 1103         return !( *
this == val );
 
 1116             outstr << 
" " << _val2;
 
 1118             outstr << 
" " << _val3;
 
 1120             outstr << 
" " << _val4;
 
 1122             outstr << 
" " << _val5;
 
 1124             outstr << 
" " << _val6;
 
 1126             outstr << 
" " << _val7;
 
 1128             outstr << 
" " << _val8;
 
 1130             outstr << 
" " << _val9;
 
 1131         if( _numVals >= 10 )
 
 1132             outstr << 
" " << _val10;
 
 1184         if( _numVals >= 10 )
 
 1192 GLS_EXPORT std::ostream& operator<<( std::ostream& outstr, 
const GlsMultiValBase& multiVal );
 
 1193 GLS_EXPORT std::istream& operator>>( std::istream& instr, GlsMultiValBase& multiVal );
 
 1205     std::string _string;
 
 1230         : _string( str ? str : 
"" )
 
 1234     operator std::string()
 const 
 1251         return str1._string == str2._string;
 
 1257         return !( str1 == str2 );
 
 1261 inline std::ostream& operator<<( std::ostream& outstr, 
const GlsPropString& str )
 
 1266 inline std::istream& operator>>( std::istream& instr, GlsPropString& str )
 
 1269     disti::GetToEnd( instr, temp, 
false );
 
 1282     std::string _string;
 
 1307     operator std::string()
 const 
 1311     std::string& String()
 
 1317         return str._string == _string;
 
 1320 inline std::ostream& operator<<( std::ostream& outstr, 
const GlsPropStringQuoted& str )
 
 1325 inline std::istream& operator>>( std::istream& instr, GlsPropStringQuoted& str )
 
 1332     if( instr.peek() != 
'\"' )
 
 1334         disti::GetToEnd( instr, temp, 
false );
 
 1344         while( instr.good() )
 
 1346             lastChar = currChar;
 
 1347             currChar = instr.get();
 
 1348             if( currChar != -1 )
 
 1350                 if( currChar == 
'\"' && lastChar != 
'\\' )
 
 1352                 temp += (char)currChar;
 
 1363 void SpawnBrowser( 
const char* url );
 
 1373 GLS_EXPORT 
bool CheckDistiLicense( 
const char* licenseGroupName, 
const char* feature, 
const char* version, 
bool quiet );
 
 1407     T Clamp( 
const T& val, 
const T& min, 
const T& max )
 
 1409         return std::min( max, std::max( min, val ) );
 
 1422     inline void Split( 
const std::string& s, 
const char delim, std::vector<std::string>& elems, 
const std::size_t maxElems = 0 )
 
 1424         std::istringstream ss( s );
 
 1426         while( std::getline( ss, item, delim ) )
 
 1428             elems.push_back( DISTI_RVAL_MOVE( item ) );
 
 1429             if( elems.size() == maxElems )
 
 1434         if( elems.size() == maxElems && ss.good() && maxElems > 0 )
 
 1436             std::string remainder;
 
 1437             std::getline( ss, remainder, 
'\0' );
 
 1438             elems.back() += delim + remainder;
 
 1452     inline std::vector<std::string> Split( 
const std::string& s, 
const char delim, 
const std::size_t maxElems = 0 )
 
 1454         std::vector<std::string> elems;
 
 1455         Split( s, delim, elems, maxElems );
 
 1456         return DISTI_RVAL_MOVE( elems );
 
 1460     inline std::string MakeString( 
const char* 
const cStr )
 
 1462         return ( cStr ? cStr : 
"" );
 
 1469 GLS_EXPORT 
void glsPerspective( 
double fovy, 
double aspect, 
double zNear, 
double zFar );
 
 1471 #ifdef MATRIX_TYPE_FLOAT 
 1472 GLS_EXPORT 
bool glsProject( 
double objx, 
double objy, 
double objz,
 
 1473     const float modelMatrix[ 16 ],
 
 1474     const float projMatrix[ 16 ],
 
 1475     const int   viewport[ 4 ],
 
 1476     double* winx, 
double* winy, 
double* winz );
 
 1478 GLS_EXPORT 
bool glsUnProject( 
double winx, 
double winy, 
double winz,
 
 1479     const float modelMatrix[ 16 ],
 
 1480     const float projMatrix[ 16 ],
 
 1481     const int   viewport[ 4 ],
 
 1482     double* objx, 
double* objy, 
double* objz );
 
 1484 GLS_EXPORT 
bool  glsProject( 
double objx, 
double objy, 
double objz,
 
 1485      const double modelMatrix[ 16 ],
 
 1486      const double projMatrix[ 16 ],
 
 1487      const int    viewport[ 4 ],
 
 1488      double* winx, 
double* winy, 
double* winz );
 
 1490 GLS_EXPORT 
bool glsUnProject( 
double winx, 
double winy, 
double winz,
 
 1491     const double modelMatrix[ 16 ],
 
 1492     const double projMatrix[ 16 ],
 
 1493     const int    viewport[ 4 ],
 
 1494     double* objx, 
double* objy, 
double* objz );
 
The DistiUnhideGlobalsDummyClass class. 
const T & Min(const T &x, const T &y)
Definition: util.h:239
int EncodedStringMinLength()
GlsPropStringQuoted(const std::string &str)
Definition: util.h:1293
virtual void StreamOut(ostreamType &outstr) const 
Definition: util.h:1112
std::string GetExtension(const std::string &filename)
GlsDefinedColorEnum
Definition: util.h:166
const int INLINE_TEXTURE_LINE_LENGTH
Definition: util.h:99
std::string & String()
Definition: util.h:1243
std::string FileExtension(const std::string &filepath)
void GlsGetPerspective(GlsMatrixType &m, double fovy, double aspect, double zNear, double zFar)
GlsPropString(const char *str)
Definition: util.h:1229
unsigned char glsDefinedColors[GLS_COLOR_MAX][4]
virtual bool operator!=(const GlsMultiVal &val) const 
Definition: util.h:1101
Definition: dynamic_array.h:62
The disti::DynamicArray class. A templated array of objects capable of dynamically growing...
Class to contain current OpenGL view, projection and draw matrices. 
Definition: util.h:278
std::string FileName(const std::string &filepath)
const char * GetBaseName(const char *path)
int EncodeString(char *dest, const char *src, const int dest_str_length)
The GlsMatrixAffine class. 
void AppendTrailingSlash(char *s)
void RemoveDoubleSlashes(char *path, char slash= '/')
bool CheckDistiLicense(const char *licenseGroupName, const char *feature, const char *version, bool quiet)
std::string GetQualifiedInstanceName(const DisplayFrame *topFrame, const DisplayObject *obj)
std::string GetDefaultComponentClassName(const char *dllFileName)
GlsMultiVal()
Definition: util.h:1007
char * PathToOS(const char *path)
const T & Max(const T &x, const T &y)
Definition: util.h:250
virtual bool operator==(const GlsMultiVal &val) const 
Definition: util.h:1075
GlsPropStringQuoted(const char *str)
Definition: util.h:1303
A file for all GL Studio files to include. 
int range_check(int num, double val,...)
bool GetObjectCoordinatesTransformSameView(DisplayObject *from, DisplayObject *to, GlsMatrixType *outTransform)
float AngularDistanceRad(float angle1, float angle2)
std::string Uppercase(const std::string &str)
void ChangeGlsDefinedColor(GlsDefinedColorEnum index, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
Definition: util.h:200
GlsPropString()
Definition: util.h:1208
VertexNoColor Vector
Definition: gls_font_base.h:66
GlsMatrixAffine< T > FindCoordinateTransformation(const Vector &new_origin, const Vector &new_i, const Vector &new_j, const Vector &new_k)
Definition: util.h:359
bool FindNonColinearVertices(int arraySize, Vector array[], int &index1, int &index2, int &index3, bool isVectorArray=true)
bool GetObjectCoordinatesTransform(DisplayObject *from, DisplayObject *to, GlsMatrixType *outTransform)
int DecodeString(char *dest, const char *src, const int dest_str_length)
bool GetComponentClassNames(const char *dllFileName, DynamicArray< std::string, false > &nameList, const char *createClassTag="CreateComponent_")
void Count(const unsigned int count)
Definition: dynamic_array.h:115
bool CalculateTexPointsFromTexCoords(DisplayObject *object)
friend bool operator!=(const GlsPropString &str1, const GlsPropString &str2)
Definition: util.h:1255
GlsMultiVal(const GlsMultiVal &src)
Definition: util.h:1020
void PushResourcePath(const char *resourcePath)
void Translate(Type x, Type y, Type z)
Definition: gls_matrix_affine.h:196
bool FileExists(const char *filename)
int C_EncodeString(char *dest, const char *src, const int dest_str_length)
virtual void StreamIn(istreamType &instr)
Definition: util.h:1141
GlsMultiVal(const T1 &val1, const T2 &val2=T2(), const T3 &val3=T3(), const T4 &val4=T4(), const T5 &val5=T5(), const T6 &val6=T6(), const T7 &val7=T7(), const T8 &val8=T8(), const T9 &val9=T9(), const T10 &val10=T10())
Definition: util.h:1049
FILE * gls_fopen(const char *filename, const char *flags)
bool IsDirectory(const char *filename)
float AngularDistanceDeg(float angle1, float angle2)
std::string FilePath(const std::string &filepath)
bool Equal(T1 x, T2 y, float precision=0.001f)
Definition: util.h:228
char * GetFileName(const char *name)
bool NotColinear(const Vector &a, const Vector &b, const Vector &c)
const char * GetFilePath(const char *name)
std::string ResolveRuntimeResourcePath(const char *fileName)
void PushResourceFinder(std::string(*finder)(const std::string &))
std::string ResolvePath(const char *path)
friend bool operator==(const GlsPropString &str1, const GlsPropString &str2)
Definition: util.h:1249
Contains the DistiAssert macro. 
Macros and helper code to determine what subset of C++11/14/17 is available. 
void GlsGetOrtho(GlsMatrixType &m, double left, double right, double bottom, double top, double zNear, double zFar)
GlsPropString(const std::string &str)
Definition: util.h:1218
int Safe_fopen(const char *filename, char *flags, FILE **f)
unsigned char * GlsDefinedColor(GlsDefinedColorEnum index)
Definition: util.h:190
Definition: bmpimage.h:46
GlsPropStringQuoted()
Definition: util.h:1284