ede/edelib2/Util.cpp
2007-07-18 18:20:04 +00:00

361 lines
7.3 KiB
C++

/*
* $Id$
*
* Library of useful functions
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2006 EDE Authors.
*
* This program is licenced under terms of the
* GNU General Public Licence version 2 or newer.
* See COPYING for details.
*/
#include "Util.h"
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <time.h>
#include <fltk/filename.h>
#ifdef _WIN32
# include <io.h>
# include <direct.h>
# include <windows.h>
# define access(a,b) _access(a,b)
# define mkdir(a,b) _mkdir(a)
# define R_OK 4
#else
# include <unistd.h>
#endif /* _WIN32 */
// From Enumerations.h
#ifdef _WIN32
# undef slash
# define slash '\\'
#else
# undef slash
# define slash '/'
#endif
// End Enumerations.h
using namespace fltk;
using namespace edelib;
// Test if path is absolute or relative
int edelib::is_path_rooted(const char *fn)
{
#ifdef _WIN32
if (fn[0] == '/' || fn[0] == '.' || fn[0] == '\\' || fn[1]==':')
#else
if (fn[0] == '/' || fn[0] == '.')
#endif
return 1;
return 0;
}
// recursively create a path in the file system
bool edelib::make_path( const char *path )
{
if(access(path, 0))
{
const char *s = strrchr( path, slash );
if ( !s ) return 0;
int len = s-path;
char *p = (char*)malloc( len+1 );
memcpy( p, path, len );
p[len] = 0;
make_path( (const char*)p );
free( p );
return ( mkdir( path, 0777 ) == 0 );
}
return true;
}
// create the path needed for file using make_path
bool edelib::make_path_for_file( const char *path )
{
const char *s = strrchr( path, slash );
if ( !s ) return false;
int len = s-path;
char *p = (char*)malloc( len+1 );
memcpy( p, path, len );
p[len] = 0;
bool ret=make_path( (const char*)p );
free( p );
return ret;
}
// Cross-platform function for system path
char* edelib::get_sys_dir()
{
#ifndef _WIN32
return SYSTEM_PATH;
#else
static char path[PATH_MAX];
HKEY hKey;
if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, &hKey)==ERROR_SUCCESS)
{
DWORD size=4096;
RegQueryValueExW(hKey, L"CommonFilesDir", NULL, NULL, (LPBYTE)path, &size);
RegCloseKey(hKey);
return path;
}
return "C:\\EDE\\";
#endif
}
// Cross-platform function for home directory...
// I don't see the purpose since getenv("HOME") works just fine
/*char* edelib::get_homedir() {
char *path = new char[PATH_MAX];
const char *str1;
str1=getenv("HOME");
if (str1) {
memcpy(path, str1, strlen(str1)+1);
return path;
}
return 0;
}*/
// strdupcat() - it's cool to strcat with implied realloc
// -- NOTE: due to use of realloc *always* use strdupcat return value:
// dest = strdupcat(dest,src);
// and *never* use it like:
// strdupcat(dest,src);
char* edelib::strdupcat(char *dest, const char *src)
{
if (!dest) {
dest=(char*)malloc(strlen(src));
} else {
dest=(char*)realloc (dest, strlen(dest)+strlen(src)+1);
}
strcat(dest,src);
return dest;
}
// wstrim() - for trimming characters (used in parser)
// parts of former fl_trimleft and fl_trimright from Fl_Util.cpp
char* edelib::wstrim(char *string)
{
if(!string)
return NULL;
char *start;
int len = strlen(string);
if (len) {
char *p = string + len;
do {
p--;
if ( !isspace(*p) ) break;
} while ( p != string );
if ( !isspace(*p) ) p++;
*p = 0;
}
for(start = string; *start && isspace (*start); start++);
memmove(string, start, strlen(start) + 1);
return string;
}
const char* edelib::twstrim(const char* string)
{
static char buffer[4096];
if (strlen(string)>4095) {
strncpy(buffer,string,4095);
buffer[4095]='\0';
} else
strcpy(buffer,string);
wstrim((char*)buffer);
return (const char*)buffer;
}
// hmmmh?
/*
char* wstrim(const char *string)
{
char *newstring = strdup(string);
return wstrim(newstring);
}*/
// Returns nicely formatted string for byte sizes
const char* edelib::nice_size(double size) {
static char buffer[256];
if (size<1024) {
snprintf(buffer,255,"%d B",(int)size);
} else if (size<1024*10) {
snprintf(buffer,255,"%.1f kB",(float)size/1024);
} else if (size<1024*1024) {
snprintf(buffer,255,"%d kB",(int)size/1024);
} else if (size<1024*1024*10) {
snprintf(buffer,255,"%.1f MB",(float)size/(1024*1024));
} else if (size<1024*1024*1024) {
snprintf(buffer,255,"%d MB",(int)size/(1024*1024));
} else if (size<1024*1024*1024*10) {
snprintf(buffer,255,"%.1f GB",(float)size/(1024*1024*1024));
} else {
snprintf(buffer,255,"%d GB",(int)size/(1024*1024*1024));
}
return (const char*) buffer;
}
const char* edelib::nice_time(long int epoch) {
static char buffer[256];
const time_t k = (const time_t)epoch;
const struct tm *timeptr = localtime(&k);
// Date/time format should be moved to configuration
snprintf(buffer,255,"%.2d.%.2d.%.4d. %.2d:%.2d", timeptr->tm_mday, timeptr->tm_mon, 1900+timeptr->tm_year, timeptr->tm_hour, timeptr->tm_min);
return buffer;
}
// Find in haystack any of needles (divided with separator)
char* edelib::strstrmulti(const char *haystack, const char *needles, const char *separator) {
if (!haystack || !needles || (strlen(haystack)==0) || (strlen(needles)==0))
return (char*)haystack; // this means that empty search returns true
char *copy = strdup(needles);
char *token = strtok(copy, separator);
char *result = 0;
do {
if ((result = strstr(haystack,token))) break;
} while ((token = strtok(NULL, separator)));
free (copy);
if (!result && (strcmp(separator,needles+strlen(needles)-strlen(separator))==0))
return (char*)haystack; // again
return result;
}
// vec_from_string() - similar to explode() in PHP or split() in Perl
// adapted from Fl_String_List to use vector
/*std::vector<char*> vec_from_string(const char *str, const char *separator)
{
if(!str) return std::vector<char*> ();
const char *ptr = str;
const char *s = strstr(ptr, separator);
std::vector<char*> retval;
if(s) {
unsigned separator_len = strlen(separator);
do {
unsigned len = s - ptr;
if (len) {
retval.push_back(strndup(ptr,len));
} else {
retval.push_back(NULL);
}
ptr = s + separator_len;
s = strstr(ptr, separator);
}
while(s);
if(*ptr) {
retval.push_back(strdup(ptr));
}
} else {
retval.push_back(strdup(ptr));
}
return retval;
}*/
// Print to a static char[] and return pointer
const char* edelib::tsprintf(char *format, ...)
{
static char buffer[4096];
va_list args;
va_start(args, format);
vsnprintf(buffer, 4095, format, args);
va_end(args);
return (const char*)buffer;
}
char* edelib::tasprintf(char *format, ...)
{
char buffer[4096];
va_list args;
va_start(args, format);
vsnprintf(buffer, 4095, format, args);
va_end(args);
return strdup(buffer);
}
// This function exists on some OSes and is mentioned in C textbooks
// However, we can just use sprintf instead
/*
char *
itoa(int value, char *string, int radix)
{
char tmp[33];
char *tp = tmp;
int i;
unsigned v;
int sign;
char *sp;
if (radix > 36 || radix <= 1)
{
return 0;
}
sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned)value;
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}
if (string == 0)
string = (char *)malloc((tp-tmp)+sign+1);
sp = string;
if (sign)
*sp++ = '-';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}*/