LCOV - code coverage report
Current view: top level - util/cstr - fd_cstr.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 109 115 94.8 %
Date: 2025-01-08 12:08:44 Functions: 20 20 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    30003294 : char const * fd_cstr_to_cstr  ( char const * cstr ) { return cstr;                             }
      12    30000015 : char         fd_cstr_to_char  ( char const * cstr ) { return cstr[0];                          }
      13    30000015 : schar        fd_cstr_to_schar ( char const * cstr ) { return (schar) strtol ( cstr, NULL, 0 ); }
      14    30000015 : short        fd_cstr_to_short ( char const * cstr ) { return (short) strtol ( cstr, NULL, 0 ); }
      15    30001626 : int          fd_cstr_to_int   ( char const * cstr ) { return (int)   strtol ( cstr, NULL, 0 ); }
      16    30000024 : long         fd_cstr_to_long  ( char const * cstr ) { return (long)  strtol ( cstr, NULL, 0 ); }
      17    30010020 : uchar        fd_cstr_to_uchar ( char const * cstr ) { return (uchar) strtoul( cstr, NULL, 0 ); }
      18    30000015 : ushort       fd_cstr_to_ushort( char const * cstr ) { return (ushort)strtoul( cstr, NULL, 0 ); }
      19    30000063 : uint         fd_cstr_to_uint  ( char const * cstr ) { return (uint)  strtoul( cstr, NULL, 0 ); }
      20    30002442 : ulong        fd_cstr_to_ulong ( char const * cstr ) { return (ulong) strtoul( cstr, NULL, 0 ); }
      21    30000018 : float        fd_cstr_to_float ( char const * cstr ) { return         strtof ( cstr, NULL    ); }
      22             : #if FD_HAS_DOUBLE
      23    30000006 : double       fd_cstr_to_double( char const * cstr ) { return         strtod ( cstr, NULL    ); }
      24             : #endif
      25             : 
      26         240 : 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         267 :                       ulong        seq_max ) {
      32         267 :   ulong seq_cnt = 0UL;
      33             : 
      34         267 :   if( !cstr ) return seq_cnt;
      35             : 
      36         258 :   char const * p = cstr;
      37         486 :   for(;;) {
      38             : 
      39         486 :     char   c;
      40         486 :     char * q;
      41             : 
      42         486 :     c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      43         486 :     if( c=='\0' ) break; /* end of sequence */
      44             : 
      45         360 :     ulong seq_ele_0 = strtoul( p, &q, 0 );
      46         360 :     if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_ele_0 is not a ulong */
      47         339 :     p = (char const *)q;
      48             : 
      49         339 :     ulong seq_ele_1  = seq_ele_0;
      50         339 :     ulong seq_stride = 1UL;
      51             : 
      52         339 :     c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      53         339 :     if( c=='-' ) {
      54         180 :       p++;
      55             : 
      56         180 :       seq_ele_1 = strtoul( p, &q, 0 );
      57         180 :       if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_ele_1 is not a ulong */
      58         153 :       p = (char const *)q;
      59             : 
      60         153 :       c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      61         153 :       if( c=='/' || c==':' ) {
      62          72 :         p++;
      63             : 
      64          72 :         seq_stride = strtoul( p, &q, 0 );
      65          72 :         if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_stride is not a ulong */
      66          51 :         p = (char const *)q;
      67          51 :       }
      68         153 :     }
      69             : 
      70         291 :     c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      71         291 :     if( !(c==',' || c=='\0' ) ) return 0UL; /* Malformed sequence, delimiter */
      72         258 :     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         258 :     if( FD_UNLIKELY( (seq_ele_1<seq_ele_0) | (!seq_stride) )) return 0UL; /* Malformed sequence, bad range */
      79             : 
      80             : 
      81         228 :     ulong seq_ele = seq_ele_0;
      82        6849 :     while( ((seq_ele_0<=seq_ele) & (seq_ele<seq_ele_1)) ) {
      83        6621 :       if( FD_LIKELY( seq_cnt<seq_max ) ) seq[ seq_cnt ] = seq_ele;
      84        6621 :       seq_cnt++;
      85        6621 :       seq_ele += seq_stride;
      86        6621 :     }
      87         228 :     if( seq_ele==seq_ele_1 ) {
      88         192 :       if( FD_LIKELY( seq_cnt<seq_max ) ) seq[ seq_cnt ] = seq_ele;
      89         192 :       seq_cnt++;
      90         192 :     }
      91         228 :   }
      92             : 
      93         126 :   return seq_cnt;
      94         258 : }
      95             : 
      96             : int
      97             : fd_cstr_casecmp( char const * a,
      98       15351 :                  char const * b ) {
      99       15351 :   return strcasecmp( a, b );
     100       15351 : }
     101             : 
     102             : ulong
     103             : fd_cstr_nlen( char const * s,
     104        1326 :               ulong        m ) {
     105        1326 :   return strnlen( s, m );
     106        1326 : }
     107             : 
     108             : char *
     109             : fd_cstr_printf( char *       buf,
     110             :                 ulong        sz,
     111             :                 ulong *      opt_len,
     112   300183201 :                 char const * fmt, ... ) {
     113   300183201 :   if( FD_UNLIKELY( (!buf) | (!sz) ) ) {
     114           0 :     if( opt_len ) *opt_len = 0UL;
     115           0 :     return buf;
     116           0 :   }
     117   300183201 :   va_list ap;
     118   300183201 :   va_start( ap, fmt );
     119   300183201 :   int   ret = vsnprintf( buf, sz, fmt, ap );
     120   300183201 :   ulong len = fd_ulong_if( ret<0, 0UL, fd_ulong_min( (ulong)ret, sz-1UL ) );
     121   300183201 :   buf[ len ] = '\0';
     122   300183201 :   va_end( ap );
     123   300183201 :   if( opt_len ) *opt_len = len;
     124   300183201 :   return buf;
     125   300183201 : }
     126             : 
     127             : int
     128             : fd_cstr_printf_check( char *       buf,
     129             :                       ulong        sz,
     130             :                       ulong *      opt_len,
     131         255 :                       char const * fmt, ... ) {
     132         255 :   if( FD_UNLIKELY( (!buf) | (!sz) ) ) {
     133           0 :     if( opt_len ) *opt_len = 0UL;
     134           0 :     return 0;
     135           0 :   }
     136         255 :   va_list ap;
     137         255 :   va_start( ap, fmt );
     138         255 :   int   ret = vsnprintf( buf, sz, fmt, ap );
     139         255 :   ulong len = fd_ulong_if( ret<0, 0UL, fd_ulong_min( (ulong)ret, sz-1UL ) );
     140         255 :   buf[ len ] = '\0';
     141         255 :   va_end( ap );
     142         255 :   if( opt_len ) *opt_len = len;
     143         255 :   return len==(ulong)ret;
     144         255 : }
     145             : 
     146             : char *
     147             : fd_cstr_append_printf( char *       buf,
     148         516 :                        char const * fmt, ... ) {
     149         516 :   if( FD_UNLIKELY( !buf ) ) return NULL;
     150         516 :   va_list ap;
     151         516 :   va_start( ap, fmt );
     152         516 :   int ret = vsprintf( buf, fmt, ap );
     153         516 :   va_end( ap );
     154         516 :   return buf + fd_ulong_if( ret<0, 0UL, (ulong)ret );
     155         516 : }
     156             : 
     157             : ulong
     158             : fd_cstr_tokenize( char ** tok,
     159             :                   ulong   tok_max,
     160             :                   char *  p,
     161         246 :                   char    delim ) {
     162         246 :   if( FD_UNLIKELY( !p ) ) return 0UL;
     163             : 
     164         243 :   ulong tok_cnt = 0UL;
     165         636 :   for(;;) {
     166             : 
     167             :     /* Find token start and record it (if possible) */
     168         636 :     while( isspace( (int)p[0] ) ) p++;
     169         636 :     if( p[0]=='\0' ) break;
     170         597 :     if( tok_cnt<tok_max ) tok[ tok_cnt ] = p;
     171         597 :     tok_cnt++;
     172             : 
     173             :     /* Find the token end and terminate it */
     174        3108 :     while( ((p[0]!=delim) & (p[0]!='\0')) ) p++;
     175         597 :     if( p[0]=='\0' ) break;
     176         393 :     p[0] = '\0';
     177         393 :     p++;
     178         393 :   }
     179             : 
     180         243 :   return tok_cnt;
     181         246 : }
     182             : 

Generated by: LCOV version 1.14