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: 2024-11-13 11:58:15 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    30001695 : 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    30001395 : int          fd_cstr_to_int   ( char const * cstr ) { return (int)   strtol ( cstr, NULL, 0 ); }
      16    30000018 : long         fd_cstr_to_long  ( char const * cstr ) { return (long)  strtol ( cstr, NULL, 0 ); }
      17    30004611 : 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    30000027 : uint         fd_cstr_to_uint  ( char const * cstr ) { return (uint)  strtoul( cstr, NULL, 0 ); }
      20    30001713 : 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          30 : 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         132 :                       ulong        seq_max ) {
      32         132 :   ulong seq_cnt = 0UL;
      33             : 
      34         132 :   if( !cstr ) return seq_cnt;
      35             : 
      36         123 :   char const * p = cstr;
      37         300 :   for(;;) {
      38             : 
      39         300 :     char   c;
      40         300 :     char * q;
      41             : 
      42         300 :     c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      43         300 :     if( c=='\0' ) break; /* end of sequence */
      44             : 
      45         231 :     ulong seq_ele_0 = strtoul( p, &q, 0 );
      46         231 :     if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_ele_0 is not a ulong */
      47         222 :     p = (char const *)q;
      48             : 
      49         222 :     ulong seq_ele_1  = seq_ele_0;
      50         222 :     ulong seq_stride = 1UL;
      51             : 
      52         222 :     c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      53         222 :     if( c=='-' ) {
      54         126 :       p++;
      55             : 
      56         126 :       seq_ele_1 = strtoul( p, &q, 0 );
      57         126 :       if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_ele_1 is not a ulong */
      58         117 :       p = (char const *)q;
      59             : 
      60         117 :       c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      61         117 :       if( c=='/' || c==':' ) {
      62          54 :         p++;
      63             : 
      64          54 :         seq_stride = strtoul( p, &q, 0 );
      65          54 :         if( FD_UNLIKELY( p==(char const *)q ) ) return 0UL; /* Malformed sequence, seq_stride is not a ulong */
      66          45 :         p = (char const *)q;
      67          45 :       }
      68         117 :     }
      69             : 
      70         204 :     c = *p; while( isspace( (int)c ) ) c = *(++p); /* Move and peek at next non-white-space character */
      71         204 :     if( !(c==',' || c=='\0' ) ) return 0UL; /* Malformed sequence, delimiter */
      72         195 :     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         195 :     if( FD_UNLIKELY( (seq_ele_1<seq_ele_0) | (!seq_stride) )) return 0UL; /* Malformed sequence, bad range */
      79             : 
      80             : 
      81         177 :     ulong seq_ele = seq_ele_0;
      82         654 :     while( ((seq_ele_0<=seq_ele) & (seq_ele<seq_ele_1)) ) {
      83         477 :       if( FD_LIKELY( seq_cnt<seq_max ) ) seq[ seq_cnt ] = seq_ele;
      84         477 :       seq_cnt++;
      85         477 :       seq_ele += seq_stride;
      86         477 :     }
      87         177 :     if( seq_ele==seq_ele_1 ) {
      88         141 :       if( FD_LIKELY( seq_cnt<seq_max ) ) seq[ seq_cnt ] = seq_ele;
      89         141 :       seq_cnt++;
      90         141 :     }
      91         177 :   }
      92             : 
      93          69 :   return seq_cnt;
      94         123 : }
      95             : 
      96             : int
      97             : fd_cstr_casecmp( char const * a,
      98       14823 :                  char const * b ) {
      99       14823 :   return strcasecmp( a, b );
     100       14823 : }
     101             : 
     102             : ulong
     103             : fd_cstr_nlen( char const * s,
     104         129 :               ulong        m ) {
     105         129 :   return strnlen( s, m );
     106         129 : }
     107             : 
     108             : char *
     109             : fd_cstr_printf( char *       buf,
     110             :                 ulong        sz,
     111             :                 ulong *      opt_len,
     112   300165465 :                 char const * fmt, ... ) {
     113   300165465 :   if( FD_UNLIKELY( (!buf) | (!sz) ) ) {
     114           0 :     if( opt_len ) *opt_len = 0UL;
     115           0 :     return buf;
     116           0 :   }
     117   300165465 :   va_list ap;
     118   300165465 :   va_start( ap, fmt );
     119   300165465 :   int   ret = vsnprintf( buf, sz, fmt, ap );
     120   300165465 :   ulong len = fd_ulong_if( ret<0, 0UL, fd_ulong_min( (ulong)ret, sz-1UL ) );
     121   300165465 :   buf[ len ] = '\0';
     122   300165465 :   va_end( ap );
     123   300165465 :   if( opt_len ) *opt_len = len;
     124   300165465 :   return buf;
     125   300165465 : }
     126             : 
     127             : int
     128             : fd_cstr_printf_check( char *       buf,
     129             :                       ulong        sz,
     130             :                       ulong *      opt_len,
     131          63 :                       char const * fmt, ... ) {
     132          63 :   if( FD_UNLIKELY( (!buf) | (!sz) ) ) {
     133           0 :     if( opt_len ) *opt_len = 0UL;
     134           0 :     return 0;
     135           0 :   }
     136          63 :   va_list ap;
     137          63 :   va_start( ap, fmt );
     138          63 :   int   ret = vsnprintf( buf, sz, fmt, ap );
     139          63 :   ulong len = fd_ulong_if( ret<0, 0UL, fd_ulong_min( (ulong)ret, sz-1UL ) );
     140          63 :   buf[ len ] = '\0';
     141          63 :   va_end( ap );
     142          63 :   if( opt_len ) *opt_len = len;
     143          63 :   return len==(ulong)ret;
     144          63 : }
     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         243 :                   char    delim ) {
     162         243 :   if( FD_UNLIKELY( !p ) ) return 0UL;
     163             : 
     164         240 :   ulong tok_cnt = 0UL;
     165         624 :   for(;;) {
     166             : 
     167             :     /* Find token start and record it (if possible) */
     168         624 :     while( isspace( (int)p[0] ) ) p++;
     169         624 :     if( p[0]=='\0' ) break;
     170         585 :     if( tok_cnt<tok_max ) tok[ tok_cnt ] = p;
     171         585 :     tok_cnt++;
     172             : 
     173             :     /* Find the token end and terminate it */
     174        3078 :     while( ((p[0]!=delim) & (p[0]!='\0')) ) p++;
     175         585 :     if( p[0]=='\0' ) break;
     176         384 :     p[0] = '\0';
     177         384 :     p++;
     178         384 :   }
     179             : 
     180         240 :   return tok_cnt;
     181         243 : }
     182             : 

Generated by: LCOV version 1.14