LCOV - code coverage report
Current view: top level - util/pod - fd_pod_ctl.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 383 532 72.0 %
Date: 2024-11-13 11:58:15 Functions: 6 6 100.0 %

          Line data    Source code
       1             : #include "../fd_util.h"
       2             : 
       3             : #if FD_HAS_HOSTED
       4             : 
       5             : #include <stdio.h>
       6             : #include <stdlib.h>
       7             : #include <ctype.h>
       8             : #include <sys/types.h>
       9             : #include <sys/stat.h>
      10             : #include <fcntl.h>
      11             : #include <unistd.h>
      12             : 
      13             : FD_IMPORT_CSTR( fd_pod_ctl_help, "src/util/pod/fd_pod_ctl_help" );
      14             : 
      15             : static int
      16         108 : supported_val_type( int val_type ) {
      17         108 :   return (val_type==FD_POD_VAL_TYPE_CSTR  ) | (val_type==FD_POD_VAL_TYPE_CHAR  )
      18         108 :        | (val_type==FD_POD_VAL_TYPE_SCHAR ) | (val_type==FD_POD_VAL_TYPE_SHORT )
      19         108 :        | (val_type==FD_POD_VAL_TYPE_INT   ) | (val_type==FD_POD_VAL_TYPE_LONG  )
      20         108 :        | (val_type==FD_POD_VAL_TYPE_UCHAR ) | (val_type==FD_POD_VAL_TYPE_USHORT)
      21         108 :        | (val_type==FD_POD_VAL_TYPE_UINT  ) | (val_type==FD_POD_VAL_TYPE_ULONG )
      22         108 :        | (val_type==FD_POD_VAL_TYPE_FLOAT )
      23         108 : #      if FD_HAS_DOUBLE
      24         108 :        | (val_type==FD_POD_VAL_TYPE_DOUBLE)
      25         108 : #      endif
      26         108 :   ;
      27         108 : }
      28             : 
      29             : static ulong
      30             : insert_val( uchar *      pod,
      31             :             char const * path,
      32             :             int          val_type,
      33         108 :             char const * val ) {
      34         108 :   ulong off;
      35         108 :   switch( val_type ) {
      36          15 :   case FD_POD_VAL_TYPE_CSTR:   off = fd_pod_insert_cstr  ( pod, path, fd_cstr_to_cstr  ( val ) ); break;
      37           9 :   case FD_POD_VAL_TYPE_CHAR:   off = fd_pod_insert_char  ( pod, path, fd_cstr_to_char  ( val ) ); break;
      38           9 :   case FD_POD_VAL_TYPE_SCHAR:  off = fd_pod_insert_schar ( pod, path, fd_cstr_to_schar ( val ) ); break;
      39           9 :   case FD_POD_VAL_TYPE_SHORT:  off = fd_pod_insert_short ( pod, path, fd_cstr_to_short ( val ) ); break;
      40           9 :   case FD_POD_VAL_TYPE_INT:    off = fd_pod_insert_int   ( pod, path, fd_cstr_to_int   ( val ) ); break;
      41           9 :   case FD_POD_VAL_TYPE_LONG:   off = fd_pod_insert_long  ( pod, path, fd_cstr_to_long  ( val ) ); break;
      42           9 :   case FD_POD_VAL_TYPE_UCHAR:  off = fd_pod_insert_uchar ( pod, path, fd_cstr_to_uchar ( val ) ); break;
      43           9 :   case FD_POD_VAL_TYPE_USHORT: off = fd_pod_insert_ushort( pod, path, fd_cstr_to_ushort( val ) ); break;
      44           9 :   case FD_POD_VAL_TYPE_UINT:   off = fd_pod_insert_uint  ( pod, path, fd_cstr_to_uint  ( val ) ); break;
      45           9 :   case FD_POD_VAL_TYPE_ULONG:  off = fd_pod_insert_ulong ( pod, path, fd_cstr_to_ulong ( val ) ); break;
      46          12 :   case FD_POD_VAL_TYPE_FLOAT:  off = fd_pod_insert_float ( pod, path, fd_cstr_to_float ( val ) ); break;
      47           0 : # if FD_HAS_DOUBLE
      48           0 :   case FD_POD_VAL_TYPE_DOUBLE: off = fd_pod_insert_double( pod, path, fd_cstr_to_double( val ) ); break;
      49           0 : # endif
      50           0 :   default: FD_LOG_ERR(( "never get here" ));
      51         108 :   }
      52         108 :   return off;
      53         108 : }
      54             : 
      55             : static inline int
      56         135 : issingleprint( int c ) {
      57         135 :   return isalnum( c ) | ispunct( c ) | (c==' ');
      58         135 : }
      59             : 
      60             : static void
      61          81 : printf_path( fd_pod_info_t const * info ) {
      62          81 :   if( FD_UNLIKELY( !info ) ) return;
      63             : 
      64          81 :   fd_pod_info_t const * node = info;
      65          81 :   ulong                 sz   = 0UL;
      66         120 :   do {
      67         120 :     ulong key_sz = node->key_sz;
      68         120 :     if( FD_UNLIKELY( !key_sz ) ) return;
      69         120 :     sz   += key_sz;
      70         120 :     node  = node->parent;
      71         120 :   } while( node );
      72             : 
      73          81 :   char * buf = malloc( sz );
      74          81 :   if( !buf ) return;
      75             : 
      76          81 :   char * p      = buf + sz;
      77          81 :   int    subpod = 0;
      78          81 :   node = info;
      79         120 :   do {
      80         120 :     ulong key_sz = node->key_sz;
      81         120 :     p -= key_sz;
      82         120 :     strcpy( p, node->key );
      83         120 :     if( subpod ) p[ key_sz-1UL ] = '.';
      84         120 :     subpod = 1;
      85         120 :     node = node->parent;
      86         120 :   } while( node );
      87             : 
      88          81 :   printf( "%s", buf );
      89          81 :   free( buf );
      90          81 : }
      91             : 
      92             : static void
      93          96 : printf_val( fd_pod_info_t const * info ) {
      94          96 :   switch( info->val_type ) {
      95             : 
      96          39 :   case FD_POD_VAL_TYPE_SUBPOD: {
      97          39 :     uchar * subpod = (uchar *)info->val;
      98          39 :     printf( "max %lu bytes, used %lu bytes, kcnt %lu keys", fd_pod_max( subpod ), fd_pod_used( subpod ), fd_pod_cnt( subpod ) );
      99          39 :     break;
     100           0 :   }
     101             : 
     102           0 :   default:
     103           6 :   case FD_POD_VAL_TYPE_BUF: {
     104           6 :     uchar const * buf = (uchar const *)info->val;
     105           6 :     ulong         sz  = info->val_sz;
     106           6 :     printf( "sz %lu", sz );
     107         138 :     for( ulong off=0UL; off<sz; off++ ) {
     108         132 :       ulong col = off & 15UL;
     109             :       /* FIXME: USER SPECIFIED INDENT AND CONFIGURE OFF WIDTH BASED ON SZ */
     110         132 :       if( FD_UNLIKELY( col==0UL ) ) printf( "\n\t\t%04lx: ", off );
     111         132 :       if( FD_UNLIKELY( col==8UL ) ) putc( ' ', stdout );
     112         132 :       printf( "%02x ", (uint)buf[ off ] );
     113         132 :       if( FD_UNLIKELY( (col==15UL) | ((off+1UL)==sz) ) ) { /* End of row */
     114             :         /* Output whitespace to align 2nd column */
     115          72 :         for( ulong rem=48UL-3UL*col; rem; rem-- ) putc( ' ', stdout );
     116             :         /* Output single character friendly bytes from row in 2nd column */
     117           9 :         char const * p = (char const *)(buf + (off & ~15UL));
     118         141 :         for( ulong rem=col+1UL; rem; rem-- ) { int c = (int)*(p++); putc( issingleprint( c ) ? c : '.', stdout ); }
     119           9 :       }
     120         132 :     }
     121           6 :     break;
     122           0 :   }
     123             : 
     124          15 :   case FD_POD_VAL_TYPE_CSTR: {
     125          15 :     if( !info->val_sz ) printf( "(null)" );
     126          15 :     else                printf( "\"%s\"", (char const *)info->val );
     127          15 :     break;
     128           0 :   }
     129             : 
     130           3 :   case FD_POD_VAL_TYPE_CHAR: {
     131           3 :     int c = (int)*(char *)info->val;
     132           3 :     if( issingleprint( c ) ) printf( "'%c'", c );
     133           0 :     else                     printf( "0x%02x", (uint)(uchar)c );
     134           3 :     break;
     135           0 :   }
     136             : 
     137           3 :   case FD_POD_VAL_TYPE_UCHAR:  { uint  u = (uint)*(uchar *)info->val; printf( "%u", u ); break; }
     138           3 :   case FD_POD_VAL_TYPE_USHORT:
     139           6 :   case FD_POD_VAL_TYPE_UINT:
     140           9 :   case FD_POD_VAL_TYPE_ULONG:  { ulong u; fd_ulong_svw_dec( info->val, &u ); printf( "%lu", u ); break; }
     141             : 
     142           6 :   case FD_POD_VAL_TYPE_SCHAR:  { int   i = (int) *(schar *)info->val; printf( "%i", i ); break; }
     143           3 :   case FD_POD_VAL_TYPE_SHORT:
     144           6 :   case FD_POD_VAL_TYPE_INT: 
     145           9 :   case FD_POD_VAL_TYPE_LONG:   { ulong u; fd_ulong_svw_dec( info->val, &u ); printf( "%li", fd_long_zz_dec( u ) ); break; }
     146             : 
     147           0 : # if FD_HAS_INT128
     148           0 :   case FD_POD_VAL_TYPE_INT128: {
     149           0 :     union { ulong w[2]; uint128 u; } tmp;
     150           0 :     fd_ulong_svw_dec( fd_ulong_svw_dec( (uchar const *)info->val, tmp.w ), tmp.w+1 );
     151           0 :     tmp.u = (uint128)fd_int128_zz_dec( tmp.u ); /* FIXME: INT128 decimal pretty printer */
     152           0 :     printf( "0x%016lx%016lx", (ulong)(tmp.u>>64), (ulong)tmp.u );
     153           0 :     break;
     154           6 :   }
     155             : 
     156           0 :   case FD_POD_VAL_TYPE_UINT128: {
     157           0 :     union { ulong w[2]; uint128 u; } tmp;
     158           0 :     fd_ulong_svw_dec( fd_ulong_svw_dec( (uchar const *)info->val, tmp.w ), tmp.w+1 );
     159             :     /* FIXME: UINT128 decimal pretty printer */
     160           0 :     printf( "0x%016lx%016lx", (ulong)(tmp.u>>64), (ulong)tmp.u );
     161           0 :     break;
     162           6 :   }
     163           0 : # endif
     164             : 
     165           6 :   case FD_POD_VAL_TYPE_FLOAT:  { float  f = *(float  *)info->val; printf( "%.21e", (double)f ); break; }
     166           0 : # if FD_HAS_DOUBLE
     167           0 :   case FD_POD_VAL_TYPE_DOUBLE: { double f = *(double *)info->val; printf( "%.21e", f );         break; }
     168          96 : # endif
     169             : 
     170          96 :   }
     171          96 : }
     172             : 
     173             : int
     174             : main( int     argc,
     175          48 :       char ** argv ) {
     176          48 :   fd_boot( &argc, &argv );
     177             : 
     178         705 : # define SHIFT(n) argv+=(n),argc-=(n)
     179             : 
     180          48 :   if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "no arguments" ));
     181          48 :   char const * bin = argv[0];
     182          48 :   SHIFT(1); 
     183             : 
     184          48 :   ulong tag = 1UL;
     185             : 
     186          48 :   int cnt = 0;
     187         378 :   while( argc ) {
     188         330 :     char const * cmd = argv[0];
     189         330 :     SHIFT(1);
     190             : 
     191         330 :     if( !strcmp( cmd, "help" ) ) {
     192             : 
     193           3 :       fputs( fd_pod_ctl_help, stdout );
     194             : 
     195           3 :       FD_LOG_NOTICE(( "%i: %s: success", cnt, cmd ));
     196             : 
     197         327 :     } else if( !strcmp( cmd, "tag" ) ) {
     198             : 
     199           3 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     200             : 
     201           3 :       tag = fd_cstr_to_ulong( argv[0] );
     202             : 
     203           3 :       FD_LOG_NOTICE(( "%i: %s %lu: success", cnt, cmd, tag ));
     204           3 :       SHIFT(1);
     205             : 
     206         324 :     } else if( !strcmp( cmd, "new" ) ) {
     207             : 
     208           3 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     209             : 
     210           3 :       char const * name =                   argv[0];
     211           3 :       ulong        max  = fd_cstr_to_ulong( argv[1] ); if( !max ) max = 4096UL;
     212             : 
     213           3 :       ulong align     = fd_pod_align();
     214           3 :       ulong footprint = fd_pod_footprint( max );
     215             : 
     216           3 :       if( FD_UNLIKELY( !footprint ) )
     217           0 :         FD_LOG_ERR(( "%i: %s: bad max (%lu)\n\tDo %s help for help", cnt, cmd, max, bin ));
     218             : 
     219           3 :       fd_wksp_t * wksp = fd_wksp_attach( name );
     220           3 :       if( FD_UNLIKELY( !wksp ) )
     221           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_attach( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, name, bin ));
     222             : 
     223           3 :       ulong gaddr = fd_wksp_alloc( wksp, align, footprint, tag );
     224           3 :       if( FD_UNLIKELY( !gaddr ) ) {
     225           0 :         fd_wksp_detach( wksp );
     226           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_alloc( \"%s\", %lu, %lu, %lu ) failed\n\tDo %s help for help",
     227           0 :                      cnt, cmd, name, align, footprint, tag, bin ));
     228           0 :       }
     229             : 
     230           3 :       void * shmem = fd_wksp_laddr( wksp, gaddr );
     231           3 :       if( FD_UNLIKELY( !shmem ) ) { /* should be impossible given fd_wksp_alloc success */
     232           0 :         fd_wksp_free( wksp, gaddr );
     233           0 :         fd_wksp_detach( wksp );
     234           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_laddr( \"%s\", %lu ) failed\n\tDo %s help for help", cnt, cmd, name, gaddr, bin ));
     235           0 :       }
     236             : 
     237           3 :       if( FD_UNLIKELY( !fd_pod_new( shmem, max ) ) ) {;
     238           0 :         fd_wksp_free( wksp, gaddr );
     239           0 :         fd_wksp_detach( wksp );
     240           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_new( \"%s:%lu\", %lu ) failed\n\tDo %s help for help", cnt, cmd, name, gaddr, max, bin ));
     241           0 :       }
     242             : 
     243           3 :       char cstr[ FD_WKSP_CSTR_MAX ];
     244           3 :       if( FD_UNLIKELY( !fd_wksp_cstr( wksp, gaddr, cstr ) ) ) {
     245           0 :         fd_wksp_free( wksp, gaddr );
     246           0 :         fd_wksp_detach( wksp );
     247           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_cstr( \"%s:%lu\" ) failed\n\tDo %s help for help", cnt, cmd, name, gaddr, bin ));
     248           0 :       }
     249             : 
     250           3 :       printf( "%s\n", cstr );
     251             : 
     252           3 :       fd_wksp_detach( wksp );
     253             : 
     254           3 :       FD_LOG_NOTICE(( "%i: %s %s %lu: success", cnt, cmd, name, max ));
     255           3 :       SHIFT(2);
     256             : 
     257         321 :     } else if( !strcmp( cmd, "delete" ) ) {
     258             : 
     259           6 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     260             : 
     261           6 :       char const * cstr = argv[0];
     262             : 
     263           6 :       void * shmem = fd_wksp_map( cstr );
     264           6 :       if( FD_UNLIKELY( !shmem ) )
     265           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     266             : 
     267           6 :       if( FD_UNLIKELY( !fd_pod_delete( shmem ) ) ) {
     268           0 :         fd_wksp_unmap( shmem );
     269           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_delete( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     270           0 :       }
     271             : 
     272           6 :       fd_wksp_free_laddr( shmem );
     273           6 :       fd_wksp_unmap( shmem );
     274             : 
     275           6 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
     276           6 :       SHIFT(1);
     277             : 
     278         315 :     } else if( !strcmp( cmd, "reset" ) ) {
     279             : 
     280           3 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     281             : 
     282           3 :       char const * cstr = argv[0];
     283             : 
     284           3 :       void * shmem = fd_wksp_map( cstr );
     285           3 :       if( FD_UNLIKELY( !shmem ) )
     286           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     287             : 
     288           3 :       uchar * pod = fd_pod_join( shmem );
     289           3 :       if( FD_UNLIKELY( !pod ) ) {
     290           0 :         fd_wksp_unmap( shmem );
     291           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     292           0 :       }
     293             : 
     294           3 :       fd_pod_reset( pod );
     295             : 
     296           3 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     297             : 
     298           3 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
     299           3 :       SHIFT(1);
     300             : 
     301         312 :     } else if( !strcmp( cmd, "list" ) ) {
     302             : 
     303           3 :       if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     304             : 
     305           3 :       char const * cstr = argv[0];
     306             : 
     307           3 :       void * shmem = fd_wksp_map( cstr );
     308           3 :       if( FD_UNLIKELY( !shmem ) )
     309           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     310             : 
     311           3 :       uchar * pod = fd_pod_join( shmem );
     312           3 :       if( FD_UNLIKELY( !pod ) ) {
     313           0 :         fd_wksp_unmap( shmem );
     314           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     315           0 :       }
     316             : 
     317           3 :       fd_pod_info_t * info;
     318           3 :       ulong info_cnt = fd_pod_cnt_recursive( pod );
     319           3 :       if( FD_UNLIKELY( !info_cnt ) ) info = NULL;
     320           3 :       else { 
     321           3 :         info = (fd_pod_info_t *)aligned_alloc( alignof(fd_pod_info_t), info_cnt*sizeof(fd_pod_info_t) );
     322           3 :         if( FD_UNLIKELY( !info ) ) {
     323           0 :           fd_wksp_unmap( fd_pod_leave( pod ) );
     324           0 :           FD_LOG_ERR(( "%i: %s: aligned_alloc failed\n\tDo %s help for help", cnt, cmd, bin ));
     325           0 :         }
     326           3 :         if( FD_UNLIKELY( !fd_pod_list_recursive( pod, info ) ) ) {
     327           0 :           free( info );
     328           0 :           fd_wksp_unmap( fd_pod_leave( pod ) );
     329           0 :           FD_LOG_ERR(( "%i: %s: fd_pod_list_recursive( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     330           0 :         }
     331           3 :       }
     332             : 
     333           3 :       printf( "pod %s\n", cstr );
     334           3 :       printf( "\tmax   %20lu bytes  used  %20lu bytes  avail %20lu bytes\n",
     335           3 :               fd_pod_max( pod ), fd_pod_used ( pod ), fd_pod_avail( pod ) );
     336           3 :       printf( "\tkcnt  %20lu keys   icnt  %20lu paths\n", fd_pod_cnt( pod ), info_cnt );
     337          84 :       for( ulong info_idx=0UL; info_idx<info_cnt; info_idx++ ) {
     338          81 :         fd_pod_info_t * node = &info[ info_idx ];
     339          81 :         char type[ FD_POD_VAL_TYPE_CSTR_MAX ]; fd_pod_val_type_to_cstr( node->val_type, type );
     340          81 :         printf( "\t%s %s ", cstr, type );
     341          81 :         printf_path( node );
     342          81 :         printf( " " );
     343          81 :         printf_val(  node );
     344          81 :         printf( "\n" );
     345          81 :       }
     346             : 
     347           3 :       if( FD_LIKELY( info ) ) free( info );
     348           3 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     349             : 
     350           3 :       FD_LOG_NOTICE(( "%i: %s %s: success", cnt, cmd, cstr ));
     351           3 :       SHIFT(1);
     352             : 
     353         309 :     } else if( !strcmp( cmd, "insert" ) ) {
     354             : 
     355          36 :       if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     356             : 
     357          36 :       char const * cstr = argv[0];
     358          36 :       char const * type = argv[1];
     359          36 :       char const * path = argv[2];
     360          36 :       char const * val  = argv[3];
     361             : 
     362          36 :       int val_type = fd_cstr_to_pod_val_type( type );
     363          36 :       if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
     364           0 :         FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
     365             : 
     366          36 :       void * shmem = fd_wksp_map( cstr );
     367          36 :       if( FD_UNLIKELY( !shmem ) )
     368           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     369             : 
     370          36 :       uchar * pod = fd_pod_join( shmem );
     371          36 :       if( FD_UNLIKELY( !pod ) ) {
     372           0 :         fd_wksp_unmap( shmem );
     373           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     374           0 :       }
     375             : 
     376          36 :       ulong off = insert_val( pod, path, val_type, val );
     377             : 
     378          36 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     379             : 
     380          36 :       if( FD_UNLIKELY( !off ) )
     381           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_insert_%s( \"%s\", \"%s\", \"%s\" ) failed\n\tDo %s help for help",
     382          36 :                      cnt, cmd, type, cstr, path, val, bin ));
     383             : 
     384          36 :       FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
     385          36 :       SHIFT(4);
     386             : 
     387         273 :     } else if( !strcmp( cmd, "insert-file" ) ) {
     388             : 
     389           6 :       if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     390             : 
     391           6 :       char const * cstr = argv[0];
     392           6 :       char const * path = argv[1];
     393           6 :       char const * file = argv[2];
     394             : 
     395           6 :       void * shmem = fd_wksp_map( cstr );
     396           6 :       if( FD_UNLIKELY( !shmem ) )
     397           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     398             : 
     399           6 :       uchar * pod = fd_pod_join( shmem );
     400           6 :       if( FD_UNLIKELY( !pod ) ) {
     401           0 :         fd_wksp_unmap( shmem );
     402           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     403           0 :       }
     404             : 
     405           6 :       int fd = open( file, O_RDONLY );
     406           6 :       if( FD_UNLIKELY( fd == -1 ) )
     407           0 :         FD_LOG_ERR(( "%i: %s: open( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, file, bin ));
     408             : 
     409           6 :       struct stat st;
     410           6 :       if( FD_UNLIKELY( fstat( fd, &st ) == -1 ) )
     411           0 :         FD_LOG_ERR(( "%i: %s: fstat( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, file, bin ));
     412           6 :       ulong buf_sz = (ulong)st.st_size;
     413             : 
     414           6 :       ulong off = fd_pod_alloc( pod, path, FD_POD_VAL_TYPE_BUF, buf_sz );
     415           6 :       if( FD_UNLIKELY( !off ) )
     416           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_alloc( \"%s\", \"%s\", FD_POD_VAL_TYPE_BUF, %lu ) failed\n\tDo %s help for help",
     417           6 :                      cnt, cmd, cstr, path, buf_sz, bin ));
     418             : 
     419           6 :       if( FD_UNLIKELY( read( fd, pod + off, buf_sz )!=(long)buf_sz ) ) {
     420           0 :         if( FD_UNLIKELY( fd_pod_remove( pod, path ) ) )
     421           0 :           FD_LOG_WARNING(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed; pod likely corrupt", cnt, cmd, cstr, path ));
     422           0 :         FD_LOG_ERR(( "%i: %s: read( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, file, bin ));
     423           0 :       }
     424             : 
     425           6 :       if( FD_UNLIKELY( close( fd ) ) )
     426           0 :         FD_LOG_WARNING(( "%i: %s: close( \"%s\" ) failed; attempting to continue", cnt, cmd, file ));
     427             : 
     428           6 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     429             : 
     430           6 :       FD_LOG_NOTICE(( "%i: %s %s %s %s: success", cnt, cmd, cstr, path, file ));
     431           6 :       SHIFT(3);
     432             : 
     433         267 :     } else if( !strcmp( cmd, "remove" ) ) {
     434             : 
     435          39 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     436             : 
     437          39 :       char const * cstr = argv[0];
     438          39 :       char const * path = argv[1];
     439             : 
     440          39 :       void * shmem = fd_wksp_map( cstr );
     441          39 :       if( FD_UNLIKELY( !shmem ) )
     442           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     443             : 
     444          39 :       uchar * pod = fd_pod_join( shmem );
     445          39 :       if( FD_UNLIKELY( !pod ) ) {
     446           0 :         fd_wksp_unmap( shmem );
     447           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     448           0 :       }
     449             : 
     450          39 :       int err = fd_pod_remove( pod, path );
     451             : 
     452          39 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     453             : 
     454          39 :       if( FD_UNLIKELY( err ) )
     455           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
     456          39 :                      cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
     457             : 
     458          39 :       FD_LOG_NOTICE(( "%i: %s %s %s: success", cnt, cmd, cstr, path ));
     459          39 :       SHIFT(2);
     460             : 
     461         228 :     } else if( !strcmp( cmd, "update" ) ) {
     462             : 
     463          33 :       if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     464             : 
     465          33 :       char const * cstr = argv[0];
     466          33 :       char const * type = argv[1];
     467          33 :       char const * path = argv[2];
     468          33 :       char const * val  = argv[3];
     469             : 
     470          33 :       int val_type = fd_cstr_to_pod_val_type( type );
     471          33 :       if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
     472           0 :         FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
     473             : 
     474          33 :       void * shmem = fd_wksp_map( cstr );
     475          33 :       if( FD_UNLIKELY( !shmem ) )
     476           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     477             : 
     478          33 :       uchar * pod = fd_pod_join( shmem );
     479          33 :       if( FD_UNLIKELY( !pod ) ) {
     480           0 :         fd_wksp_unmap( shmem );
     481           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     482           0 :       }
     483             : 
     484          33 :       fd_pod_info_t info[1];
     485          33 :       int err = fd_pod_query( pod, path, info );
     486          33 :       if( FD_UNLIKELY( !!err ) ) {
     487           0 :         fd_wksp_unmap( fd_pod_leave( pod ) );
     488           0 :         FD_LOG_ERR(( "%i: %s: no path %s to type (%i-%s) in pod %s (%i-%s)\n\tDo %s help for help",
     489           0 :                      cnt, cmd, path, val_type, type, cstr, err, fd_pod_strerror( err ), bin ));
     490           0 :       }
     491             : 
     492          33 :       if( FD_UNLIKELY( info->val_type!=val_type ) ) {
     493           0 :         fd_wksp_unmap( fd_pod_leave( pod ) );
     494           0 :         char buf[ FD_POD_VAL_TYPE_CSTR_MAX ];
     495           0 :         FD_LOG_ERR(( "%i: %s: type (%i-%s) at %s %s does not match requested type (%i-%s)\n\tDo %s help for help",
     496           0 :                      cnt, cmd, info->val_type, fd_pod_val_type_to_cstr( info->val_type, buf ),
     497           0 :                      cstr, path, val_type, type, bin ));
     498           0 :       }
     499             : 
     500          33 :       err = fd_pod_remove( pod, path );
     501          33 :       if( FD_UNLIKELY( err ) ) {
     502           0 :         fd_wksp_unmap( fd_pod_leave( pod ) );
     503           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
     504           0 :                      cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
     505           0 :       }
     506             : 
     507          33 :       ulong off = insert_val( pod, path, val_type, val );
     508             : 
     509          33 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     510             : 
     511          33 :       if( FD_UNLIKELY( !off ) )
     512           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_insert_%s( \"%s\", \"%s\", \"%s\" ) failed\n\tDo %s help for help",
     513          33 :                      cnt, cmd, type, cstr, path, val, bin ));
     514             : 
     515          33 :       FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
     516          33 :       SHIFT(4);
     517             : 
     518         195 :     } else if( !strcmp( cmd, "set" ) ) {
     519             : 
     520          39 :       if( FD_UNLIKELY( argc<4 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     521             : 
     522          39 :       char const * cstr = argv[0];
     523          39 :       char const * type = argv[1];
     524          39 :       char const * path = argv[2];
     525          39 :       char const * val  = argv[3];
     526             : 
     527          39 :       int val_type = fd_cstr_to_pod_val_type( type );
     528          39 :       if( FD_UNLIKELY( !supported_val_type( val_type ) ) )
     529           0 :         FD_LOG_ERR(( "%i: %s: unsupported type %s\n\tDo %s help for help", cnt, cmd, type, bin ));
     530             : 
     531          39 :       void * shmem = fd_wksp_map( cstr );
     532          39 :       if( FD_UNLIKELY( !shmem ) )
     533           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     534             : 
     535          39 :       uchar * pod = fd_pod_join( shmem );
     536          39 :       if( FD_UNLIKELY( !pod ) ) {
     537           0 :         fd_wksp_unmap( shmem );
     538           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     539           0 :       }
     540             : 
     541          39 :       fd_pod_info_t info[1];
     542          39 :       int err = fd_pod_query( pod, path, info );
     543          39 :       if( FD_LIKELY( !err ) ) {
     544             : 
     545          33 :         if( FD_UNLIKELY( info->val_type!=val_type ) ) {
     546           0 :           fd_wksp_unmap( fd_pod_leave( pod ) );
     547           0 :           char buf[ FD_POD_VAL_TYPE_CSTR_MAX ];
     548           0 :           FD_LOG_ERR(( "%i: %s: type (%i-%s) at %s %s does not match requested type (%i-%s)\n\tDo %s help for help",
     549           0 :                        cnt, cmd, info->val_type, fd_pod_val_type_to_cstr( info->val_type, buf ),
     550           0 :                        cstr, path, val_type, type, bin ));
     551           0 :         }
     552             : 
     553          33 :         err = fd_pod_remove( pod, path );
     554          33 :         if( FD_UNLIKELY( err ) ) {
     555           0 :           fd_wksp_unmap( fd_pod_leave( pod ) );
     556           0 :           FD_LOG_ERR(( "%i: %s: fd_pod_remove( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
     557           0 :                        cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
     558           0 :         }
     559             : 
     560          33 :       } else if( FD_UNLIKELY( err!=FD_POD_ERR_RESOLVE ) ) {
     561             : 
     562           0 :         fd_wksp_unmap( fd_pod_leave( pod ) );
     563           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_query( \"%s\", \"%s\" ) failed (%i-%s)\n\tDo %s help for help",
     564           0 :                      cnt, cmd, cstr, path, err, fd_pod_strerror( err ), bin ));
     565             : 
     566           0 :       }
     567             : 
     568          39 :       ulong off = insert_val( pod, path, val_type, val );
     569             : 
     570          39 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     571             : 
     572          39 :       if( FD_UNLIKELY( !off ) )
     573           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_insert_%s( \"%s\", \"%s\", \"%s\" ) failed\n\tDo %s help for help",
     574          39 :                      cnt, cmd, type, cstr, path, val, bin ));
     575             : 
     576          39 :       FD_LOG_NOTICE(( "%i: %s %s %s %s %s: success", cnt, cmd, cstr, type, path, val ));
     577          39 :       SHIFT(4);
     578             : 
     579             : 
     580         156 :     } else if( !strcmp( cmd, "compact" ) ) {
     581             : 
     582           0 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     583             : 
     584           0 :       char const * cstr =                 argv[0];
     585           0 :       int          full = fd_cstr_to_int( argv[1] );
     586             : 
     587           0 :       void * shmem = fd_wksp_map( cstr );
     588           0 :       if( FD_UNLIKELY( !shmem ) )
     589           0 :         FD_LOG_ERR(( "%i: %s: fd_wksp_map( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     590             : 
     591           0 :       uchar * pod = fd_pod_join( shmem );
     592           0 :       if( FD_UNLIKELY( !pod ) ) {
     593           0 :         fd_wksp_unmap( shmem );
     594           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_join( \"%s\" ) failed\n\tDo %s help for help", cnt, cmd, cstr, bin ));
     595           0 :       }
     596             : 
     597           0 :       ulong new_max = fd_pod_compact( pod, full );
     598             : 
     599           0 :       fd_wksp_unmap( fd_pod_leave( pod ) );
     600             : 
     601           0 :       if( FD_UNLIKELY( !new_max ) )
     602           0 :         FD_LOG_ERR(( "%i: %s: fd_pod_compact( \"%s\", %i ) failed\n\tDo %s help for help", cnt, cmd, cstr, full, bin ));
     603             : 
     604           0 :       FD_LOG_NOTICE(( "%i: %s %s %i: success", cnt, cmd, cstr, full ));
     605           0 :       SHIFT(2);
     606             : 
     607         156 :     } else if( !strcmp( cmd, "query-root" ) ) {
     608             : 
     609          42 :       if( FD_UNLIKELY( argc<2 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     610             : 
     611          42 :       char const * what = argv[0];
     612          42 :       char const * cstr = argv[1];
     613             : 
     614          42 :       void *  shmem = NULL;
     615          42 :       uchar * pod   = NULL;
     616          42 :       int     err   = FD_POD_ERR_INVAL;
     617             : 
     618          42 :       shmem = fd_wksp_map( cstr );
     619          42 :       if( FD_LIKELY( shmem ) ) {
     620          21 :         pod = fd_pod_join( shmem );
     621          21 :         if( FD_LIKELY( pod ) ) err = 0;
     622          21 :       }
     623             : 
     624          42 :       if(      !strcmp( what, "test"       ) ) printf( "%i\n",  err );
     625          36 :       else if( !strcmp( what, "max"        ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_max          ( pod ) : 0UL );
     626          30 :       else if( !strcmp( what, "used"       ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_used         ( pod ) : 0UL );
     627          24 :       else if( !strcmp( what, "avail"      ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_avail        ( pod ) : 0UL );
     628          18 :       else if( !strcmp( what, "cnt"        ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt          ( pod ) : 0UL );
     629          12 :       else if( !strcmp( what, "recursive"  ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt_recursive( pod ) : 0UL );
     630           6 :       else if( !strcmp( what, "subpod-cnt" ) ) printf( "%lu\n", FD_LIKELY(!err) ? fd_pod_cnt_subpod   ( pod ) : 0UL );
     631           0 :       else                                     FD_LOG_ERR(( "unknown query %s", what ));
     632             : 
     633          42 :       if( FD_LIKELY( pod   ) ) fd_pod_leave( pod );
     634          42 :       if( FD_LIKELY( shmem ) ) fd_wksp_unmap( shmem );
     635          42 :       FD_LOG_NOTICE(( "%i: %s %s %s: success", cnt, cmd, what, cstr ));
     636          42 :       SHIFT(2);
     637             : 
     638         114 :     } else if( !strcmp( cmd, "query" ) ) {
     639             : 
     640         114 :       if( FD_UNLIKELY( argc<3 ) ) FD_LOG_ERR(( "%i: %s: too few arguments\n\tDo %s help for help", cnt, cmd, bin ));
     641             : 
     642         114 :       char const * what = argv[0];
     643         114 :       char const * cstr = argv[1];
     644         114 :       char const * path = argv[2];
     645             : 
     646         114 :       void *        shmem = NULL;
     647         114 :       uchar *       pod   = NULL;
     648         114 :       int           err   = FD_POD_ERR_INVAL;
     649         114 :       fd_pod_info_t info[1];
     650         114 :       char          type[ FD_POD_VAL_TYPE_CSTR_MAX ];
     651         114 :       int           is_subpod = 0;
     652             : 
     653         114 :       shmem = fd_wksp_map( cstr );
     654         114 :       if( FD_LIKELY( shmem ) ) {
     655         111 :         pod = fd_pod_join( shmem );
     656         111 :         if( FD_LIKELY( pod ) ) {
     657         111 :           err = fd_pod_query( pod, path, info );
     658         111 :           if( FD_LIKELY( !err ) ) {
     659          72 :             is_subpod = (info->val_type==FD_POD_VAL_TYPE_SUBPOD);
     660          72 :             if( FD_UNLIKELY( !fd_pod_val_type_to_cstr( info->val_type, type ) ) ) { /* only possible if corruption */
     661           0 :               err = FD_POD_ERR_INVAL;
     662           0 :             }
     663          72 :           }
     664         111 :         }
     665         111 :       }
     666             : 
     667         114 :       if(      !strcmp( what, "test"       ) ) printf( "%i\n",  err );
     668          99 :       else if( !strcmp( what, "type"       ) ) printf( "%s\n",  FD_LIKELY( !err )      ? type : "void" );
     669          87 :       else if( !strcmp( what, "val"        ) ) {
     670           9 :         if( FD_UNLIKELY( err ) ) printf( "void\n" );
     671           6 :         else {
     672           6 :           printf_val( info );
     673           6 :           printf( "\n" );
     674           6 :         }
     675           9 :       }
     676          78 :       else if( !strcmp( what, "max"        ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_max          ( info->val ) : 0UL );
     677          69 :       else if( !strcmp( what, "used"       ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_used         ( info->val ) : 0UL );
     678          60 :       else if( !strcmp( what, "avail"      ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_avail        ( info->val ) : 0UL );
     679          51 :       else if( !strcmp( what, "cnt"        ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt          ( info->val ) : 0UL );
     680          42 :       else if( !strcmp( what, "recursive"  ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt_recursive( info->val ) : 0UL );
     681          33 :       else if( !strcmp( what, "subpod-cnt" ) ) printf( "%lu\n", FD_LIKELY( is_subpod ) ? fd_pod_cnt_subpod   ( info->val ) : 0UL );
     682          24 :       else if( !strcmp( what, "gaddr" ) ) {
     683          12 :         char buf[ FD_WKSP_CSTR_MAX ];
     684          12 :         printf( "%s\n", (FD_LIKELY( !err ) && FD_LIKELY( fd_wksp_cstr_laddr( info->val, buf ) )) ? buf : "null" );
     685          12 :       }
     686          12 :       else if( !strcmp( what, "full"         ) ) {
     687          12 :         if( FD_UNLIKELY( err ) ) printf( "%s void %s void\n", cstr, path );
     688           9 :         else {
     689           9 :           printf( "%s %s %s ", cstr, type, path );
     690           9 :           printf_val( info );
     691           9 :           printf( "\n" );
     692           9 :         }
     693          12 :       }
     694           0 :       else                                       FD_LOG_ERR(( "unknown query %s", what ));
     695             : 
     696         114 :       if( FD_LIKELY( pod   ) ) fd_pod_leave( pod );
     697         114 :       if( FD_LIKELY( shmem ) ) fd_wksp_unmap( shmem );
     698         114 :       FD_LOG_NOTICE(( "%i: %s %s %s %s: success", cnt, cmd, what, cstr, path ));
     699         114 :       SHIFT(3);
     700             : 
     701         114 :     } else {
     702             : 
     703           0 :       FD_LOG_ERR(( "%i: %s: unknown command\n\t"
     704           0 :                    "Do %s help for help", cnt, cmd, bin ));
     705             : 
     706           0 :     }
     707         330 :     cnt++;
     708         330 :   }
     709             : 
     710          48 :   if( FD_UNLIKELY( cnt<1 ) ) FD_LOG_NOTICE(( "processed %i commands\n\tDo %s help for help", cnt, bin ));
     711          45 :   else                       FD_LOG_NOTICE(( "processed %i commands", cnt ));
     712             : 
     713          48 : # undef SHIFT
     714          48 :   fd_halt();
     715          48 :   return 0;
     716          48 : }
     717             : 
     718             : #else
     719             : 
     720             : int
     721             : main( int     argc,
     722             :       char ** argv ) {
     723             :   fd_boot( &argc, &argv );
     724             :   if( FD_UNLIKELY( argc<1 ) ) FD_LOG_ERR(( "No arguments" ));
     725             :   if( FD_UNLIKELY( argc>1 ) ) FD_LOG_ERR(( "fd_pod_ctl not supported on this platform" ));
     726             :   FD_LOG_NOTICE(( "processed 0 commands" ));
     727             :   fd_halt();
     728             :   return 0;
     729             : }
     730             : 
     731             : #endif
     732             : 

Generated by: LCOV version 1.14