File:  [Coherent Logic Development] / freem / src / strings.c
Revision 1.3: download - view: text, annotated - select for diffs
Sun Mar 9 19:50:47 2025 UTC (3 weeks, 2 days ago) by snw
Branches: MAIN
CVS tags: v0-62-3, v0-62-2, v0-62-1, v0-62-0, HEAD
Second phase of REUSE compliance and header reformat

/*
 *   $Id: strings.c,v 1.3 2025/03/09 19:50:47 snw Exp $
 *    freem string library
 *
 *  
 *   Author: Serena Willis <snw@coherent-logic.com>
 *    Copyright (C) 1998 MUG Deutschland
 *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
 *
 *
 *   This file is part of FreeM.
 *
 *   FreeM is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   FreeM 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 Affero Public License for more details.
 *
 *   You should have received a copy of the GNU Affero Public License
 *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
 *
 *   $Log: strings.c,v $
 *   Revision 1.3  2025/03/09 19:50:47  snw
 *   Second phase of REUSE compliance and header reformat
 *
 *
 * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
 * SPDX-License-Identifier: AGPL-3.0-or-later
 **/

#include "mpsdef.h"
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

/* length of 'source' string in bytes */
long int stlen (const char *source)				
{
    register int length = 0;

    while (*source++ != EOL) length++;

    return length;
}

long int stnlen (const char *source, size_t siz)
{
    register int length = 0;

    while ((*source++ != EOL) && (length < siz)) length++;

    return length;
}


/* copy string from 'source' to 'dest' */
long int stcpy (char *dest, const char *source)			
{
    register int count = 0;

    while ((*dest++ = *source++) != EOL) count++;

    return count;
}

long int stncpy (char *dest, const char *source, size_t siz)
{
    register int count = 0;

    while (((*dest++ = *source++) != EOL) && (count < siz)) count++;

    return count;
}
    

/* copy exactly 'length' characters from source to dest */
void stcpy0 (char *dest, const char *source, long length)		
{
    while (length-- > 0) *dest++ = *source++;

    return;
}


/* copy exactly 'length' characters from source to dest*/
void stcpy1 (char *dest, const char *source, long length)		
{
    while (length-- > 0) *dest-- = *source--;

    return;
}


/* concatenate string from 'source' to the end of 'dest' */
short int stcat (char *dest, const char *source)
{
    register int i = 0;

    while (dest[i++] != EOL);

    i--;
    
    while ((dest[i] = *source++) != EOL) {
	   
       if (i++ >= STRLEN) {
           //printf("i = %d\r\n", i);
           dest[--i] = EOL;	   
           return FALSE;
       }

    }

    return TRUE;
}

long int stncat (char *dest, const char *source, size_t siz)
{
    long int srclen;
    long int dstlen;

    srclen = stnlen (source, siz);
    dstlen = stnlen (dest, siz);

    
    return 0;
}

/* compare str1 and str2 */
short int stcmp (char *str1, char *str2)			
{
    while (*str1 == *str2) {
	
        if (*str1 == EOL) return 0;
	
        str1++;
        str2++;

    }
    
    return *str1 - *str2;
}

/* trim whitespace from string 's' */
char *trim (char *s)
{
    
    char *t = strdup (s);
    char *end;
    char *result;
    int final_len;
    
    if (t == NULL) return NULL;

    while (isspace ((unsigned char) *t)) t++;

    if (*t == 0) return t;

    end = t + strlen (t) - 1;

    while (end > t && isspace ((unsigned char) *end)) end--;

    end[1] = '\0';

    /* recover waste ('t' still occupies the same heap
     * as it did before the whitespace was stripped)
     */
    
    final_len = strlen (t);
    result = (char *) malloc ((final_len + 1) * sizeof (char));

    if (result == NULL) return NULL;
    
    strcpy (result, t);
    free (t);

    return result;

}


/* convert EOL-terminated string 'mstr' to NUL-terminated string in-place */
void stcnv_m2c(char *mstr)
{
    mstr[stlen(mstr)] = NUL; 
}

void stncnv_m2c(char *mstr, size_t siz)
{
    mstr[stnlen (mstr, siz)] = NUL;
}      

/* convert NUL-terminated string 'cstr' to EOL-terminated string in-place */
void stcnv_c2m(char *cstr)
{
    register int i;
    
    for(i = 0; i < 256; i++) {

        if(cstr[i] == '\0') {
            cstr[i] = '\201';
        
            return;
        }
        
    }
}

void stncnv_c2m(char *cstr, size_t siz)
{
    register int i;

    for (i = 0; i < siz; i++) {

        if (cstr[i] == NUL) {
            cstr[i] = EOL;
            return;
        }
        
    }

    return;
}
/* convert at most 'count' characters of *key into human-readable format in *buf */
size_t key_to_name(char *buf, const char *key, size_t count)
{
    size_t i;
    int j = 0;
    int first = 1;
    int has_subs = 0;
    int in_strlit = 0;
    char c;
    char next;

    if (key[0] == NUL) {
        buf[0] = NUL;

        return 0;
    }

    buf[0] = '^';

    for (i = 0; i < count; i++) {

        c = key[i];
        next = key[i + 1];
        
        switch (key[i]) {

            case EOL:
                
                if (first == 0) {

                    if (has_subs == 1) {

                        if (!in_strlit) {
                            buf[j++] = ')';
                            buf[j] = NUL;
                        }
                        else {
                            buf[j++] = '\"';
                            buf[j++] = ')';
                            buf[j] = NUL;
                        }

                    }
                    else {                        
                        buf[j] = NUL;
                    }

                }
                else {
                    buf[j] = NUL;
                }
                
                return i;


            case DELIM:
                
                if (first == 1) {
                
                    buf[j] = '(';
                    first = 0;
                    has_subs = 1;                    

                }
                else {

                    if (!in_strlit) {
                        buf[j] = ',';
                    }
                    else {

                        buf[j++] = '\"';
                        buf[j] = ',';

                        in_strlit = 0;

                    }

                }

                if (isalpha(next) && !in_strlit) {                    
                    in_strlit = 1;
                    buf[++j] = '\"';
                }
                else if (in_strlit) {
                    in_strlit = 0;
                    buf[++j] = '\"';
                }
                
                break;


            default:
                buf[j] = key[i];
                break;
        }

        j++;
    }

    return count;

}

size_t name_to_key(char *buf, const char *name, size_t count)
{
    size_t i;
    size_t j = 0;

    short insubs = FALSE;
    short instr = FALSE;

    char ch;

    for (i = 0; i < count; i++) buf[i] = NUL;

    for (i = 0; i < count; i++) {

        ch = name[i];

        switch (ch) {

            case EOL:
                buf[j] = ch;
                goto n_to_k_done;

            case '(':
                if (insubs == FALSE && instr == FALSE) {
                    insubs = TRUE;
                    buf[j++] = DELIM;
                }
                else {
                    if (instr == TRUE) {
                        buf[j++] = ch;
                    }
                }
                break;


            case ')':
                if (insubs == TRUE && instr == FALSE) {
                    buf[j] = EOL;

                    goto n_to_k_done;
                }
                else {
                    if (insubs == TRUE && instr == TRUE) {
                        buf[j++] = ch;                        
                    }
                }
                break;


            case ',':
                if (insubs == TRUE && instr == FALSE) {
                    if (buf[j - 1] != DELIM) {
                        buf[j++] = DELIM;
                    }
                }
                else if (insubs == TRUE && instr == TRUE) {
                    buf[j++] = ch;                    
                }

                break;


            case '"':

                if (insubs == TRUE && instr == FALSE) {
                    instr = TRUE;
                    
                    if (buf[j - 1] != DELIM) {
                        buf[j++] = DELIM;
                    }
                    
                    break;
                }

                if (instr == TRUE) {
                    instr = FALSE;
                    buf[j++] = DELIM;
                }

                break;


            default:
                buf[j++] = ch;
                break;
        }

    }

n_to_k_done:

    return j;

}

void create_var_key (char *buf, int subct, char *nam, ...)
{
    int i;
    va_list args;
    
    strcat (buf, nam);
    strcat (buf, "\202");
    
    va_start (args, nam);

    for (i = 0; i < subct; i++) {
        
        strcat (buf, va_arg (args, char *));

        if (i < (subct - 1)) strcat (buf, "\202");

    }

    va_end (args);

    strcat (buf, "\201");
}

void trim_decimal (char *s)
{
    register int i;

    for (i = stlen (s) - 1; s[i] == '0'; i--) s[i] = EOL;

    if (s[i] == '.') s[i] = EOL;
}

void uuid_v4 (char *buf)
{
    
    char *chars = "0123456789abcdef";
    int seg3num;
    int seg4num;
    int i;

    char seg1[9];
    char seg2[5];
    char seg3[5];
    char seg4[5];
    char seg5[13];
    
    seg3num = (rand () % 4095) + 16384;
    seg4num = (rand () % 16383) + 32768;

    for (i = 0; i < 9; i++) {
        seg1[i] = chars[rand () % 16];
    }

    seg1[8] = '\0';

    for (i = 0; i < 4; i++) {
        seg2[i] = chars[rand () % 16];
    }

    seg2[4] = '\0';

    snprintf (seg3, 5, "%04x", seg3num);
    snprintf (seg4, 5, "%04x", seg4num);

    for (i = 0; i < 12; i++) {
        seg5[i] = chars[rand () % 16];
    }

    seg5[12] = '\0';

    sprintf (buf, "%s-%s-%s-%s-%s", seg1, seg2, seg3, seg4, seg5);

    return;
    
}

        

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>