Annotation of sbbs/xpdev/genwrap.c, revision 1.1.1.1

1.1       root        1: /* genwrap.c */
                      2: 
                      3: /* General cross-platform development wrappers */
                      4: 
                      5: /* $Id: genwrap.c,v 1.47 2004/10/27 22:00:28 rswindell Exp $ */
                      6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
                     11:  * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html         *
                     12:  *                                                                                                                                                     *
                     13:  * This library is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU Lesser General Public License          *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU Lesser General Public License for more details: lgpl.txt or     *
                     18:  * http://www.fsf.org/copyleft/lesser.html                                                                     *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #include <string.h>     /* strlen() */
                     39: #include <stdarg.h>    /* vsnprintf() */
                     40: #include <stdlib.h>            /* RAND_MAX */
                     41: #include <fcntl.h>             /* O_NOCTTY */
                     42: #include <time.h>              /* clock() */
                     43: #include <errno.h>             /* errno */
                     44: #include <ctype.h>             /* toupper/tolower */
                     45: 
                     46: #if defined(__unix__)
                     47:        #include <sys/ioctl.h>          /* ioctl() */
                     48:        #include <sys/utsname.h>        /* uname() */
                     49:        /* KIOCSOUND */
                     50:        #if defined(__FreeBSD__)
                     51:                #include <sys/kbio.h>
                     52:        #elif defined(__linux__)
                     53:                #include <sys/kd.h>     
                     54:        #elif defined(__solaris__)
                     55:                #include <sys/kbio.h>
                     56:                #include <sys/kbd.h>
                     57:        #endif
                     58:        #if defined(__OpenBSD__) || defined(__NetBSD__)
                     59:                #include <machine/spkr.h>
                     60:        #elif defined(__FreeBSD__)
                     61:                #include <machine/speaker.h>
                     62:        #endif
                     63: #endif /* __unix__ */
                     64: 
                     65: #include "genwrap.h"   /* Verify prototypes */
                     66: 
                     67: /****************************************************************************/
                     68: /* Used to replace snprintf()  guarantees to terminate.                                                */
                     69: /****************************************************************************/
                     70: int DLLCALL safe_snprintf(char *dst, size_t size, const char *fmt, ...)
                     71: {
                     72:        va_list argptr;
                     73:        int     numchars;
                     74: 
                     75:        va_start(argptr,fmt);
                     76:        numchars= vsnprintf(dst,size,fmt,argptr);
                     77:        va_end(argptr);
                     78:        dst[size-1]=0;
                     79: #ifdef _MSC_VER
                     80:        if(numchars==-1)
                     81:                numchars=strlen(dst);
                     82: #endif
                     83:        if(numchars>=(int)size && numchars>0)
                     84:                numchars=size-1;
                     85:        return(numchars);
                     86: }
                     87: 
                     88: /****************************************************************************/
                     89: /* Return last character of string                                                                                     */
                     90: /****************************************************************************/
                     91: char* DLLCALL lastchar(const char* str)
                     92: {
                     93:        size_t  len;
                     94: 
                     95:        len = strlen(str);
                     96: 
                     97:        if(len)
                     98:                return((char*)&str[len-1]);
                     99: 
                    100:        return((char*)str);
                    101: }
                    102: 
                    103: /****************************************************************************/
                    104: /* Return character value of C-escaped (\) character                                           */
                    105: /****************************************************************************/
                    106: char DLLCALL unescape_char(char ch)
                    107: {
                    108:        switch(ch) {
                    109:                case '\\':      return('\\');
                    110:                case '\'':      return('\'');
                    111:                case '"':       return('"');
                    112:                case '?':       return('?');
                    113:                case 'a':       return('\a');
                    114:                case 'b':       return('\b');
                    115:                case 'f':       return('\f');
                    116:                case 'n':       return('\n');
                    117:                case 'r':       return('\r');
                    118:                case 't':       return('\t');
                    119:                case 'v':       return('\v');
                    120:        }
                    121:        return(ch);
                    122: }
                    123: 
                    124: /****************************************************************************/
                    125: /* Return character value of C-escaped (\) character sequence                          */
                    126: /* (supports \Xhh and \0ooo escape sequences)                                                          */
                    127: /* This code currently has problems with sequences like: "\x01blue"                    */
                    128: /****************************************************************************/
                    129: char DLLCALL unescape_char_ptr(const char* str, char** endptr)
                    130: {
                    131:        char    ch;
                    132: 
                    133:        if(toupper(*str)=='X')
                    134:                ch=(char)strtol(++str,endptr,16);
                    135:        else if(isdigit(*str))
                    136:                ch=(char)strtol(++str,endptr,8);
                    137:        else {
                    138:                ch=unescape_char(*(str++));
                    139:                if(endptr!=NULL)
                    140:                        *endptr=(char*)str;
                    141:        }
                    142: 
                    143:        return(ch);
                    144: }
                    145: 
                    146: /****************************************************************************/
                    147: /* Unescape a C string, in place                                                                                       */
                    148: /****************************************************************************/
                    149: char* DLLCALL unescape_cstr(char* str)
                    150: {
                    151:        char    ch;
                    152:        char*   buf;
                    153:        char*   src;
                    154:        char*   dst;
                    155: 
                    156:        if(str==NULL || (buf=strdup(str))==NULL)
                    157:                return(NULL);
                    158: 
                    159:        src=buf;
                    160:        dst=str;
                    161:        while((ch=*(src++))!=0) {
                    162:                if(ch=='\\')    /* escape */
                    163:                        ch=unescape_char_ptr(src,&src);
                    164:                *(dst++)=ch;
                    165:        }
                    166:        *dst=0;
                    167:        free(buf);
                    168:        return(str);
                    169: }
                    170: 
                    171: /****************************************************************************/
                    172: /* Convert ASCIIZ string to upper case                                                                         */
                    173: /****************************************************************************/
                    174: #if defined(__unix__)
                    175: char* DLLCALL strupr(char* str)
                    176: {
                    177:        char*   p=str;
                    178: 
                    179:        while(*p) {
                    180:                *p=toupper(*p);
                    181:                p++;
                    182:        }
                    183:        return(str);
                    184: }
                    185: /****************************************************************************/
                    186: /* Convert ASCIIZ string to lower case                                                                         */
                    187: /****************************************************************************/
                    188: char* DLLCALL strlwr(char* str)
                    189: {
                    190:        char*   p=str;
                    191: 
                    192:        while(*p) {
                    193:                *p=tolower(*p);
                    194:                p++;
                    195:        }
                    196:        return(str);
                    197: }
                    198: /****************************************************************************/
                    199: /* Reverse characters of a string (provided by amcleod)                                                */
                    200: /****************************************************************************/
                    201: char* strrev(char* str)
                    202: {
                    203:     char t, *i=str, *j=str+strlen(str);
                    204: 
                    205:     while (i<j) {
                    206:         t=*i; *(i++)=*(--j); *j=t;
                    207:     }
                    208:     return str;
                    209: }
                    210: 
                    211: /****************************************************************************/
                    212: /* Generate a tone at specified frequency for specified milliseconds           */
                    213: /* Thanks to Casey Martin for this code                                                                                */
                    214: /****************************************************************************/
                    215: void DLLCALL unix_beep(int freq, int dur)
                    216: {
                    217:        static int console_fd=-1;
                    218: 
                    219: #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
                    220:        int speaker_fd=-1;
                    221:        tone_t tone;
                    222: 
                    223:        speaker_fd = open("/dev/speaker", O_WRONLY|O_APPEND);
                    224:        if(speaker_fd != -1)  {
                    225:                tone.frequency=freq;
                    226:                tone.duration=dur;
                    227:                ioctl(speaker_fd,SPKRTONE,&tone);
                    228:                close(speaker_fd);
                    229:                return;
                    230:        }
                    231: #endif
                    232: 
                    233: #if !defined(__GNU__) && !defined(__QNX__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__)
                    234:        if(console_fd == -1) 
                    235:                console_fd = open("/dev/console", O_NOCTTY);
                    236:        
                    237:        if(console_fd != -1) {
                    238: #if defined(__solaris__)
                    239:                ioctl(console_fd, KIOCCMD, KBD_CMD_BELL);
                    240: #else
                    241:                if(freq != 0)   /* Don't divide by zero */
                    242:                        ioctl(console_fd, KIOCSOUND, (int) (1193180 / freq));
                    243: #endif /* solaris */
                    244:                SLEEP(dur);
                    245: #if defined(__solaris__)
                    246:                ioctl(console_fd, KIOCCMD, KBD_CMD_NOBELL);     /* turn off tone */
                    247: #else
                    248:                ioctl(console_fd, KIOCSOUND, 0);        /* turn off tone */
                    249: #endif /* solaris */
                    250:        }
                    251: #endif
                    252: }
                    253: #endif
                    254: 
                    255: /****************************************************************************/
                    256: /* Return random number between 0 and n-1                                                                      */
                    257: /****************************************************************************/
                    258: int DLLCALL xp_random(int n)
                    259: {
                    260:        float f;
                    261:        static BOOL initialized;
                    262: 
                    263:        if(!initialized) {
                    264:                srand(time(NULL));      /* seed random number generator */
                    265:                rand();                         /* throw away first result */
                    266:                initialized=TRUE;
                    267:        }
                    268:        if(n<2)
                    269:                return(0);
                    270:        f=(float)rand()/(float)RAND_MAX;
                    271: 
                    272:        return((int)(n*f));
                    273: }
                    274: 
                    275: /****************************************************************************/
                    276: /* Return ASCII string representation of ulong                                                         */
                    277: /* There may be a native GNU C Library function to this...                                     */
                    278: /****************************************************************************/
                    279: #if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__WATCOMC__)
                    280: char* DLLCALL ultoa(ulong val, char* str, int radix)
                    281: {
                    282:        switch(radix) {
                    283:                case 8:
                    284:                        sprintf(str,"%lo",val);
                    285:                        break;
                    286:                case 10:
                    287:                        sprintf(str,"%lu",val);
                    288:                        break;
                    289:                case 16:
                    290:                        sprintf(str,"%lx",val);
                    291:                        break;
                    292:                default:
                    293:                        sprintf(str,"bad radix: %d",radix);
                    294:                        break;
                    295:        }
                    296:        return(str);
                    297: }
                    298: #endif
                    299: 
                    300: /****************************************************************************/
                    301: /* Write the version details of the current operating system into str          */
                    302: /****************************************************************************/
                    303: char* DLLCALL os_version(char *str)
                    304: {
                    305: #if defined(__OS2__) && defined(__BORLANDC__)
                    306: 
                    307:        sprintf(str,"OS/2 %u.%u (%u.%u)",_osmajor/10,_osminor/10,_osmajor,_osminor);
                    308: 
                    309: #elif defined(_WIN32)
                    310: 
                    311:        /* Windows Version */
                    312:        char*                   winflavor="";
                    313:        OSVERSIONINFO   winver;
                    314: 
                    315:        winver.dwOSVersionInfoSize=sizeof(winver);
                    316:        GetVersionEx(&winver);
                    317: 
                    318:        switch(winver.dwPlatformId) {
                    319:                case VER_PLATFORM_WIN32_NT:
                    320:                        winflavor="NT ";
                    321:                        break;
                    322:                case VER_PLATFORM_WIN32s:
                    323:                        winflavor="Win32s ";
                    324:                        break;
                    325:                case VER_PLATFORM_WIN32_WINDOWS:
                    326:                        winver.dwBuildNumber&=0xffff;
                    327:                        break;
                    328:        }
                    329: 
                    330:        sprintf(str,"Windows %sVersion %u.%u (Build %u) %s"
                    331:                        ,winflavor
                    332:                        ,winver.dwMajorVersion, winver.dwMinorVersion
                    333:                        ,winver.dwBuildNumber,winver.szCSDVersion);
                    334: 
                    335: #elif defined(__unix__)
                    336: 
                    337:        struct utsname unixver;
                    338: 
                    339:        if(uname(&unixver)<0)
                    340:                sprintf(str,"Unix (uname errno: %d)",errno);
                    341:        else
                    342:                sprintf(str,"%s %s %s"
                    343:                        ,unixver.sysname        /* e.g. "Linux" */
                    344:                        ,unixver.release        /* e.g. "2.2.14-5.0" */
                    345:                        ,unixver.machine        /* e.g. "i586" */
                    346:                        );
                    347: 
                    348: #else  /* DOS */
                    349: 
                    350:        sprintf(str,"DOS %u.%02u",_osmajor,_osminor);
                    351: 
                    352: #endif
                    353: 
                    354:        return(str);
                    355: }
                    356: 
                    357: #if !defined(__unix__)
                    358: 
                    359: /****************************************************************************/
                    360: /* Win32 implementations of the recursive (thread-safe) versions of std C      */
                    361: /* time functions (gmtime, localtime, ctime, and asctime) used in Unix.                */
                    362: /* The native Win32 versions of these functions are already thread-safe.       */
                    363: /****************************************************************************/
                    364: 
                    365: struct tm* DLLCALL gmtime_r(const time_t* t, struct tm* tm)
                    366: {
                    367:        struct tm* tmp = gmtime(t);
                    368: 
                    369:        if(tmp==NULL)
                    370:                return(NULL);
                    371: 
                    372:        *tm = *tmp;
                    373:        return(tm);
                    374: }
                    375: 
                    376: struct tm* DLLCALL localtime_r(const time_t* t, struct tm* tm)
                    377: {
                    378:        struct tm* tmp = localtime(t);
                    379: 
                    380:        if(tmp==NULL)
                    381:                return(NULL);
                    382: 
                    383:        *tm = *tmp;
                    384:        return(tm);
                    385: }
                    386: 
                    387: char* DLLCALL ctime_r(const time_t *t, char *buf)
                    388: {
                    389:        char* p = ctime(t);
                    390: 
                    391:        if(p==NULL)
                    392:                return(NULL);
                    393: 
                    394:        strcpy(buf,p);
                    395:        return(buf);
                    396: }
                    397: 
                    398: char* DLLCALL asctime_r(const struct tm *tm, char *buf)
                    399: {
                    400:        char* p = asctime(tm);
                    401: 
                    402:        if(p==NULL)
                    403:                return(NULL);
                    404: 
                    405:        strcpy(buf,p);
                    406:        return(buf);
                    407: }
                    408: 
                    409: #endif /* !defined(__unix__) */
                    410: 
                    411: /********************************************/
                    412: /* Hi-res real-time clock implementation.      */
                    413: /********************************************/
                    414: #ifdef __unix__
                    415: clock_t DLLCALL msclock(void)
                    416: {
                    417:        long long int usecs;
                    418:        struct timeval tv;
                    419:        if(gettimeofday(&tv,NULL)==1)
                    420:                return(-1);
                    421:        usecs=tv.tv_sec*1000000+tv.tv_usec;
                    422:        return((clock_t)(usecs/(1000000/MSCLOCKS_PER_SEC)));
                    423: }
                    424: #endif
                    425: 
                    426: /****************************************************************************/
                    427: /* Truncates all white-space chars off end of 'str'    (needed by STRERRROR)   */
                    428: /****************************************************************************/
                    429: char* DLLCALL truncsp(char* str)
                    430: {
                    431:        size_t i,len;
                    432: 
                    433:        i=len=strlen(str);
                    434:        while(i && (str[i-1]==' ' || str[i-1]=='\t' || str[i-1]=='\r' || str[i-1]=='\n')) 
                    435:                i--;
                    436:        if(i!=len)
                    437:                str[i]=0;       /* truncate */
                    438: 
                    439:        return(str);
                    440: }
                    441: 
                    442: /****************************************************************************/
                    443: /* Truncates all white-space chars off end of \n-terminated lines in 'str'     */
                    444: /****************************************************************************/
                    445: char* DLLCALL truncsp_lines(char* dst)
                    446: {
                    447:        char* sp;
                    448:        char* dp;
                    449:        char* src;
                    450: 
                    451:        if((src=strdup(dst))==NULL)
                    452:                return(dst);
                    453: 
                    454:        for(sp=src, dp=dst; *sp!=0; sp++) {
                    455:                if(*sp=='\n')
                    456:                        while(dp!=dst 
                    457:                                && (*(dp-1)==' ' || *(dp-1)=='\t' || *(dp-1)=='\r') && *(dp-1)!='\n') 
                    458:                                        dp--;
                    459:                *(dp++)=*sp;
                    460:        }
                    461:        *dp=0;
                    462: 
                    463:        free(src);
                    464:        return(dst);
                    465: }
                    466: 
                    467: /****************************************************************************/
                    468: /* Truncates carriage-return and line-feed chars off end of 'str'                      */
                    469: /****************************************************************************/
                    470: char* DLLCALL truncnl(char* str)
                    471: {
                    472:        size_t i,len;
                    473: 
                    474:        i=len=strlen(str);
                    475:        while(i && (str[i-1]=='\r' || str[i-1]=='\n')) 
                    476:                i--;
                    477:        if(i!=len)
                    478:                str[i]=0;       /* truncate */
                    479: 
                    480:        return(str);
                    481: }
                    482: 
                    483: /****************************************************************************/
                    484: /* Return errno from the proper C Library implementation                                       */
                    485: /* (single/multi-threaded)                                                                                                     */
                    486: /****************************************************************************/
                    487: int DLLCALL    get_errno(void)
                    488: {
                    489:        return(errno);
                    490: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.