Annotation of sbbs/sbbs3/str_util.c, revision 1.1.1.1

1.1       root        1: /* str_util.c */
                      2: 
                      3: /* Synchronet string utility routines */
                      4: 
                      5: /* $Id: str_util.c,v 1.30 2004/09/11 09:36:19 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 program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU 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 General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.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 "sbbs.h"
                     39: 
                     40: /****************************************************************************/
                     41: /* Removes ctrl-a codes from the string 'instr'                             */
                     42: /****************************************************************************/
                     43: char* DLLCALL remove_ctrl_a(char *instr, char *outstr)
                     44: {
                     45:        char str[1024],*p;
                     46:        uint i,j;
                     47: 
                     48:        for(i=j=0;instr[i] && j<sizeof(str)-1;i++) {
                     49:                if(instr[i]==CTRL_A && instr[i+1]!=0)
                     50:                        i++;
                     51:                else str[j++]=instr[i]; 
                     52:        }
                     53:        str[j]=0;
                     54:        if(outstr!=NULL)
                     55:                p=outstr;
                     56:        else
                     57:                p=instr;
                     58:        strcpy(p,str);
                     59:        return(p);
                     60: }
                     61: 
                     62: char* DLLCALL strip_ctrl(char *str)
                     63: {
                     64:        char tmp[1024];
                     65:        int i,j;
                     66: 
                     67:        for(i=j=0;str[i] && j<(int)sizeof(tmp)-1;i++) {
                     68:                if(str[i]==CTRL_A && str[i+1]!=0)
                     69:                        i++;
                     70:                else if((uchar)str[i]>=' ')
                     71:                        tmp[j++]=str[i];
                     72:        }
                     73:        if(i!=j) {
                     74:                tmp[j]=0;
                     75:                strcpy(str,tmp);
                     76:        }
                     77:        return(str);
                     78: }
                     79: 
                     80: char* DLLCALL strip_exascii(char *str)
                     81: {
                     82:        char tmp[1024];
                     83:        int i,j;
                     84: 
                     85:        for(i=j=0;str[i] && j<(int)sizeof(tmp)-1;i++)
                     86:                if(!(str[i]&0x80))
                     87:                        tmp[j++]=str[i];
                     88:        tmp[j]=0;
                     89:        strcpy(str,tmp);
                     90:        return(str);
                     91: }
                     92: 
                     93: char* DLLCALL prep_file_desc(char *str)
                     94: {
                     95:        char tmp[1024];
                     96:        int i,j;
                     97: 
                     98:        for(i=j=0;str[i];i++)
                     99:                if(str[i]==CTRL_A && str[i+1]!=0)
                    100:                        i++;
                    101:                else if(j && str[i]<=' ' && tmp[j-1]==' ')
                    102:                        continue;
                    103:                else if(i && !isalnum(str[i]) && str[i]==str[i-1])
                    104:                        continue;
                    105:                else if((uchar)str[i]>=' ')
                    106:                        tmp[j++]=str[i];
                    107:                else if(str[i]==TAB || (str[i]==CR && str[i+1]==LF))
                    108:                        tmp[j++]=' ';
                    109:        tmp[j]=0;
                    110:        strcpy(str,tmp);
                    111:        return(str);
                    112: }
                    113: 
                    114: /****************************************************************************/
                    115: /* Pattern matching string search of 'insearchof' in 'fname'.                          */
                    116: /****************************************************************************/
                    117: BOOL DLLCALL findstr(char* insearchof, char* fname)
                    118: {
                    119:        char*   p;
                    120:        char    str[128];
                    121:        char    search[81];
                    122:        int             c;
                    123:        int             i;
                    124:        BOOL    found;
                    125:        FILE*   stream;
                    126: 
                    127:        if((stream=fopen(fname,"r"))==NULL)
                    128:                return(FALSE); 
                    129: 
                    130:        SAFECOPY(search,insearchof);
                    131:        strupr(search);
                    132: 
                    133:        found=FALSE;
                    134: 
                    135:        while(!feof(stream) && !ferror(stream) && !found) {
                    136:                if(!fgets(str,sizeof(str),stream))
                    137:                        break;
                    138:                
                    139:                found=FALSE;
                    140: 
                    141:                p=str;  
                    142:                while(*p && *p<=' ') p++; /* Skip white-space */
                    143: 
                    144:                if(*p==';')             /* comment */
                    145:                        continue;
                    146: 
                    147:                if(*p=='!')     {       /* !match */
                    148:                        found=TRUE;
                    149:                        p++;
                    150:                }
                    151: 
                    152:                truncsp(p);
                    153:                c=strlen(p);
                    154:                if(c) {
                    155:                        c--;
                    156:                        strupr(p);
                    157:                        if(p[c]=='~') {
                    158:                                p[c]=0;
                    159:                                if(strstr(search,p))
                    160:                                        found=!found; 
                    161:                        }
                    162: 
                    163:                        else if(p[c]=='^' || p[c]=='*') {
                    164:                                p[c]=0;
                    165:                                if(!strncmp(p,search,c))
                    166:                                        found=!found; 
                    167:                        }
                    168: 
                    169:                        else if(p[0]=='*') {
                    170:                                i=strlen(search);
                    171:                                if(i<c)
                    172:                                        continue;
                    173:                                if(!strncmp(p+1,search+(i-c),c))
                    174:                                        found=!found; 
                    175:                        }
                    176: 
                    177:                        else if(!strcmp(p,search))
                    178:                                found=!found; 
                    179:                } 
                    180:        }
                    181:        fclose(stream);
                    182:        return(found);
                    183: }
                    184: 
                    185: /****************************************************************************/
                    186: /* Searches the file <name>.can in the TEXT directory for matches                      */
                    187: /* Returns TRUE if found in list, FALSE if not.                                                                */
                    188: /****************************************************************************/
                    189: BOOL DLLCALL trashcan(scfg_t* cfg, char* insearchof, char* name)
                    190: {
                    191:        char fname[MAX_PATH+1];
                    192: 
                    193:        sprintf(fname,"%s%s.can",cfg->text_dir,name);
                    194:        return(findstr(insearchof,fname));
                    195: }
                    196: 
                    197: /****************************************************************************/
                    198: /* Returns the number of characters in 'str' not counting ctrl-ax codes                */
                    199: /* or the null terminator                                                                                                      */
                    200: /****************************************************************************/
                    201: int bstrlen(char *str)
                    202: {
                    203:        int i=0;
                    204: 
                    205:        while(*str) {
                    206:                if(*str==CTRL_A)
                    207:                        str++;
                    208:                else
                    209:                        i++;
                    210:                if(!(*str)) break;
                    211:                str++; }
                    212:        return(i);
                    213: }
                    214: 
                    215: /****************************************************************************/
                    216: /* Returns in 'string' a character representation of the number in l with   */
                    217: /* commas.                                                                                                                                     */
                    218: /****************************************************************************/
                    219: char* DLLCALL ultoac(ulong l, char *string)
                    220: {
                    221:        char str[256];
                    222:        int i,j,k;
                    223: 
                    224:        ultoa(l,str,10);
                    225:        i=strlen(str)-1;
                    226:        j=i/3+1+i;
                    227:        string[j--]=0;
                    228:        for(k=1;i>-1;k++) {
                    229:                string[j--]=str[i--];
                    230:                if(j>0 && !(k%3))
                    231:                        string[j--]=','; }
                    232:        return(string);
                    233: }
                    234: 
                    235: /****************************************************************************/
                    236: /* Truncate string at first occurance of char in specified character set       */
                    237: /****************************************************************************/
                    238: char* DLLCALL truncstr(char* str, const char* set)
                    239: {
                    240:        char* p;
                    241: 
                    242:        p=strpbrk(str,set);
                    243:        if(p!=NULL && *p!=0)
                    244:                *p=0;
                    245: 
                    246:        return(p);
                    247: }
                    248: 
                    249: /****************************************************************************/
                    250: /* rot13 encoder/decoder - courtesy of Mike Acar                                                       */
                    251: /****************************************************************************/
                    252: char* DLLCALL rot13(char* str)
                    253: {
                    254:        char ch, cap;
                    255:        char* p;
                    256:   
                    257:        p=str;
                    258:        while((ch=*p)!=0) {
                    259:                cap = ch & 32;
                    260:                ch &= ~cap;
                    261:                ch = ((ch >= 'A') && (ch <= 'Z') ? ((ch - 'A' + 13) % 26 + 'A') : ch) | cap;
                    262:                *(p++)=ch;
                    263:     }
                    264: 
                    265:        return(str);
                    266: }
                    267: 
                    268: /****************************************************************************/
                    269: /* Puts a backslash on path strings if not just a drive letter and colon       */
                    270: /****************************************************************************/
                    271: void backslashcolon(char *str)
                    272: {
                    273:     int i;
                    274: 
                    275:        i=strlen(str);
                    276:        if(i && !IS_PATH_DELIM(str[i-1]) && str[i-1]!=':') {
                    277:                str[i]=PATH_DELIM; 
                    278:                str[i+1]=0; 
                    279:        }
                    280: }
                    281: 
                    282: /****************************************************************************/
                    283: /* Compares pointers to pointers to char. Used in conjuction with qsort()   */
                    284: /****************************************************************************/
                    285: int pstrcmp(char **str1, char **str2)
                    286: {
                    287:        return(strcmp(*str1,*str2));
                    288: }
                    289: 
                    290: /****************************************************************************/
                    291: /* Returns the number of characters that are the same between str1 and str2 */
                    292: /****************************************************************************/
                    293: int strsame(char *str1, char *str2)
                    294: {
                    295:        int i,j=0;
                    296: 
                    297:        for(i=0;str1[i];i++)
                    298:                if(str1[i]==str2[i]) j++;
                    299:        return(j);
                    300: }
                    301: 
                    302: 
                    303: /****************************************************************************/
                    304: /* Returns string for 2 digit hex+ numbers up to 575                                           */
                    305: /****************************************************************************/
                    306: char *hexplus(uint num, char *str)
                    307: {
                    308:        sprintf(str,"%03x",num);
                    309:        str[0]=num/0x100 ? 'f'+(num/0x10)-0xf : str[1];
                    310:        str[1]=str[2];
                    311:        str[2]=0;
                    312:        return(str);
                    313: }
                    314: 
                    315: /****************************************************************************/
                    316: /* Converts an ASCII Hex string into an ulong                               */
                    317: /* by Steve Deppe (Ille Homine Albe)                                                                           */
                    318: /****************************************************************************/
                    319: ulong ahtoul(char *str)
                    320: {
                    321:     ulong l,val=0;
                    322: 
                    323:        while((l=(*str++)|0x20)!=0x20)
                    324:                val=(l&0xf)+(l>>6&1)*9+val*16;
                    325:        return(val);
                    326: }
                    327: 
                    328: /****************************************************************************/
                    329: /* Converts hex-plus string to integer                                                                         */
                    330: /****************************************************************************/
                    331: uint hptoi(char *str)
                    332: {
                    333:        char tmp[128];
                    334:        uint i;
                    335: 
                    336:        if(!str[1] || toupper(str[0])<='F')
                    337:                return(ahtoul(str));
                    338:        strcpy(tmp,str);
                    339:        tmp[0]='F';
                    340:        i=ahtoul(tmp)+((toupper(str[0])-'F')*0x10);
                    341:        return(i);
                    342: }
                    343: 
                    344: /****************************************************************************/
                    345: /* Returns 1 if a is a valid ctrl-a code, 0 if it isn't.                    */
                    346: /****************************************************************************/
                    347: BOOL DLLCALL validattr(char a)
                    348: {
                    349: 
                    350:        switch(toupper(a)) {
                    351:                case '+':       /* push attr    */
                    352:                case '-':   /* pop attr         */
                    353:                case '_':   /* clear        */
                    354:                case 'B':   /* blue     fg  */
                    355:                case 'C':   /* cyan     fg  */
                    356:                case 'G':   /* green    fg  */
                    357:                case 'H':   /* high     fg  */
                    358:                case 'I':   /* blink        */
                    359:                case 'K':   /* black    fg  */
                    360:                case 'L':   /* cls          */
                    361:                case 'M':   /* magenta  fg  */
                    362:                case 'N':   /* normal       */
                    363:                case 'P':   /* pause        */
                    364:                case 'R':   /* red      fg  */
                    365:                case 'W':   /* white    fg  */
                    366:                case 'Y':   /* yellow   fg  */
                    367:                case '0':   /* black    bg  */
                    368:                case '1':   /* red      bg  */
                    369:                case '2':   /* green    bg  */
                    370:                case '3':   /* brown    bg  */
                    371:                case '4':   /* blue     bg  */
                    372:                case '5':   /* magenta  bg  */
                    373:                case '6':   /* cyan     bg  */
                    374:                case '7':   /* white    bg  */
                    375:                        return(TRUE); 
                    376:        }
                    377:        return(FALSE);
                    378: }
                    379: 
                    380: /****************************************************************************/
                    381: /* Strips invalid Ctrl-Ax sequences from str                                */
                    382: /* Returns number of ^A's in line                                           */
                    383: /****************************************************************************/
                    384: size_t DLLCALL strip_invalid_attr(char *strin)
                    385: {
                    386:     char str[1024];
                    387:     size_t a,c,d;
                    388: 
                    389:        for(a=c=d=0;strin[c] && d<sizeof(str)-1;c++) {
                    390:                if(strin[c]==CTRL_A && strin[c+1]!=0) {
                    391:                        a++;
                    392:                        if(!validattr(strin[c+1])) {
                    393:                                c++;
                    394:                                continue; 
                    395:                        } 
                    396:                }
                    397:                str[d++]=strin[c]; 
                    398:        }
                    399:        str[d]=0;
                    400:        strcpy(strin,str);
                    401:        return(a);
                    402: }
                    403: 

unix.superglobalmegacorp.com

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