File indexing completed on 2022-11-29 14:10:21

0001 /*
0002  * This file is part of WorkMan, the civilized CD player library
0003  * Copyright (C) 1991-1997 by Steven Grimm <koreth@midwinter.com>
0004  * Copyright (C) by Dirk Försterling <milliByte@DeathsDoor.com>
0005  * Copyright (C) 2004-2006 Alexander Kern <alex.kern@gmx.de>
0006  *
0007  * This library is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU Library General Public
0009  * License as published by the Free Software Foundation; either
0010  * version 2 of the License, or (at your option) any later version.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Library General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Library General Public
0018  * License along with this library; if not, write to the Free
0019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0020  *
0021  *
0022  * Some helpful functions...
0023  *
0024  */
0025 
0026 #define _BSD_SOURCE /* strdup, timerclear */
0027 #define _DEFAULT_SOURCE /* stop glibc whining about the previous line */
0028 
0029 #include <stdio.h>
0030 #include <string.h>
0031 #include <stdlib.h>
0032 #include <errno.h>
0033 #include <stdarg.h>
0034 #include <sys/time.h>
0035 #include "include/workman_defs.h"
0036 #include "include/wm_config.h"
0037 #include "include/wm_helpers.h"
0038 #include "include/wm_struct.h"
0039 
0040 #define WM_MSG_CLASS WM_MSG_CLASS_MISC
0041 
0042 int wm_lib_verbosity = WM_MSG_LEVEL_ERROR | WM_MSG_CLASS_ALL;
0043 
0044 /*
0045  * Some seleced functions of version reporting follow...
0046  */
0047 
0048 int wm_libver_major( void ){return WM_LIBVER_MAJOR;}
0049 int wm_libver_minor( void ){return WM_LIBVER_MINOR;}
0050 int wm_libver_pl( void ){return WM_LIBVER_PL;}
0051 
0052 char *wm_libver_name( void )
0053 {
0054     char *s = NULL;
0055 
0056     wm_strmcat(&s, WM_LIBVER_NAME);
0057     return s;
0058 } /* wm_libver_name() */
0059 
0060 char *wm_libver_number( void )
0061 {
0062     char *s = NULL;
0063 
0064     s = malloc(10);
0065     /* this is not used very often, so don't care about speed...*/
0066     sprintf(s, "%d.%d.%d", wm_libver_major(), wm_libver_minor(), wm_libver_pl());
0067     return s;
0068 } /* wm_libver_number() */
0069 
0070 char *wm_libver_date( void )
0071 {
0072     char *s = NULL;
0073     wm_strmcat(&s, __DATE__);
0074     return s;
0075 } /* wm_libver_date() */
0076 
0077 char *wm_libver_string( void )
0078 {
0079     char *s = NULL;
0080 
0081     wm_strmcat( &s, wm_libver_name() );
0082     wm_strmcat( &s, " " );
0083     wm_strmcat( &s, wm_libver_number() );
0084     return s;
0085 } /* wm_libver_string() */
0086 
0087 
0088 /*
0089  *
0090  * Now for some memory management...
0091  *
0092  */
0093 
0094 /* Free some memory and set a pointer to null. */
0095 void freeup( char **x )
0096 {
0097     if (*x != NULL)
0098     {
0099         free(*x);
0100         *x = NULL;
0101     }
0102 } /* freeup() */
0103 
0104 /* Copy into a malloced string. */
0105 void
0106 wm_strmcpy( char **t, const char *s )
0107 {
0108     wm_lib_message(WM_MSG_CLASS_MISC | WM_MSG_LEVEL_DEBUG, "wm_strmcpy(%s, '%s')\n", *t, s);
0109     if (*t != NULL)
0110       {
0111         wm_lib_message(WM_MSG_CLASS_MISC | WM_MSG_LEVEL_DEBUG, "wm_strmcpy freeing pointer %p\n", *t);
0112         free(*t);
0113       }
0114 
0115     *t = malloc(strlen(s) + 1);
0116     if (*t == NULL)
0117     {
0118         perror("wm_strmcpy");
0119         exit(1);
0120     }
0121 
0122     wm_lib_message(WM_MSG_CLASS_MISC | WM_MSG_LEVEL_DEBUG, "wm_strmcpy finally copying (%p, '%s')\n", *t, s);
0123     strncpy(*t, s, strlen(s));
0124 } /* wm_strmcpy() */
0125 
0126 /* Add to a malloced string. */
0127 void
0128 wm_strmcat( char **t, const char *s)
0129 {
0130     int len = strlen(s) + 1;
0131 
0132     wm_lib_message(WM_MSG_CLASS_MISC | WM_MSG_LEVEL_DEBUG, "wm_strmcat(%s, %s)\n", *t, s);
0133 
0134     if (*s == '\0')
0135         return;
0136 
0137     if (*t != NULL)
0138     {
0139         len += strlen(*t);
0140         *t = realloc(*t, len);
0141         if (*t == NULL)
0142         {
0143             perror("wm_strmcat");
0144             exit(1);
0145         }
0146         strcat(*t, s);
0147     }
0148     else
0149         wm_strmcpy(t, s);
0150 } /* wm_strmcat() */
0151 
0152 /* Duplicate a string.  Some systems have this in libc, but not all. */
0153 char *
0154 wm_strdup( char *s )
0155 {
0156     char    *new;
0157 
0158     new = malloc(strlen(s) + 1);
0159     if (new)
0160         strcpy(new, s);
0161     return (new);
0162 } /* wm_strdup() */
0163 
0164 
0165 /*
0166  * set and get verbosity level.
0167  */
0168 void wm_lib_set_verbosity( int level )
0169 {
0170     int l = level & WM_MSG_LEVEL_ALL;
0171     int c = level & WM_MSG_CLASS_ALL;
0172     if( WM_MSG_LEVEL_NONE <= l && l <= WM_MSG_LEVEL_DEBUG )
0173     {
0174         wm_lib_verbosity = l | c;
0175         wm_lib_message(WM_MSG_CLASS_MISC | WM_MSG_LEVEL_DEBUG, "Verbosity set to 0x%x|0x%x\n", l, c);
0176     }
0177 } /* wm_lib_set_verbosity */
0178 
0179 int wm_lib_get_verbosity( void )
0180 {
0181     return wm_lib_verbosity;
0182 }
0183 
0184 /*
0185  * wm_lib_message().
0186  *
0187  * any message that falls into allowed classes and has at least
0188  * verbosity level wm_lib_verbosity & 0xf will be printed.
0189  *
0190  * Usage:
0191  *
0192  * wm_lib_message( WM_MSG_LEVEL | WM_MSG_CLASS, "format", contents);
0193  *
0194  * To simplify the usage, you may simply use WM_MSG_CLASS. It should be
0195  * defined in each module to reflect the correct message class.
0196  *
0197  */
0198 void wm_lib_message( unsigned int level, const char *fmt, ... )
0199 {
0200     va_list ap;
0201     
0202     unsigned int l, c, vl, vc;
0203     /* verbosity level */
0204     vl = wm_lib_verbosity & WM_MSG_LEVEL_ALL;
0205     /* allowed classes */
0206     vc = wm_lib_verbosity & WM_MSG_CLASS_ALL;
0207 
0208     l = level & WM_MSG_LEVEL_ALL;
0209     c = level & WM_MSG_CLASS_ALL;
0210 
0211     /*
0212      * print it only if level and class are allowed.
0213      */
0214     if( (l <= vl) && (vc & c) )
0215     {
0216         fprintf(stderr, "libWorkMan: ");
0217         va_start(ap, fmt);
0218         vfprintf(stderr, fmt, ap);
0219         va_end(ap);
0220     }
0221 } /* wm_lib_message() */
0222 
0223 /*
0224  * Simulate usleep() using select().
0225  */
0226 int
0227 wm_susleep( int usec )
0228 {
0229     struct timeval  tv;
0230 
0231     timerclear(&tv);
0232     tv.tv_sec = usec / 1000000;
0233     tv.tv_usec = usec % 1000000;
0234     return (select(0, NULL, NULL, NULL, &tv));
0235 } /* wm_susleep() */
0236 
0237