00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "korebot.h"
00012
00013
00028 static int kb_is_valid_ientifier( const char * str );
00029
00030 static void kb_config_error( const char * file ,
00031 unsigned int line ,
00032 const char * func ,
00033 unsigned int error ,
00034 va_list argptr );
00035
00036 static int kb_parse_section( int argc , char * argv[] , void * data);
00037 static int kb_parse_modbus( int argc , char * argv[] , void * data);
00038 static int kb_parse_modbusaddr( int argc , char * argv[] , void * data);
00039 static int kb_parse_alias( int argc , char * argv[] , void * data);
00040 static int kb_parse_device( int argc , char * argv[] , void * data);
00041 static int kb_parse_register( int argc , char * argv[] , void * data);
00042
00043 static struct kb_command_s kb_config_cmds[] = {
00044 { "section" , 1 , 1 , kb_parse_section } ,
00045 { "modulebus" , 1 , 1 , kb_parse_modbus } ,
00046 { "modbusaddr", 1 , 1 , kb_parse_modbusaddr} ,
00047 { "alias" , 1 , 1 , kb_parse_alias } ,
00048 { "device" , 3 , 3 , kb_parse_device } ,
00049 { "register" , 2 , 2 , kb_parse_register } ,
00050 { NULL , 0 , 0 , NULL }
00051 };
00052
00058 const char * device_class_names[] = {
00059 "i2c" , "spi" , "module" , "rs232" , NULL
00060 };
00061
00062 static kb_symbol_table_t kb_config_table;
00063 static kb_symbol_t * kb_sections = NULL;
00064 static kb_symbol_t * kb_config_scope = NULL;
00065 static const char * kb_config_file = 0;
00066 static unsigned int kb_config_line = 0;
00067
00068
00078 int kb_config_init( int argc , char * argv[] )
00079 {
00080 DIR * dir;
00081 struct dirent *d;
00082 char *p;
00083 int rc = 0;
00084 unsigned int count = 0;
00085 char filename[PATH_MAX + 1];
00086
00087 kb_create_symbol_table( &kb_config_table );
00088
00089
00090 if ((dir = opendir(KB_CONFIG_DIR_INTERNAL)) == NULL ) {
00091 return kb_warning(KB_WARN_OPENDIR, KB_CONFIG_DIR_INTERNAL);
00092 }
00093
00094 while ((d = readdir( dir)) != NULL ) {
00095 strcpy(filename, KB_CONFIG_DIR_INTERNAL);
00096 strcat(filename, d->d_name);
00097 p = d->d_name + strlen(d->d_name) - 4;
00098 if (!strncmp(p,".knc",4)) {
00099 count++;
00100 if ((rc=kb_parse_config_file(filename))<0) {
00101 break;
00102 }
00103 }
00104 }
00105
00106 if(!count)
00107 kb_warning( KB_WARN_CONFIG_FILE, KB_CONFIG_DIR_INTERNAL );
00108
00109 closedir( dir );
00110
00111
00112
00113 return rc;
00114 }
00115
00116
00123 void kb_config_exit( void )
00124 {
00125 kb_destroy_symbol_table(&kb_config_table);
00126 }
00127
00128
00137 kb_device_config_t * kb_lookup_device( const char * name )
00138 {
00139 kb_symbol_t * sym;
00140 kb_alias_config_t * alias;
00141
00142 if ((sym = kb_lookup_symbol( &kb_config_table , name )) != NULL ) {
00143
00144 if ( sym->type == KB_SYMBOL_TYPE_ALIAS ) {
00145 alias = (kb_alias_config_t *)sym->value;
00146
00147 if ( alias->ptr == NULL ) {
00148 sym = kb_lookup_symbol( &kb_config_table , alias->name );
00149 }
00150 else {
00151 sym = alias->ptr;
00152 }
00153
00154 if ( sym == NULL ) return NULL;
00155 }
00156
00157 if ( sym->type == KB_SYMBOL_TYPE_DEVICE ) {
00158 return (kb_device_config_t *)sym->value;
00159 }
00160
00161 }
00162 return NULL;
00163 }
00164
00165
00175 kb_register_config_t * kb_lookup_register( const char * name )
00176 {
00177 kb_symbol_t * sym;
00178 kb_alias_config_t * alias;
00179
00180 if ((sym = kb_lookup_symbol( &kb_config_table , name )) != NULL ) {
00181
00182 if ( sym->type == KB_SYMBOL_TYPE_ALIAS ) {
00183 alias = (kb_alias_config_t *)sym->value;
00184
00185 if ( alias->ptr == NULL ) {
00186 sym = kb_lookup_symbol( &kb_config_table , alias->name );
00187 }
00188 else {
00189 sym = alias->ptr;
00190 }
00191
00192 if ( sym == NULL ) return NULL;
00193 }
00194
00195 if ( sym->type == KB_SYMBOL_TYPE_REGISTER )
00196 return (kb_register_config_t *)sym->value;
00197
00198 }
00199 return NULL;
00200 }
00201
00202
00221 static int kb_is_valid_identifier( const char * str )
00222 {
00223 unsigned int pos;
00224 unsigned int len = strlen(str);
00225
00226 int ok = 0;
00227
00228 if ((isalpha(str[0]) || str[0]=='_') && len >= 3) {
00229
00230 ok = 1;
00231 for (pos=1; pos<len; pos++) {
00232 if ( ! (isalnum(str[pos]) || str[pos]=='_') ) {
00233 ok = 0;
00234 break;
00235 }
00236 }
00237 }
00238
00239 if ( !ok ) {
00240 return kb_error( __FILE__ ,
00241 __LINE__ ,
00242 "kb_is_valid_identifier" ,
00243 KB_ERROR_INVALID ,
00244 str );
00245 }
00246
00247 return 0;
00248 }
00249
00250
00263 static char * kb_build_scoped_name( char * scoped_name ,
00264 const char * name )
00265 {
00266 static char buffer[ KB_SYMBOL_NAME_SIZE ];
00267
00268 if ( scoped_name == NULL )
00269 scoped_name = buffer;
00270
00271 if ( kb_config_scope != NULL )
00272 sprintf( scoped_name , "%s:%s" , kb_config_scope->name , name );
00273 else
00274 strcpy( scoped_name , name );
00275
00276 return scoped_name;
00277 }
00278
00279
00293 static void kb_config_error( const char * file ,
00294 unsigned int line ,
00295 const char * func ,
00296 unsigned int error ,
00297 va_list argptr )
00298 {
00299 fprintf( stderr , "%s:%u " ,
00300 kb_config_file ,
00301 kb_config_line );
00302
00303 kb_verror( file , line , func , error , argptr );
00304 }
00305
00306
00323 static int kb_parse_modbus( int argc , char * argv[] , void * data)
00324 {
00325 int device_class;
00326 kb_section_config_t * section;
00327
00328
00329 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00330 return kb_error( __FILE__ ,
00331 __LINE__ ,
00332 "kb_parse_modbus" ,
00333 KB_ERROR_NOSECTION ,
00334 argv[0], argv[1] );
00335 }
00336
00337
00338 device_class = kb_find_string( argv[1] , knet_bus_names );
00339
00340 if ( device_class == -1 ) {
00341 return kb_error( __FILE__ ,
00342 __LINE__ ,
00343 "kb_parse_modbus" ,
00344 KB_ERROR_UNKBUS ,
00345 argv[1] );
00346 }
00347
00348
00349 section->module_bus = device_class - 1;
00350
00351 return 1;
00352 }
00353
00354
00371 static int kb_parse_modbusaddr( int argc , char * argv[] , void * data)
00372 {
00373 int device_class;
00374 kb_section_config_t * section;
00375
00376
00377 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00378 return kb_error( __FILE__ ,
00379 __LINE__ ,
00380 "kb_parse_modbus" ,
00381 KB_ERROR_NOSECTION ,
00382 argv[0], argv[1] );
00383 }
00384
00385
00386 section->module_bus_addr = atoi(argv[1]);
00387
00388 return 1;
00389 }
00390
00391
00406 static int kb_parse_section( int argc , char * argv[] , void * data)
00407 {
00408 kb_symbol_t * sym;
00409 kb_section_config_t * section;
00410
00411
00412 if (kb_is_valid_identifier(argv[1])<0)
00413 return 0;
00414
00415
00416 if ( kb_lookup_symbol( &kb_config_table , argv[1] ) != NULL ) {
00417
00418 kb_error( __FILE__ ,
00419 __LINE__ ,
00420 "kb_config_parse_section" ,
00421 KB_ERROR_SYMDEF , argv[1] );
00422 return 0;
00423 }
00424
00425 section = KB_ALLOC( kb_section_config_t , 1 );
00426 section->module_bus = -1;
00427 section->module_bus_addr = -1;
00428 section->device_count = 0;
00429 section->devices = NULL;
00430 section->register_count = 0;
00431 section->registers = NULL;
00432 section->next = NULL;
00433
00434 sym = KB_ALLOC( kb_symbol_t , 1 );
00435 sym->alloc = 1;
00436 sym->value = (unsigned int) section;
00437 sym->type = KB_SYMBOL_TYPE_SECTION;
00438 sym->next = NULL;
00439 strcpy( sym->name , argv[1] );
00440
00441 kb_add_symbol( &kb_config_table , sym );
00442
00443 section->next = kb_sections;
00444 kb_sections = sym;
00445
00446 kb_config_scope = sym;
00447
00448 return 1;
00449 }
00450
00451
00466 static int kb_parse_alias( int argc , char * argv[] , void * data)
00467 {
00468 char sym_name[ KB_SYMBOL_NAME_SIZE ];
00469 char *alias_name;
00470 kb_symbol_t *sym , * aliasSym ;
00471 kb_alias_config_t * alias;
00472 kb_section_config_t * section;
00473
00474
00475 if ( kb_is_valid_identifier( argv[1] ) < 0)
00476 return 0;
00477
00478 kb_build_scoped_name( sym_name , argv[1] );
00479
00480
00481 if (kb_lookup_symbol( &kb_config_table , sym_name ) != NULL ) {
00482 kb_error( __FILE__ ,
00483 __LINE__ ,
00484 "kb_parse_alias" ,
00485 KB_ERROR_SYMDEF ,
00486 sym_name );
00487 return 0;
00488 }
00489
00490
00491 if ( strchr( argv[2] , ':' ) == NULL ) {
00492 alias_name = kb_build_scoped_name( NULL , argv[2] );
00493 }
00494 else {
00495 alias_name = argv[2];
00496 }
00497
00498
00499 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00500 return kb_error( __FILE__ ,
00501 __LINE__ ,
00502 "kb_parse_alias" ,
00503 KB_ERROR_NOSECTION ,
00504 "alias" , argv[1] );
00505 }
00506
00507
00508 aliasSym = kb_lookup_symbol ( &kb_config_table , alias_name );
00509
00510 alias = KB_ALLOC( kb_alias_config_t , 1 );
00511 alias->ptr = aliasSym;
00512 strcpy(alias->name , alias_name );
00513
00514 sym = KB_ALLOC( kb_symbol_t , 1 );
00515 sym->type = KB_SYMBOL_TYPE_ALIAS;
00516 sym->value = (unsigned int)alias;
00517 sym->alloc = 1;
00518 sym->next = NULL;
00519 strcpy( sym->name , sym_name );
00520
00521 alias->next = section->aliases;
00522 section->aliases = sym;
00523 section->alias_count++;
00524
00525 kb_add_symbol( &kb_config_table , sym );
00526
00527 return 1;
00528 }
00529
00530
00545 static int kb_parse_device( int argc , char * argv[] , void * data)
00546 {
00547 int device_class;
00548 long device_address;
00549 char * device_name;
00550 char * sym_name;
00551 kb_symbol_t * sym;
00552 kb_device_config_t * dev;
00553
00554
00555 if (kb_is_valid_identifier( argv[1] )<0)
00556 return 0;
00557
00558
00559 device_class = kb_find_string( argv[2] , device_class_names );
00560
00561 if ( device_class == -1 ) {
00562 kb_error( __FILE__ ,
00563 __LINE__ ,
00564 "kb_parse_device" ,
00565 KB_ERROR_UNKDEVCLASS ,
00566 argv[2] );
00567 return 0;
00568 }
00569
00570 device_name = NULL;
00571 device_address = 0;
00572 sym_name = kb_build_scoped_name( NULL , argv[1] );
00573
00574
00575 if ((sym=kb_lookup_symbol( &kb_config_table , sym_name )) != NULL ) {
00576
00577
00578 if (sym->type != KB_SYMBOL_TYPE_DEVICE ) {
00579 kb_error( __FILE__ ,
00580 __LINE__ ,
00581 "kb_parse_device" ,
00582 KB_ERROR_SYMDEF ,
00583 argv[1] );
00584 return 0;
00585 }
00586
00587 dev = (kb_device_config_t *)sym->value;
00588
00589 if ( dev->kclass[ device_class ].defined ) {
00590 kb_error( __FILE__ ,
00591 __LINE__ ,
00592 "kb_parse_device" ,
00593 KB_ERROR_DEVCLASSUSED ,
00594 argv[1] , argv[2] );
00595 return 0;
00596 }
00597
00598 }
00599 else {
00600
00601 kb_section_config_t * section;
00602
00603 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00604 return kb_error( __FILE__ ,
00605 __LINE__ ,
00606 "kb_parse_device" ,
00607 KB_ERROR_NOSECTION ,
00608 "device" , argv[1] );
00609 }
00610
00611 dev = KB_ALLOC( kb_device_config_t , 1 );
00612
00613 dev->next = NULL;
00614
00615
00616 sym = KB_ALLOC( kb_symbol_t , 1 );
00617 sym->type = KB_SYMBOL_TYPE_DEVICE;
00618 sym->value = (unsigned int) dev;
00619 sym->alloc = 1;
00620 sym->next = NULL;
00621 strcpy( sym->name , sym_name );
00622
00623 dev->next = section->devices;
00624 dev->section = section;
00625 section->devices = sym;
00626 section->device_count++;
00627
00628 kb_add_symbol( &kb_config_table , sym );
00629
00630 }
00631
00632
00633
00634 dev->kclass[ device_class ].defined = 1;
00635
00636
00637 switch(device_class)
00638 {
00639 case KB_DEVICE_CLASS_I2C:
00640 case KB_DEVICE_CLASS_MODULE:
00641 case KB_DEVICE_CLASS_SPI:
00642
00643 if ((device_address = strtol(argv[3],NULL,0))<0) {
00644 kb_error( __FILE__ ,
00645 __LINE__ ,
00646 "kb_parse_device" ,
00647 KB_ERROR_INVNUM , argv[3] );
00648
00649 return 0;
00650 }
00651
00652 dev->kclass[ device_class ].address = device_address;
00653 strncpy(dev->kclass[ device_class ].device_name, "/dev/null", KB_SYMBOL_NAME_SIZE);
00654 break;
00655
00656 case KB_DEVICE_CLASS_RS232:
00657 dev->kclass[ device_class ].address = device_address;
00658 device_name = argv[3];
00659 if ( device_name != NULL )
00660 strncpy(dev->kclass[ device_class ].device_name, device_name, KB_SYMBOL_NAME_SIZE);
00661 else {
00662 kb_error( __FILE__ ,
00663 __LINE__ ,
00664 "kb_parse_device" ,
00665 KB_ERROR_INVNAME , argv[3] );
00666
00667 return 0;
00668 }
00669
00670 break;
00671 }
00672
00673
00674 #if 0
00675 if ( device_class == KB_DEVICE_CLASS_SPI ||
00676 device_class == KB_DEVICE_CLASS_MODULE ||
00677 device_class == KB_DEVICE_CLASS_I2C ) {
00678
00679 if ((device_address = strtol(argv[3],NULL,0))<0) {
00680 kb_error( __FILE__ ,
00681 __LINE__ ,
00682 "kb_parse_device" ,
00683 KB_ERROR_INVNUM , argv[3] );
00684 return 0;
00685 }
00686 }
00687 else {
00688 device_name = argv[3];
00689 }
00690
00691
00692 if ((sym=kb_lookup_symbol( &kb_config_table , sym_name )) != NULL ) {
00693
00694
00695 if (sym->type != KB_SYMBOL_TYPE_DEVICE ) {
00696 kb_error( __FILE__ ,
00697 __LINE__ ,
00698 "kb_parse_device" ,
00699 KB_ERROR_SYMDEF ,
00700 argv[1] );
00701 return 0;
00702 }
00703
00704
00705 dev = (kb_device_config_t *)sym->value;
00706
00707 if ( dev->kclass[ device_class ].defined ) {
00708 kb_error( __FILE__ ,
00709 __LINE__ ,
00710 "kb_parse_device" ,
00711 KB_ERROR_DEVCLASSUSED ,
00712 argv[1] , argv[2] );
00713 return 0;
00714 }
00715
00716
00717 dev->kclass[ device_class ].defined = 1;
00718 dev->kclass[ device_class ].address = device_address;
00719 if ( device_name != NULL )
00720 strncpy( dev->kclass[ device_class ].device_name ,
00721 device_name , KB_SYMBOL_NAME_SIZE );
00722 }
00723 else {
00724
00725
00726 kb_section_config_t * section;
00727
00728 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00729 return kb_error( __FILE__ ,
00730 __LINE__ ,
00731 "kb_parse_device" ,
00732 KB_ERROR_NOSECTION ,
00733 "device" , argv[1] );
00734 }
00735
00736 dev = KB_ALLOC( kb_device_config_t , 1 );
00737
00738 dev->kclass[ device_class ].defined = 1;
00739 dev->kclass[ device_class ].address = device_address;
00740 if ( device_name != NULL )
00741 strncpy( dev->kclass[ device_class ].device_name ,
00742 device_name , KB_SYMBOL_NAME_SIZE );
00743 dev->next = NULL;
00744
00745 sym = KB_ALLOC( kb_symbol_t , 1 );
00746 sym->type = KB_SYMBOL_TYPE_DEVICE;
00747 sym->value = (unsigned int) dev;
00748 sym->alloc = 1;
00749 sym->next = NULL;
00750 strcpy( sym->name , sym_name );
00751
00752 dev->next = section->devices;
00753 dev->section = section;
00754 section->devices = sym;
00755 section->device_count++;
00756
00757 kb_add_symbol( &kb_config_table , sym );
00758 }
00759 #endif
00760 return 1;
00761 }
00762
00763
00778 static int kb_parse_register( int argc , char * argv[] , void * data)
00779 {
00780 long value;
00781 char * sym_name;
00782 kb_symbol_t * sym;
00783 kb_register_config_t * reg;
00784 kb_section_config_t * section;
00785
00786
00787 if ( kb_is_valid_identifier( argv[1] ) < 0 )
00788 return 0;
00789
00790 if ((value = strtol( argv[3] , NULL , 0 )) < 0) {
00791 kb_error( __FILE__ ,
00792 __LINE__ ,
00793 "kb_parse_register" ,
00794 KB_ERROR_INVNUM , argv[3] );
00795 return 0;
00796 }
00797
00798 sym_name = kb_build_scoped_name( NULL , argv[1] );
00799
00800 if (( sym = kb_lookup_symbol( &kb_config_table , sym_name )) != NULL ) {
00801 kb_error( __FILE__ ,
00802 __LINE__ ,
00803 "kb_parse_register" ,
00804 KB_ERROR_SYMDEF , sym_name );
00805 return 0;
00806 }
00807
00808
00809 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00810 return kb_error( __FILE__ ,
00811 __LINE__ ,
00812 "kb_parse_register" ,
00813 KB_ERROR_NOSECTION ,
00814 "register" , argv[1] );
00815 }
00816
00817 reg = KB_ALLOC( kb_register_config_t , 1 );
00818 reg->value = value;
00819 reg->next = NULL;
00820
00821 sym = KB_ALLOC(kb_symbol_t,1);
00822 sym->type = KB_SYMBOL_TYPE_REGISTER;
00823 sym->alloc = 1;
00824 strcpy( sym->name , sym_name );
00825 sym->value = (unsigned int)reg;
00826 sym->next = NULL;
00827
00828 reg->next = section->registers;
00829 section->registers = sym;
00830 section->register_count++;
00831
00832 kb_add_symbol( &kb_config_table , sym );
00833
00834 return 0;
00835 }
00836
00837
00848 int kb_parse_config_file( const char * file )
00849 {
00850 FILE * in;
00851 char * buf;
00852 int rc , len;
00853
00854
00855 if ((in = fopen( file , "r")) == NULL ) {
00856 return kb_error( __FILE__ ,
00857 __LINE__ ,
00858 "kb_parse_config_file" ,
00859 KB_ERROR_FILEOPEN ,
00860 file );
00861 }
00862
00863 buf = KB_ALLOC( char , 1024 );
00864
00865 kb_set_error_handler( kb_config_error );
00866
00867 kb_config_line = 0;
00868 kb_config_file = file;
00869 kb_config_scope = NULL;
00870
00871 while(fgets(buf,1024, in) != NULL) {
00872
00873 kb_config_line++;
00874
00875
00876 len = strlen( buf );
00877 if ( len > 0 )
00878 buf[len-1] = '\0';
00879
00880
00881 if (buf[0]=='#' || buf[0]=='\0')
00882 continue;
00883
00884 if ((rc = kb_parse_command( buf , kb_config_cmds ,NULL))<0) {
00885 if ( rc != -KB_ERROR_UNKCMD )
00886 break;
00887 }
00888 rc = 0;
00889
00890 }
00891 kb_set_error_handler( NULL );
00892 kb_free(buf);
00893 fclose(in);
00894 return rc;
00895 }
00896
00897
00909 int kb_enum_section( int (*func)( const char * name ,
00910 kb_section_config_t * section ,
00911 void * context ) ,
00912 void * context )
00913 {
00914 int rc, count = 0;
00915 kb_symbol_t * sym = kb_sections;
00916 kb_section_config_t * section;
00917
00918 if ( sym ) {
00919 while ( sym != NULL ) {
00920 section = (kb_section_config_t *)sym->value;
00921
00922 if ((rc = func( sym->name , section , context ))<0)
00923 return rc;
00924
00925 sym = section->next;
00926 count++;
00927 }
00928 return count;
00929 }
00930 return 0;
00931 }
00932
00933
00946 int kb_enum_alias( const char * section_name ,
00947 int (*func)( const char * name ,
00948 kb_alias_config_t * alias ,
00949 void * context ) ,
00950 void * context )
00951 {
00952 kb_symbol_t * sym;
00953 kb_section_config_t * section;
00954 kb_alias_config_t * alias;
00955 int rc;
00956
00957 sym = kb_lookup_symbol( &kb_config_table , section_name );
00958
00959 if ( sym != NULL ) {
00960
00961 if ( sym->type == KB_SYMBOL_TYPE_SECTION ) {
00962
00963 section = (kb_section_config_t *)sym->value;
00964
00965 sym = section->aliases;
00966
00967 while ( sym != NULL ) {
00968
00969 alias = (kb_alias_config_t *)sym->value;
00970
00971 if ((rc = func( sym->name ,
00972 alias ,
00973 context )) < 0 )
00974 return rc;
00975
00976 sym = alias->next;
00977 }
00978 return (int)section->alias_count;
00979 }
00980 }
00981 return 0;
00982 }
00983
00984
00997 int kb_enum_device( const char * section_name ,
00998 int (*func)( const char * name ,
00999 kb_device_config_t * device ,
01000 void * context ) ,
01001 void * context )
01002 {
01003 kb_symbol_t * sym;
01004 kb_section_config_t * section;
01005 kb_device_config_t * device;
01006 int rc;
01007
01008 sym = kb_lookup_symbol( &kb_config_table , section_name );
01009
01010 if ( sym != NULL ) {
01011
01012 if ( sym->type == KB_SYMBOL_TYPE_SECTION ) {
01013
01014 section = (kb_section_config_t *)sym->value;
01015
01016 sym = section->devices;
01017
01018 while ( sym != NULL ) {
01019
01020 device = (kb_device_config_t *)sym->value;
01021
01022 if ((rc = func( sym->name ,
01023 device ,
01024 context )) < 0 )
01025 return rc;
01026
01027 sym = device->next;
01028 }
01029 return (int)section->device_count;
01030 }
01031 }
01032 return 0;
01033 }
01034
01035
01047 int kb_enum_register( const char * section_name ,
01048 int (*func)( const char * name ,
01049 kb_register_config_t * reg ,
01050 void * context ) ,
01051 void * context )
01052 {
01053 kb_symbol_t * sym;
01054 kb_section_config_t * section;
01055 kb_register_config_t * reg;
01056 int rc;
01057
01058 sym = kb_lookup_symbol( &kb_config_table , section_name );
01059
01060 if ( sym != NULL ) {
01061
01062 if ( sym->type == KB_SYMBOL_TYPE_SECTION ) {
01063
01064 section = (kb_section_config_t *)sym->value;
01065
01066 sym = section->registers;
01067
01068 while ( sym != NULL ) {
01069
01070 reg = (kb_register_config_t *)sym->value;
01071
01072 if ((rc = func( sym->name , reg , context )) < 0 )
01073 return rc;
01074
01075 sym = reg->next;
01076 }
01077 return (int)section->register_count;
01078 }
01079 }
01080 return 0;
01081 }