LCOV - code coverage report
Current view: top level - util/pod - fd_pod_ctl.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 127 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 5 0.0 %

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

Generated by: LCOV version 1.14