Logo Search packages:      
Sourcecode: afterstep version File versions

afterbase.c

/*
 * Copyright (C) 2001 Sasha Vasko <sasha at aftercode.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#ifdef _WIN32
#include "win32/config.h"
#else
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#include <sys/stat.h>

#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# if HAVE_SYS_DIRENT_H
#  include <sys/dirent.h>
#  define NAMLEN(dirent) strlen((dirent)->d_name)
# else
#  define dirent direct
#  define NAMLEN(dirent) (dirent)->d_namlen
#  if HAVE_SYS_NDIR_H
#   include <sys/ndir.h>
#  endif
#  if HAVE_SYS_DIR_H
#   include <sys/dir.h>
#  endif
#  if HAVE_NDIR_H
#   include <ndir.h>
#  endif
# endif
#endif

#ifdef _WIN32
#include "win32/afterbase.h"
#include <io.h>
#include <windows.h>
#define access _access
#else
#include "afterbase.h"
#endif

#ifdef X_DISPLAY_MISSING
#include "colornames.h"
#endif

/*#include <X11/Xlib.h>*/

Display *dpy = NULL ;
char    *asim_ApplicationName = NULL ;

void
asim_set_application_name (char *argv0)
{
      char *temp = &(argv0[0]);
      do
      {     /* Save our program name - for error messages */
            register int i = 1 ;                   /* we don't use standard strrchr since there
                                                                        * seems to be some wierdness in
                                                                        * CYGWIN implementation of it. */
            asim_ApplicationName =  temp ;
            while( temp[i] && temp[i] != '/' ) ++i ;
            temp = temp[i] ? &(temp[i]): NULL ;
      }while( temp != NULL );
}

const char *
asim_get_application_name()
{
      return asim_ApplicationName;
}

static unsigned int asim_as_output_threshold = OUTPUT_DEFAULT_THRESHOLD ;

unsigned int
asim_get_output_threshold()
{
      return asim_as_output_threshold ;
}

unsigned int
asim_set_output_threshold( unsigned int threshold )
{
    unsigned int old = asim_as_output_threshold;
    asim_as_output_threshold = threshold ;
    return old;
}


/* from libAfterBase/output.c : */
Bool asim_show_error( const char *error_format, ...)
{
    if( OUTPUT_LEVEL_ERROR <= get_output_threshold())
    {
        va_list ap;
        fprintf (stderr, "%s ERROR: ", get_application_name() );
        va_start (ap, error_format);
        vfprintf (stderr, error_format, ap);
        va_end (ap);
        fprintf (stderr, "\n" );
        return True;
    }
    return False;
}

Bool asim_show_warning( const char *warning_format, ...)
{
    if( OUTPUT_LEVEL_WARNING <= get_output_threshold())
    {
        va_list ap;
        fprintf (stderr, "%s warning: ", get_application_name() );
        va_start (ap, warning_format);
        vfprintf (stderr, warning_format, ap);
        va_end (ap);
        fprintf (stderr, "\n" );
        return True;
    }
    return False;
}

Bool asim_show_progress( const char *msg_format, ...)
{
    if( OUTPUT_LEVEL_PROGRESS <= get_output_threshold())
    {
        va_list ap;
        fprintf (stderr, "%s : ", get_application_name() );
        va_start (ap, msg_format);
        vfprintf (stderr, msg_format, ap);
        va_end (ap);
        fprintf (stderr, "\n" );
        return True;
    }
    return False;
}


Bool asim_show_debug( const char *file, const char *func, int line, const char *msg_format, ...)
{
    if( OUTPUT_LEVEL_DEBUG <= get_output_threshold())
    {
        va_list ap;
        fprintf (stderr, "%s debug msg: %s:%s():%d: ", get_application_name(), file, func, line );
        va_start (ap, msg_format);
        vfprintf (stderr, msg_format, ap);
        va_end (ap);
        fprintf (stderr, "\n" );
        return True;
    }
    return False;
}


void asim_nonGNUC_debugout( const char *format, ...)
{
    va_list ap;
    fprintf (stderr, "%s: ", get_application_name() );
    va_start (ap, format);
    vfprintf (stderr, format, ap);
    va_end (ap);
    fprintf (stderr, "\n" );
}

inline void asim_nonGNUC_debugout_stub( const char *format, ...)
{}

/* from libAfterBase/fs.c : */

int         asim_check_file_mode (const char *file, int mode)
{
      struct stat   st;

      if ((stat (file, &st) == -1) || (st.st_mode & S_IFMT) != mode)
            return (-1);
      else
            return (0);
}

char         *
asim_put_file_home (const char *path_with_home)
{
      static char  *home = NULL;                         /* the HOME environment variable */
      static char   default_home[3] = "./";
      static int    home_len = 0;
      char         *str = NULL, *ptr;
      register int  i;
      if (path_with_home == NULL)
            return NULL;
      /* home dir ? */
      if (path_with_home[0] != '~' || path_with_home[1] != '/')
      {
            char *t = mystrdup (path_with_home);
            return t;
      }

      if (home == NULL)
      {
            if ((home = getenv ("HOME")) == NULL)
                  home = &(default_home[0]);
            home_len = strlen (home);
      }

      for (i = 2; path_with_home[i]; i++);
      str = safemalloc (home_len + i);
      for (ptr = str + home_len-1; i > 0; i--)
            ptr[i] = path_with_home[i];
      for (i = 0; i < home_len; i++)
            str[i] = home[i];
      return str;
}

char*
asim_load_file(const char* realfilename)
{
      struct stat st;
      FILE* fp;
      char* str;
      int len;

      /* Get the file size. */
      if (stat(realfilename, &st)) return NULL;

      /* Open the file. */
      fp = fopen(realfilename, "rb");
      if (!(fp = fopen(realfilename, "rb"))) return NULL;

      /* Read in the file. */
      str = NEW_ARRAY(char, st.st_size + 1);
      len = fread(str, 1, st.st_size, fp);
      if (len >= 0) str[len] = '\0';

      fclose(fp);
      return str;
}


/****************************************************************************
 *
 * Find the specified icon file somewhere along the given path.
 *
 * There is a possible race condition here:  We check the file and later
 * do something with it.  By then, the file might not be accessible.
 * Oh well.
 *
 ****************************************************************************/
/* supposedly pathlist should not include any environment variables
   including things like ~/
 */
void 
unix_path2dos_path( char *path )
{
      int i = strlen(path) ; 
      while( --i >= 0 ) 
            if( path[i] == '/' && ( i == 0 || path[i-1] != '/' ) )
                  path[i] = '\\' ;
}              


char         *
asim_find_file (const char *file, const char *pathlist, int type)
{
      char          *path;
      register int   len;
      int            max_path = 0;
      register char *ptr;
      register int   i;
      Bool local = False ;

      if (file == NULL)
            return NULL;
#ifdef _WIN32
#define PATH_SEPARATOR_CHAR ';'
#define PATH_CHAR '\\'
#else
#define PATH_SEPARATOR_CHAR ':'
#define PATH_CHAR '/'
#endif
      
      if (*file == PATH_CHAR || *file == '~' || ((pathlist == NULL) || (*pathlist == '\0')))
            local = True ;
      else if( file[0] == '.' && (file[1] == PATH_CHAR || (file[1] == '.' && file[2] == PATH_CHAR))) 
            local = True ;
      else if( strncmp( file, "$HOME", 5) == 0 ) 
            local = True ;
      if( local ) 
      {
            path = put_file_home (file);
            if ( access (path, type) == 0 )
            {
                  return path;
            }
            free (path);
            return NULL;
      }
/*    return put_file_home(file); */
      for (i = 0; file[i]; i++);
      len = i ;
      for (ptr = (char *)pathlist; *ptr; ptr += i)
      {
            if (*ptr == ':' || *ptr == PATH_SEPARATOR_CHAR)
                  ptr++;
            for (i = 0; ptr[i] && ptr[i] != ':' && ptr[i] != PATH_SEPARATOR_CHAR; i++);
            if (i > max_path)
                  max_path = i;
      }

      path = safemalloc (max_path + 1 + len + 1 + 100);
      strcpy( path+max_path+1, file );
      path[max_path] = PATH_CHAR ;

      ptr = (char*)&(pathlist[0]) ;
      while( ptr[0] != '\0' )
      {
            for( i = 0 ; ptr[i] == ':' || ptr[i] == PATH_SEPARATOR_CHAR; ++i );
            ptr += i ;
            for( i = 0 ; ptr[i] != ':' && ptr[i] != PATH_SEPARATOR_CHAR && ptr[i] != '\0' ; ++i );
            if( i > 0 )
            {
                  strncpy( path+max_path-i, ptr, i );
                  if (access(path, type) == 0)
                  {
                        char* res = mystrdup(path+max_path-i);
                        free( path );
                        return res;
                  }
            }
            ptr += i ;
      }
      free (path);
      return NULL;
}

static char         *
find_envvar (char *var_start, int *end_pos)
{
      char          backup, *name_start = var_start;
      register int  i;
      char         *var = NULL;

      if (var_start[0] == '{')
      {
            name_start++;
            for (i = 1; var_start[i] && var_start[i] != '}'; i++);
      } else
            for (i = 0; isalnum ((int)var_start[i]) || var_start[i] == '_'; i++);

      backup = var_start[i];
      var_start[i] = '\0';
      var = getenv (name_start);
      var_start[i] = backup;

      *end_pos = i;
      if (backup == '}')
            (*end_pos)++;
      return var;
}

static char *
do_replace_envvar (char *path)
{
      char         *data = path, *tmp;
      char         *home = getenv ("HOME");
      int           pos = 0, len, home_len = 0;

      if (path == NULL)
            return NULL;
      if (*path == '\0')
            return path;
      len = strlen (path);
      if (home)
            home_len = strlen (home);

      while (*(data + pos))
      {
            char         *var;
            int           var_len, end_pos;

            while (*(data + pos) != '$' && *(data + pos))
            {
                  if (*(data + pos) == '~' && *(data + pos + 1) == '/')
                  {
                        if (pos > 0)
                              if (*(data + pos - 1) != ':')
                              {
                                    pos += 2;
                                    continue;
                              }
                        if (home == NULL)
                              *(data + (pos++)) = '.';
                        else
                        {
                              len += home_len;
                              tmp = safemalloc (len);
                              strncpy (tmp, data, pos);
                              strcpy (tmp + pos, home);
                              strcpy (tmp + pos + home_len, data + pos + 1);
                              if( data != path )
                                    free (data);
                              data = tmp;
                              pos += home_len;
                        }
                  }
                  pos++;
            }
            if (*(data + pos) == '\0')
                  break;
            /* found $ sign - trying to replace var */
            if ((var = find_envvar (data + pos + 1, &end_pos)) == NULL)
            {
                  ++pos;
                  continue;
            }
            var_len = strlen (var);
            len += var_len;
            tmp = safemalloc (len);
            strncpy (tmp, data, pos);
            strcpy (tmp + pos, var);
            strcpy (tmp + pos + var_len, data + pos + end_pos + 1);
            if( data != path )
                  free (data);
            data = tmp;
      }
      return data;
}

char*
asim_copy_replace_envvar (char *path)
{
      char         *res = do_replace_envvar( path );
      return ( res == path )?mystrdup( res ):res;
}


/*******************************************************************/
/* from mystring.c : */
char         *
asim_mystrndup (const char *str, size_t n)
{
      char         *c = NULL;
      if (str)
      {
            c = malloc (n + 1);
            strncpy (c, str, n);
            c[n] = '\0';
      }
      return c;
}

#ifdef X_DISPLAY_MISSING
static int compare_xcolor_entries(const void *a, const void *b)
{
   return strcmp((const char *) a, ((const XColorEntry *) b)->name);
}

static int FindColor(const char *name, CARD32 *colorPtr)
{
   XColorEntry *found;

   found = bsearch(name, xColors, numXColors, sizeof(XColorEntry),
                   compare_xcolor_entries);
   if (found == NULL)
      return 0;

   *colorPtr = 0xFF000000|((found->red<<16)&0x00FF0000)|((found->green<<8)&0x0000FF00)|((found->blue)&0x000000FF);
   return 1;
}
#endif

/*******************************************************************/
/* from parse,c : */
const char *asim_parse_argb_color( const char *color, CARD32 *pargb )
{
#define hextoi(h)   (isdigit(h)?((h)-'0'):(isupper(h)?((h)-'A'+10):((h)-'a'+10)))
      if( color )
      {
            if( *color == '#' )
            {
                  CARD32 argb = 0 ;
                  int len = 0 ;
                  register const char *ptr = color+1 ;
                  while( isxdigit((int)ptr[len]) ) len++;
                  if( len >= 3)
                  {
                        if( (len&0x3) == 0 && len != 12 )
                        {  /* we do have alpha channel !!! */
                              len = len>>2 ;
                              argb = (hextoi((int)ptr[0])<<28)&0xF0000000 ;
                              if( len > 1 )
                                    argb |= (hextoi((int)ptr[1])<<24)&0x0F000000 ;
                              else
                                    argb |= 0x0F000000;
                              ptr += len ;
                        }else
                        {
                              len = len/3 ;
                              argb = 0xFF000000;
                        }
                        /* processing rest of the channels : */
                        if( len == 1 )
                        {
                              argb |= 0x000F0F0F;
                              argb |= (hextoi((int)ptr[0])<<20)&0x00F00000 ;
                              argb |= (hextoi((int)ptr[1])<<12)&0x0000F000 ;
                              argb |= (hextoi((int)ptr[2])<<4 )&0x000000F0 ;
                              ptr += 3 ;
                        }else
                        {
                              argb |= (hextoi((int)ptr[0])<<20)&0x00F00000 ;
                              argb |= (hextoi((int)ptr[1])<<16)&0x000F0000 ;
                              ptr += len ;
                              argb |= (hextoi((int)ptr[0])<<12)&0x0000F000 ;
                              argb |= (hextoi((int)ptr[1])<<8) &0x00000F00 ;
                              ptr += len ;
                              argb |= (hextoi((int)ptr[0])<<4 )&0x000000F0 ;
                              argb |= (hextoi((int)ptr[1]))    &0x0000000F ;
                              ptr += len ;
                        }
                        *pargb = argb ;
                        return ptr;
                  }
            }else if( *color )
            {
                  /* does not really matter here what screen to use : */
#ifdef X_DISPLAY_MISSING
                  register const char *ptr = &(color[0]);
            if(!FindColor(color, pargb))
                return color;
            while( !isspace((int)*ptr) && *ptr != '\0' ) ptr++;
                  return ptr;
#else
                  if( dpy == NULL )
                        return color ;
                  else
                  {
                        register const char *ptr = &(color[0]);
#ifndef X_DISPLAY_MISSING
                        XColor xcol, xcol_scr ;
/* XXX Not sure if Scr.asv->colormap is always defined here.  If not,
** change back to DefaultColormap(dpy,DefaultScreen(dpy)). */
                        if( XLookupColor( dpy, DefaultColormap(dpy,DefaultScreen(dpy)), color, &xcol, &xcol_scr) )
                              *pargb = 0xFF000000|((xcol.red<<8)&0x00FF0000)|(xcol.green&0x0000FF00)|((xcol.blue>>8)&0x000000FF);
#endif
                        while( !isspace((int)*ptr) && *ptr != '\0' ) ptr++;
                        return ptr;
                  }
#endif
            }
      }
      return color;
}

/*******************************************************************/
/* from ashash,c : */
ASHashKey asim_default_hash_func (ASHashableValue value, ASHashKey hash_size)
{
      return (ASHashKey)(value % hash_size);
}

long
asim_default_compare_func (ASHashableValue value1, ASHashableValue value2)
{
      return ((long)value1 - (long)value2);
}

long
asim_desc_long_compare_func (ASHashableValue value1, ASHashableValue value2)
{
    return ((long)value2 - (long)value1);
}

void
asim_init_ashash (ASHashTable * hash, Bool freeresources)
{
LOCAL_DEBUG_CALLER_OUT( " has = %p, free ? %d", hash, freeresources );
      if (hash)
      {
            if (freeresources)
                  if (hash->buckets)
                        free (hash->buckets);
            memset (hash, 0x00, sizeof (ASHashTable));
      }
}

ASHashTable  *
asim_create_ashash (ASHashKey size,
                     ASHashKey (*hash_func) (ASHashableValue, ASHashKey),
                     long (*compare_func) (ASHashableValue, ASHashableValue),
                     void (*item_destroy_func) (ASHashableValue, void *))
{
      ASHashTable  *hash;

      if (size <= 0)
            size = 63;

      hash = safemalloc (sizeof (ASHashTable));
      init_ashash (hash, False);

      hash->buckets = safemalloc (sizeof (ASHashBucket) * size);
      memset (hash->buckets, 0x00, sizeof (ASHashBucket) * size);

      hash->size = size;

      if (hash_func)
            hash->hash_func = hash_func;
      else
            hash->hash_func = asim_default_hash_func;

      if (compare_func)
            hash->compare_func = compare_func;
      else
            hash->compare_func = asim_default_compare_func;

      hash->item_destroy_func = item_destroy_func;

      return hash;
}

static void
destroy_ashash_bucket (ASHashBucket * bucket, void (*item_destroy_func) (ASHashableValue, void *))
{
      register ASHashItem *item, *next;

      for (item = *bucket; item != NULL; item = next)
      {
            next = item->next;
            if (item_destroy_func)
                  item_destroy_func (item->value, item->data);
            free (item);
      }
      *bucket = NULL;
}

void
asim_destroy_ashash (ASHashTable ** hash)
{
LOCAL_DEBUG_CALLER_OUT( " hash = %p, *hash = %p", hash, *hash  );
      if (*hash)
      {
            register int  i;

            for (i = (*hash)->size - 1; i >= 0; i--)
                  if ((*hash)->buckets[i])
                        destroy_ashash_bucket (&((*hash)->buckets[i]), (*hash)->item_destroy_func);

            asim_init_ashash (*hash, True);
            free (*hash);
            *hash = NULL;
      }
}

static        ASHashResult
add_item_to_bucket (ASHashBucket * bucket, ASHashItem * item, long (*compare_func) (ASHashableValue, ASHashableValue))
{
      ASHashItem  **tmp;

      /* first check if we already have this item */
      for (tmp = bucket; *tmp != NULL; tmp = &((*tmp)->next))
      {
            register long res = compare_func ((*tmp)->value, item->value);

            if (res == 0)
                  return ((*tmp)->data == item->data) ? ASH_ItemExistsSame : ASH_ItemExistsDiffer;
            else if (res > 0)
                  break;
      }
      /* now actually add this item */
      item->next = (*tmp);
      *tmp = item;
      return ASH_Success;
}

#define DEALLOC_CACHE_SIZE      1024
static ASHashItem*  deallocated_mem[DEALLOC_CACHE_SIZE+10] ;
static unsigned int deallocated_used = 0 ;

ASHashResult
asim_add_hash_item (ASHashTable * hash, ASHashableValue value, void *data)
{
      ASHashKey     key;
      ASHashItem   *item;
      ASHashResult  res;

      if (hash == NULL)
        return ASH_BadParameter;

      key = hash->hash_func (value, hash->size);
      if (key >= hash->size)
        return ASH_BadParameter;

    if( deallocated_used > 0 )
        item = deallocated_mem[--deallocated_used];
    else
        item = safemalloc (sizeof (ASHashItem));

      item->next = NULL;
      item->value = value;
      item->data = data;

      res = add_item_to_bucket (&(hash->buckets[key]), item, hash->compare_func);
      if (res == ASH_Success)
      {
            hash->most_recent = item ;
            hash->items_num++;
            if (hash->buckets[key]->next == NULL)
                  hash->buckets_used++;
      } else
            free (item);
      return res;
}

static ASHashItem **
find_item_in_bucket (ASHashBucket * bucket,
                               ASHashableValue value, long (*compare_func) (ASHashableValue, ASHashableValue))
{
      register ASHashItem **tmp;
      register long res;

      /* first check if we already have this item */
      for (tmp = bucket; *tmp != NULL; tmp = &((*tmp)->next))
      {
            res = compare_func ((*tmp)->value, value);
            if (res == 0)
                  return tmp;
            else if (res > 0)
                  break;
      }
      return NULL;
}

ASHashResult
asim_get_hash_item (ASHashTable * hash, ASHashableValue value, void **trg)
{
      ASHashKey     key;
      ASHashItem  **pitem = NULL;

      if (hash)
      {
            key = hash->hash_func (value, hash->size);
            if (key < hash->size)
                  pitem = find_item_in_bucket (&(hash->buckets[key]), value, hash->compare_func);
      }
      if (pitem)
            if (*pitem)
            {
                  if (trg)
                        *trg = (*pitem)->data;
                  return ASH_Success;
            }
      return ASH_ItemNotExists;
}

ASHashResult
asim_remove_hash_item (ASHashTable * hash, ASHashableValue value, void **trg, Bool destroy)
{
      ASHashKey     key = 0;
      ASHashItem  **pitem = NULL;

      if (hash)
      {
            key = hash->hash_func (value, hash->size);
            if (key < hash->size)
                  pitem = find_item_in_bucket (&(hash->buckets[key]), value, hash->compare_func);
      }
      if (pitem)
            if (*pitem)
            {
                  ASHashItem   *next;

                  if( hash->most_recent == *pitem )
                        hash->most_recent = NULL ;

                  if (trg)
                        *trg = (*pitem)->data;

                  next = (*pitem)->next;
                  if (hash->item_destroy_func && destroy)
                        hash->item_destroy_func ((*pitem)->value, (trg) ? NULL : (*pitem)->data);

            if( deallocated_used < DEALLOC_CACHE_SIZE )
            {
                deallocated_mem[deallocated_used++] = *pitem ;
            }else
                free( *pitem );

            *pitem = next;
                  if (hash->buckets[key] == NULL)
                        hash->buckets_used--;
                  hash->items_num--;

                  return ASH_Success;
            }
      return ASH_ItemNotExists;
}

void asim_flush_ashash_memory_pool()
{
      /* we better disable errors as some of this data will belong to memory audit : */
      while( deallocated_used > 0 )
            free( deallocated_mem[--deallocated_used] );
}

/************************************************************************/
/************************************************************************/
/*    Some usefull implementations                          */
/************************************************************************/

/* case sensitive strings hash */
ASHashKey
asim_string_hash_value (ASHashableValue value, ASHashKey hash_size)
{
      ASHashKey     hash_key = 0;
      register int  i = 0;
      char         *string = (char*)value;
      register char c;

      do
      {
            c = string[i];
            if (c == '\0')
                  break;
            hash_key += (((ASHashKey) c) << i);
            ++i ;
      }while( i < ((sizeof (ASHashKey) - sizeof (char)) << 3) );
      return hash_key % hash_size;
}

long
asim_string_compare (ASHashableValue value1, ASHashableValue value2)
{
      register char *str1 = (char*)value1;
      register char *str2 = (char*)value2;
      register int   i = 0 ;

      if (str1 == str2)
            return 0;
      if (str1 == NULL)
            return -1;
      if (str2 == NULL)
            return 1;
      do
      {
            if (str1[i] != str2[i])
                  return (long)(str1[i]) - (long)(str2[i]);

      }while( str1[i++] );
      return 0;
}

void
asim_string_destroy_without_data (ASHashableValue value, void *data)
{
      if ((char*)value != NULL)
            free ((char*)value);
}

/* variation for case-unsensitive strings */
ASHashKey
asim_casestring_hash_value (ASHashableValue value, ASHashKey hash_size)
{
      ASHashKey     hash_key = 0;
      register int  i = 0;
      char         *string = (char*)value;
      register int c;

      do
      {
            c = string[i];
            if (c == '\0')
                  break;
            if (isupper (c))
                  c = tolower (c);
            hash_key += (((ASHashKey) c) << i);
            ++i;
      }while(i < ((sizeof (ASHashKey) - sizeof (char)) << 3));

      return hash_key % hash_size;
}

long
asim_casestring_compare (ASHashableValue value1, ASHashableValue value2)
{
      register char *str1 = (char*)value1;
      register char *str2 = (char*)value2;
      register int   i = 0;

      if (str1 == str2)
            return 0;
      if (str1 == NULL)
            return -1;
      if (str2 == NULL)
            return 1;
      do
      {
            int          u1, u2;

            u1 = str1[i];
            u2 = str2[i];
            if (islower (u1))
                  u1 = toupper (u1);
            if (islower (u2))
                  u2 = toupper (u2);
            if (u1 != u2)
                  return (long)u1 - (long)u2;
      }while( str1[i++] );
      return 0;
}

int
asim_get_drawable_size (Drawable d, unsigned int *ret_w, unsigned int *ret_h)
{
      *ret_w = 0;
      *ret_h = 0;
#ifndef X_DISPLAY_MISSING
      if( d )
      {
            Window        root;
            unsigned int  ujunk;
            int           junk;
            if (XGetGeometry (dpy, d, &root, &junk, &junk, ret_w, ret_h, &ujunk, &ujunk) != 0)
                  return 1;
      }
#endif
      return 0;
}

#ifdef X_DISPLAY_MISSING
int XParseGeometry (  char *string,int *x,int *y,
                      unsigned int *width,    /* RETURN */
                                unsigned int *height)    /* RETURN */
{
      show_error( "Parsing of geometry is not supported without either Xlib opr libAfterBase" );
      return 0;
}
void XDestroyImage( void* d){}
int XGetWindowAttributes( void*d, Window w, unsigned long m, void* s){  return 0;}
void *XGetImage( void* dpy,Drawable d,int x,int y,unsigned int width,unsigned int height, unsigned long m,int t)
{return NULL ;}
unsigned long XGetPixel(void* d, int x, int y){return 0;}
int XQueryColors(void* a,Colormap c,void* x,int m){return 0;}
#endif


/***************************************/
/* from sleep.c                        */
/***************************************/
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif
#ifndef _WIN32
# include <sys/times.h>
#endif
static clock_t _as_ticker_last_tick = 0;
static clock_t _as_ticker_tick_size = 1;
static clock_t _as_ticker_tick_time = 0;

/**************************************************************************
 * Sleep for n microseconds
 *************************************************************************/
void
sleep_a_little (int n)
{
#ifndef _WIN32
      struct timeval value;

      if (n <= 0)
            return;

      value.tv_usec = n % 1000000;
      value.tv_sec = n / 1000000;

#ifndef PORTABLE_SELECT
#ifdef __hpux
#define PORTABLE_SELECT(w,i,o,e,t)  select((w),(int *)(i),(int *)(o),(e),(t))
#else
#define PORTABLE_SELECT(w,i,o,e,t)  select((w),(i),(o),(e),(t))
#endif
#endif
      PORTABLE_SELECT (1, 0, 0, 0, &value);
#else /* win32 : */
      Sleep(n);
#endif
}

void
asim_start_ticker (unsigned int size)
{
#ifndef _WIN32
      struct tms    t;

      _as_ticker_last_tick = times (&t);           /* in system ticks */
      if (_as_ticker_tick_time == 0)
      {
            register clock_t delta = _as_ticker_last_tick;
            /* calibrating clock - how many ms per cpu tick ? */
            sleep_a_little (100);
            _as_ticker_last_tick = times (&t);
            delta = _as_ticker_last_tick - delta ;
            if( delta <= 0 )
                  _as_ticker_tick_time = 100;
            else
                  _as_ticker_tick_time = 101 / delta;
      }
#else
      _as_ticker_tick_time = 1000;
      _as_ticker_last_tick = time(NULL) ;
#endif
      _as_ticker_tick_size = size;                 /* in ms */

}

void
asim_wait_tick ()
{
#ifndef _WIN32
      struct tms    t;
      register clock_t curr = (times (&t) - _as_ticker_last_tick) * _as_ticker_tick_time;
#else
      register int curr = (time(NULL) - _as_ticker_last_tick) * _as_ticker_tick_time;
#endif

      if (curr < _as_ticker_tick_size)
            sleep_a_little (_as_ticker_tick_size - curr);

#ifndef _WIN32
      _as_ticker_last_tick = times (&t);
#else
      _as_ticker_last_tick = time(NULL) ;
#endif
}

#ifndef _WIN32
/*
 * Non-NULL select and dcomp pointers are *NOT* tested, but should be OK.
 * They are not used by afterstep however, so this implementation should
 * be good enough.
 *
 * c.ridd@isode.com
 */
int
asim_my_scandir (char *dirname, struct direntry *(*namelist[]),
                  int (*select) (const char *), int (*dcomp) (struct direntry **, struct direntry **))
{
      DIR          *d;
      struct dirent *e;                                  /* Pointer to static struct inside readdir() */
      struct direntry **nl;                              /* Array of pointers to dirents */
      struct direntry **nnl;
      int           n;                                   /* Count of nl used so far */
      int           sizenl;                              /* Number of entries in nl array */
      int           j;
      size_t        realsize;
      char         *filename;                            /* For building filename to pass to stat */
      char         *p;                                   /* Place where filename starts */
      struct stat   buf;


      d = opendir (dirname);

      if (d == NULL)
            return -1;

      filename = (char *)safemalloc (strlen (dirname) + PATH_MAX + 2);
      if (filename == NULL)
      {
            closedir (d);
            return -1;
      }
      strcpy (filename, dirname);
      p = filename + strlen (filename);
      *p++ = '/';
      *p = 0;                                                        /* Just in case... */

      nl = NULL;
      n = 0;
      sizenl = 0;

      while ((e = readdir (d)) != NULL)
      {
            if ((select == NULL) || select (&(e->d_name[0])))
            {
                  /* add */
                  if (sizenl == n)
                  {
                        /* Grow array */
                        sizenl += 32;                          /* arbitrary delta */
                        nnl = realloc (nl, sizenl * sizeof (struct direntry *));
                        if (nnl == NULL)
                        {
                              /* Free the old array */
                              for (j = 0; j < n; j++)
                                    free (nl[j]);
                              free (nl);
                              free (filename);
                              closedir (d);
                              return -1;
                        }
                        nl = nnl;
                  }
                  realsize = offsetof (struct direntry, d_name)+strlen (e->d_name) + 1;
                  nl[n] = (struct direntry *)safemalloc (realsize);
                  if (nl[n] == NULL)
                  {
                        for (j = 0; j < n; j++)
                              free (nl[j]);
                        free (nl);
                        free (filename);
                        closedir (d);
                        return -1;
                  }
                  /* Fill in the fields using stat() */
                  strcpy (p, e->d_name);
                  if (stat (filename, &buf) == -1)
                  {
                        for (j = 0; j <= n; j++)
                              free (nl[j]);
                        free (nl);
                        free (filename);
                        closedir (d);
                        return -1;
                  }
                  nl[n]->d_mode = buf.st_mode;
                  nl[n]->d_mtime = buf.st_mtime;
                  strcpy (nl[n]->d_name, e->d_name);
                  n++;
            }
      }
      free (filename);

      if (closedir (d) == -1)
      {
            free (nl);
            return -1;
      }
      if (n == 0)
      {
            if (nl)
                  free (nl);
/* OK, but not point sorting or freeing anything */
            return 0;
      }
      *namelist = realloc (nl, n * sizeof (struct direntry *));

      if (*namelist == NULL)
      {
            for (j = 0; j < n; j++)
                  free (nl[j]);
            free (nl);
            return -1;
      }
      /* Optionally sort the list */
      if (dcomp)
            qsort (*namelist, n, sizeof (struct direntry *), (int (*)())dcomp);

      /* Return the count of the entries */
      return n;
}
#endif

Generated by  Doxygen 1.6.0   Back to index