X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=ETL%2Ftrunk%2FETL%2F_stringf.h;h=22939a2dbcb7c2231d6283c7d888529ba3e8c996;hb=2fde73ebec7ee1bcb147abc19d16b1bc0deb17bf;hp=60653c36feaa4608cdbae396225d241040b75b4a;hpb=4ec81d053bf1d0cbcd9f0bf048914ec8eca08f4c;p=synfig.git diff --git a/ETL/trunk/ETL/_stringf.h b/ETL/trunk/ETL/_stringf.h index 60653c3..22939a2 100644 --- a/ETL/trunk/ETL/_stringf.h +++ b/ETL/trunk/ETL/_stringf.h @@ -4,6 +4,7 @@ ** $Id$ ** ** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** Copyright (c) 2007 Chris Moore ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as @@ -29,9 +30,14 @@ /* === H E A D E R S ======================================================= */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include #include #include +#include /* === M A C R O S ========================================================= */ @@ -39,6 +45,21 @@ #define ETL_STRPRINTF_MAX_LENGTH (800) #endif +#ifdef WIN32 +#define POPEN_BINARY_READ_TYPE "rb" +#define POPEN_BINARY_WRITE_TYPE "wb" +#else +#define POPEN_BINARY_READ_TYPE "r" +#define POPEN_BINARY_WRITE_TYPE "w" +#endif + +#ifdef __ETL_HAS__VSNPRINTF +#ifndef __ETL_HAS_VSNPRINTF +#define vnsprintf _vnsprintf +#define __ETL_HAS_VSNPRINTF +#endif +#endif + /* === T Y P E D E F S ===================================================== */ _ETL_BEGIN_CDECLS @@ -49,22 +70,33 @@ _ETL_BEGIN_CDECLS #define ETL_NO_THROW throw() #endif -#ifdef HAVE_VASPRINTF // This is the preferred method - extern int vasprintf(char **,const char *,va_list)ETL_NO_THROW; +// Prefer prototypes from glibc headers, since defining them ourselves +// works around glibc security mechanisms + +#ifdef __ETL_HAS_VASPRINTF // This is the preferred method + #ifndef __GLIBC__ + extern int vasprintf(char **,const char *,va_list)ETL_NO_THROW; + #endif #else -# ifdef HAVE_VSNPRINTF // This is the secondary method - extern int vsnprintf(char *,size_t,const char*,va_list)ETL_NO_THROW; +# ifdef __ETL_HAS_VSNPRINTF // This is the secondary method + #ifndef __GLIBC__ + extern int vsnprintf(char *,size_t,const char*,va_list)ETL_NO_THROW; + #endif # endif #endif -#ifdef HAVE_VSSCANF -extern int vsscanf(const char *,const char *,va_list)ETL_NO_THROW; +#ifdef __ETL_HAS_VSSCANF + #ifndef __GLIBC__ + extern int vsscanf(const char *,const char *,va_list)ETL_NO_THROW; + #endif #else #define ETL_NO_VSTRSCANF -#ifdef HAVE_SSCANF -extern int sscanf(const char *buf, const char *format, ...)ETL_NO_THROW; +#ifdef __ETL_HAS_SSCANF + #ifndef __GLIBC__ + extern int sscanf(const char *buf, const char *format, ...)ETL_NO_THROW; + #endif #endif #endif @@ -79,15 +111,18 @@ _ETL_BEGIN_NAMESPACE inline std::string vstrprintf(const char *format, va_list args) { -#ifdef HAVE_VASPRINTF // This is the preferred method (and safest) +#ifdef __ETL_HAS_VASPRINTF // This is the preferred method (and safest) char *buffer; std::string ret; - vasprintf(&buffer,format,args); - ret=buffer; - free(buffer); + int i=vasprintf(&buffer,format,args); + if (i>-1) + { + ret=buffer; + free(buffer); + } return ret; #else -#ifdef HAVE_VSNPRINTF // This is the secondary method (Safe, but bulky) +#ifdef __ETL_HAS_VSNPRINTF // This is the secondary method (Safe, but bulky) #warning etl::vstrprintf() has a maximum size of ETL_STRPRINTF_MAX_LENGTH in this configuration. #ifdef ETL_THREAD_SAFE char buffer[ETL_STRPRINTF_MAX_LENGTH]; @@ -136,7 +171,7 @@ strscanf(const std::string &data, const char*format, ...) } #else -#if defined (HAVE_SSCANF) && defined (__GNUC__) +#if defined (__ETL_HAS_SSCANF) && defined (__GNUC__) #define strscanf(data,format,...) sscanf(data.c_str(),format,__VA_ARGS__) #endif #endif @@ -189,14 +224,38 @@ dirname(const std::string &str) break; if(iter==str.begin()) + { if (*iter==ETL_DIRECTORY_SEPARATOR) return "/"; else return "."; + } return std::string(str.begin(),iter); } +// filename_extension("/f.e/d.c") => ".c" +inline std::string +filename_extension(const std::string &str) +{ + std::string base = basename(str); + std::string::size_type pos = base.find_last_of('.'); + if (pos == std::string::npos) return std::string(); + return base.substr(pos); +} + +// filename_sans_extension("/f.e/d.c") => "/f.e/d" +inline std::string +filename_sans_extension(const std::string &str) +{ + std::string base = basename(str); + std::string::size_type pos = base.find_last_of('.'); + if (pos == std::string::npos) return str; + std::string dir = dirname(str); + if (dir == ".") return base.substr(0,pos); + return dir + ETL_DIRECTORY_SEPARATOR + base.substr(0,pos); +} + inline bool is_absolute_path(const std::string &path) {