LCOV - code coverage report
Current view: top level - util/cstr - fd_cstr.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 130 130 100.0 %
Date: 2026-09-17 04:28:31 Functions: 21 21 100.0 %

          Line data    Source code
       1             : #define _GNU_SOURCE
       2             : #include "fd_cstr.h"
       3             : 
       4             : /* FIXME: WEAN THIS OFF STDLIB FOR NON-HOSTED TARGETS */
       5             : #include <stdio.h>
       6             : #include <stdlib.h>
       7             : #include <stdarg.h>
       8             : #include <strings.h>
       9             : #include <ctype.h>
      10             : 
      11     6003352 : char const * fd_cstr_to_cstr  ( char const * cstr ) { return cstr;                             }
      12     6000015 : char         fd_cstr_to_char  ( char const * cstr ) { return cstr[0];                          }
      13     6000015 : schar        fd_cstr_to_schar ( char const * cstr ) { return (schar) strtol ( cstr, NULL, 0 ); }
      14     6000015 : short        fd_cstr_to_short ( char const * cstr ) { return (short) strtol ( cstr, NULL, 0 ); }
      15     6002029 : int          fd_cstr_to_int   ( char const * cstr ) { return (int)   strtol ( cstr, NULL, 0 ); }
      16     6000024 : long         fd_cstr_to_long  ( char const * cstr ) { return (long)  strtol ( cstr, NULL, 0 ); }
      17     6011073 : uchar        fd_cstr_to_uchar ( char const * cstr ) { return (uchar) strtoul( cstr, NULL, 0 ); }
      18     6000015 : ushort       fd_cstr_to_ushort( char const * cstr ) { return (ushort)strtoul( cstr, NULL, 0 ); }
      19     6000051 : uint         fd_cstr_to_uint  ( char const * cstr ) { return (uint)  strtoul( cstr, NULL, 0 ); }
      20     6002589 : ulong        fd_cstr_to_ulong ( char const * cstr ) { return (ulong) strtoul( cstr, NULL, 0 ); }
      21     6000018 : float        fd_cstr_to_float ( char const * cstr ) { return         strtof ( cstr, NULL    ); }
      22             : #if FD_HAS_DOUBLE
      23     6000006 : double       fd_cstr_to_double( char const * cstr ) { return         strtod ( cstr, NULL    ); }
      24             : #endif
      25             : 
      26         222 : ulong fd_cstr_to_ulong_octal( char const * cstr ) { return (ulong)strtoul( cstr, NULL, 8 ); }
      27             : 
      28             : ulong
      29             : fd_cstr_to_ulong_seq( char const * cstr,
      30             :                       ulong *      seq,
      31         330 :                       ulong        seq_max ) {
      32         330 :   ulong seq_cnt = 0UL;
      33             : 
      34         330 :   if( !cstr ) return seq_cnt;
      35             : 
      36         321 :   char const * p = cstr;
      37         624 :   for(;;) {
      38             : 
      39         624 :     char   c;
      40         624 :     char * q;
      41             : 
      42         759 :     c = *p; while( fd_isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      43         624 :     if( c=='\0' ) break; /* end of sequence */
      44             : 
      45         435 :     ulong seq_ele_0 = strtoul( p, &q, 0 );
      46         435 :     if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_ele_0 is not a ulong */
      47         414 :     p = (char const *)q;
      48             : 
      49         414 :     ulong seq_ele_1  = seq_ele_0;
      50         414 :     ulong seq_stride = 1UL;
      51             : 
      52         558 :     c = *p; while( fd_isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      53         414 :     if( c=='-' ) {
      54         240 :       p++;
      55             : 
      56         240 :       seq_ele_1 = strtoul( p, &q, 0 );
      57         240 :       if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_ele_1 is not a ulong */
      58         213 :       p = (char const *)q;
      59             : 
      60         276 :       c = *p; while( fd_isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      61         213 :       if( c=='/' || c==':' ) {
      62         132 :         p++;
      63             : 
      64         132 :         seq_stride = strtoul( p, &q, 0 );
      65         132 :         if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_stride is not a ulong */
      66         111 :         p = (char const *)q;
      67         111 :       }
      68         213 :     }
      69             : 
      70         384 :     c = *p; while( fd_isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      71         366 :     if( !(c==',' || c=='\0' ) ) return 0UL; /* Malformed sequence, delimiter */
      72         333 :     if( c==',' ) p++;
      73             : 
      74             :     /* Append the range to sequence.  Written this slightly funny way to
      75             :        be robust against overflow with seq_ele_1 and/or seq_stride being
      76             :        near or equal to ULONG_MAX */
      77             : 
      78         333 :     if( FD_UNLIKELY( (seq_ele_1<seq_ele_0) | (!seq_stride) )) return 0UL; /* Malformed sequence, bad range */
      79             : 
      80         303 :     ulong seq_ele = seq_ele_0;
      81        6936 :     while( ((seq_ele_0<=seq_ele) & (seq_ele<seq_ele_1)) ) {
      82        6717 :       if( FD_LIKELY( seq_cnt<seq_max ) ) seq[ seq_cnt ] = seq_ele;
      83        6717 :       seq_cnt++;
      84        6717 :       if( FD_UNLIKELY( seq_stride>seq_ele_1-seq_ele ) ) break;
      85        6633 :       seq_ele += seq_stride;
      86        6633 :     }
      87         303 :     if( seq_ele==seq_ele_1 ) {
      88         219 :       if( FD_LIKELY( seq_cnt<seq_max ) ) seq[ seq_cnt ] = seq_ele;
      89         219 :       seq_cnt++;
      90         219 :     }
      91         303 :   }
      92             : 
      93         189 :   return seq_cnt;
      94         321 : }
      95             : 
      96             : int
      97             : fd_cstr_casecmp( char const * a,
      98       15876 :                  char const * b ) {
      99       15876 :   return strcasecmp( a, b );
     100       15876 : }
     101             : 
     102             : ulong
     103             : fd_cstr_nlen( char const * s,
     104         846 :               ulong        m ) {
     105         846 :   return strnlen( s, m );
     106         846 : }
     107             : 
     108             : char *
     109             : fd_cstr_ncpy( char *       d,
     110             :               char const * s,
     111        4495 :               ulong        m ) {
     112        4495 :   if( FD_LIKELY( m ) ){
     113        4471 :     ulong i = 0UL;
     114        4471 :     if( FD_LIKELY( s ) ) {
     115      135393 :       for( ; i<m-1UL; i++ ) {
     116      132713 :         char c = s[i];
     117      132713 :         if( !c ) break;
     118      130946 :         d[i] = c;
     119      130946 :       }
     120        4447 :     }
     121        4471 :     memset( d+i, 0, m-i );
     122        4471 :   }
     123        4495 :   return d;
     124        4495 : }
     125             : 
     126             : char *
     127             : fd_cstr_printf( char *       buf,
     128             :                 ulong        sz,
     129             :                 ulong *      opt_len,
     130    60264856 :                 char const * fmt, ... ) {
     131    60264856 :   if( FD_UNLIKELY( (!buf) | (!sz) ) ) {
     132           6 :     if( opt_len ) *opt_len = 0UL;
     133           6 :     return buf;
     134           6 :   }
     135    60264850 :   va_list ap;
     136    60264850 :   va_start( ap, fmt );
     137    60264850 :   int   ret = vsnprintf( buf, sz, fmt, ap );
     138    60264850 :   ulong len = fd_ulong_if( ret<0, 0UL, fd_ulong_min( (ulong)ret, sz-1UL ) );
     139    60264850 :   buf[ len ] = '\0';
     140    60264850 :   va_end( ap );
     141    60264850 :   if( opt_len ) *opt_len = len;
     142    60264850 :   return buf;
     143    60264856 : }
     144             : 
     145             : int
     146             : fd_cstr_printf_check( char *       buf,
     147             :                       ulong        sz,
     148             :                       ulong *      opt_len,
     149       10793 :                       char const * fmt, ... ) {
     150       10793 :   if( FD_UNLIKELY( (!buf) | (!sz) ) ) {
     151           6 :     if( opt_len ) *opt_len = 0UL;
     152           6 :     return 0;
     153           6 :   }
     154       10787 :   va_list ap;
     155       10787 :   va_start( ap, fmt );
     156       10787 :   int   ret = vsnprintf( buf, sz, fmt, ap );
     157       10787 :   ulong len = fd_ulong_if( ret<0, 0UL, fd_ulong_min( (ulong)ret, sz-1UL ) );
     158       10787 :   buf[ len ] = '\0';
     159       10787 :   va_end( ap );
     160       10787 :   if( opt_len ) *opt_len = len;
     161       10787 :   return len==(ulong)ret;
     162       10793 : }
     163             : 
     164             : char *
     165             : fd_cstr_append_printf( char *       buf,
     166        1032 :                        char const * fmt, ... ) {
     167        1032 :   if( FD_UNLIKELY( !buf ) ) return NULL;
     168        1032 :   va_list ap;
     169        1032 :   va_start( ap, fmt );
     170        1032 :   int ret = vsprintf( buf, fmt, ap );
     171        1032 :   va_end( ap );
     172        1032 :   return buf + fd_ulong_if( ret<0, 0UL, (ulong)ret );
     173        1032 : }
     174             : 
     175             : ulong
     176             : fd_cstr_tokenize( char ** tok,
     177             :                   ulong   tok_max,
     178             :                   char *  p,
     179        1866 :                   char    delim ) {
     180        1866 :   if( FD_UNLIKELY( !p ) ) return 0UL;
     181             : 
     182        1863 :   ulong tok_cnt = 0UL;
     183        5541 :   for(;;) {
     184             : 
     185             :     /* Find token start and record it (if possible) */
     186        5658 :     while( fd_isspace( (int)p[0] ) ) p++;
     187        5541 :     if( p[0]=='\0' ) break;
     188        5385 :     if( tok_cnt<tok_max ) tok[ tok_cnt ] = p;
     189        5385 :     tok_cnt++;
     190             : 
     191             :     /* Find the token end and terminate it */
     192       27450 :     while( ((p[0]!=delim) & (p[0]!='\0')) ) p++;
     193        5385 :     if( p[0]=='\0' ) break;
     194        3678 :     p[0] = '\0';
     195        3678 :     p++;
     196        3678 :   }
     197             : 
     198        1863 :   return tok_cnt;
     199        1866 : }

Generated by: LCOV version 1.14