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
00321 static int kb_parse_modbus( int argc , char * argv[] , void * data)
00322 {
00323 int device_class;
00324 kb_section_config_t * section;
00325
00326
00327 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00328 return kb_error( __FILE__ ,
00329 __LINE__ ,
00330 "kb_parse_modbus" ,
00331 KB_ERROR_NOSECTION ,
00332 argv[0], argv[1] );
00333 }
00334
00335
00336 device_class = kb_find_string( argv[1] , knet_bus_names );
00337
00338 if ( device_class == -1 ) {
00339 return kb_error( __FILE__ ,
00340 __LINE__ ,
00341 "kb_parse_modbus" ,
00342 KB_ERROR_UNKBUS ,
00343 argv[1] );
00344 }
00345
00346
00347 section->module_bus = device_class - 1;
00348
00349 return 1;
00350 }
00351
00352
00367 static int kb_parse_modbusaddr( int argc , char * argv[] , void * data)
00368 {
00369 int device_class;
00370 kb_section_config_t * section;
00371
00372
00373 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00374 return kb_error( __FILE__ ,
00375 __LINE__ ,
00376 "kb_parse_modbus" ,
00377 KB_ERROR_NOSECTION ,
00378 argv[0], argv[1] );
00379 }
00380
00381
00382 section->module_bus_addr = atoi(argv[1]);
00383
00384 return 1;
00385 }
00386
00387
00400 static int kb_parse_section( int argc , char * argv[] , void * data)
00401 {
00402 kb_symbol_t * sym;
00403 kb_section_config_t * section;
00404
00405
00406 if (kb_is_valid_identifier(argv[1])<0)
00407 return 0;
00408
00409
00410 if ( kb_lookup_symbol( &kb_config_table , argv[1] ) != NULL ) {
00411
00412 kb_error( __FILE__ ,
00413 __LINE__ ,
00414 "kb_config_parse_section" ,
00415 KB_ERROR_SYMDEF , argv[1] );
00416 return 0;
00417 }
00418
00419 section = KB_ALLOC( kb_section_config_t , 1 );
00420 section->module_bus = -1;
00421 section->module_bus_addr = -1;
00422 section->device_count = 0;
00423 section->devices = NULL;
00424 section->register_count = 0;
00425 section->registers = NULL;
00426 section->next = NULL;
00427
00428 sym = KB_ALLOC( kb_symbol_t , 1 );
00429 sym->alloc = 1;
00430 sym->value = (unsigned int) section;
00431 sym->type = KB_SYMBOL_TYPE_SECTION;
00432 sym->next = NULL;
00433 strcpy( sym->name , argv[1] );
00434
00435 kb_add_symbol( &kb_config_table , sym );
00436
00437 section->next = kb_sections;
00438 kb_sections = sym;
00439
00440 kb_config_scope = sym;
00441
00442 return 1;
00443 }
00444
00445
00458 static int kb_parse_alias( int argc , char * argv[] , void * data)
00459 {
00460 char sym_name[ KB_SYMBOL_NAME_SIZE ];
00461 char *alias_name;
00462 kb_symbol_t *sym , * aliasSym ;
00463 kb_alias_config_t * alias;
00464 kb_section_config_t * section;
00465
00466
00467 if ( kb_is_valid_identifier( argv[1] ) < 0)
00468 return 0;
00469
00470 kb_build_scoped_name( sym_name , argv[1] );
00471
00472
00473 if (kb_lookup_symbol( &kb_config_table , sym_name ) != NULL ) {
00474 kb_error( __FILE__ ,
00475 __LINE__ ,
00476 "kb_parse_alias" ,
00477 KB_ERROR_SYMDEF ,
00478 sym_name );
00479 return 0;
00480 }
00481
00482
00483 if ( strchr( argv[2] , ':' ) == NULL ) {
00484 alias_name = kb_build_scoped_name( NULL , argv[2] );
00485 }
00486 else {
00487 alias_name = argv[2];
00488 }
00489
00490
00491 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00492 return kb_error( __FILE__ ,
00493 __LINE__ ,
00494 "kb_parse_alias" ,
00495 KB_ERROR_NOSECTION ,
00496 "alias" , argv[1] );
00497 }
00498
00499
00500 aliasSym = kb_lookup_symbol ( &kb_config_table , alias_name );
00501
00502 alias = KB_ALLOC( kb_alias_config_t , 1 );
00503 alias->ptr = aliasSym;
00504 strcpy(alias->name , alias_name );
00505
00506 sym = KB_ALLOC( kb_symbol_t , 1 );
00507 sym->type = KB_SYMBOL_TYPE_ALIAS;
00508 sym->value = (unsigned int)alias;
00509 sym->alloc = 1;
00510 sym->next = NULL;
00511 strcpy( sym->name , sym_name );
00512
00513 alias->next = section->aliases;
00514 section->aliases = sym;
00515 section->alias_count++;
00516
00517 kb_add_symbol( &kb_config_table , sym );
00518
00519 return 1;
00520 }
00521
00522
00535 static int kb_parse_device( int argc , char * argv[] , void * data)
00536 {
00537 int device_class;
00538 long device_address;
00539 char * device_name;
00540 char * sym_name;
00541 kb_symbol_t * sym;
00542 kb_device_config_t * dev;
00543
00544
00545 if (kb_is_valid_identifier( argv[1] )<0)
00546 return 0;
00547
00548
00549 device_class = kb_find_string( argv[2] , device_class_names );
00550
00551 if ( device_class == -1 ) {
00552 kb_error( __FILE__ ,
00553 __LINE__ ,
00554 "kb_parse_device" ,
00555 KB_ERROR_UNKDEVCLASS ,
00556 argv[2] );
00557 return 0;
00558 }
00559
00560 device_name = NULL;
00561 device_address = 0;
00562 sym_name = kb_build_scoped_name( NULL , argv[1] );
00563
00564
00565 if ((sym=kb_lookup_symbol( &kb_config_table , sym_name )) != NULL ) {
00566
00567
00568 if (sym->type != KB_SYMBOL_TYPE_DEVICE ) {
00569 kb_error( __FILE__ ,
00570 __LINE__ ,
00571 "kb_parse_device" ,
00572 KB_ERROR_SYMDEF ,
00573 argv[1] );
00574 return 0;
00575 }
00576
00577 dev = (kb_device_config_t *)sym->value;
00578
00579 if ( dev->kclass[ device_class ].defined ) {
00580 kb_error( __FILE__ ,
00581 __LINE__ ,
00582 "kb_parse_device" ,
00583 KB_ERROR_DEVCLASSUSED ,
00584 argv[1] , argv[2] );
00585 return 0;
00586 }
00587
00588 }
00589 else {
00590
00591 kb_section_config_t * section;
00592
00593 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00594 return kb_error( __FILE__ ,
00595 __LINE__ ,
00596 "kb_parse_device" ,
00597 KB_ERROR_NOSECTION ,
00598 "device" , argv[1] );
00599 }
00600
00601 dev = KB_ALLOC( kb_device_config_t , 1 );
00602
00603 dev->next = NULL;
00604
00605
00606 sym = KB_ALLOC( kb_symbol_t , 1 );
00607 sym->type = KB_SYMBOL_TYPE_DEVICE;
00608 sym->value = (unsigned int) dev;
00609 sym->alloc = 1;
00610 sym->next = NULL;
00611 strcpy( sym->name , sym_name );
00612
00613 dev->next = section->devices;
00614 dev->section = section;
00615 section->devices = sym;
00616 section->device_count++;
00617
00618 kb_add_symbol( &kb_config_table , sym );
00619
00620 }
00621
00622
00623
00624 dev->kclass[ device_class ].defined = 1;
00625
00626
00627 switch(device_class)
00628 {
00629 case KB_DEVICE_CLASS_I2C:
00630 case KB_DEVICE_CLASS_MODULE:
00631 case KB_DEVICE_CLASS_SPI:
00632
00633 if ((device_address = strtol(argv[3],NULL,0))<0) {
00634 kb_error( __FILE__ ,
00635 __LINE__ ,
00636 "kb_parse_device" ,
00637 KB_ERROR_INVNUM , argv[3] );
00638
00639 return 0;
00640 }
00641
00642 dev->kclass[ device_class ].address = device_address;
00643 strncpy(dev->kclass[ device_class ].device_name, "/dev/null", KB_SYMBOL_NAME_SIZE);
00644 break;
00645
00646 case KB_DEVICE_CLASS_RS232:
00647 dev->kclass[ device_class ].address = device_address;
00648 device_name = argv[3];
00649 if ( device_name != NULL )
00650 strncpy(dev->kclass[ device_class ].device_name, device_name, KB_SYMBOL_NAME_SIZE);
00651 else {
00652 kb_error( __FILE__ ,
00653 __LINE__ ,
00654 "kb_parse_device" ,
00655 KB_ERROR_INVNAME , argv[3] );
00656
00657 return 0;
00658 }
00659
00660 break;
00661 }
00662
00663
00664 #if 0
00665 if ( device_class == KB_DEVICE_CLASS_SPI ||
00666 device_class == KB_DEVICE_CLASS_MODULE ||
00667 device_class == KB_DEVICE_CLASS_I2C ) {
00668
00669 if ((device_address = strtol(argv[3],NULL,0))<0) {
00670 kb_error( __FILE__ ,
00671 __LINE__ ,
00672 "kb_parse_device" ,
00673 KB_ERROR_INVNUM , argv[3] );
00674 return 0;
00675 }
00676 }
00677 else {
00678 device_name = argv[3];
00679 }
00680
00681
00682 if ((sym=kb_lookup_symbol( &kb_config_table , sym_name )) != NULL ) {
00683
00684
00685 if (sym->type != KB_SYMBOL_TYPE_DEVICE ) {
00686 kb_error( __FILE__ ,
00687 __LINE__ ,
00688 "kb_parse_device" ,
00689 KB_ERROR_SYMDEF ,
00690 argv[1] );
00691 return 0;
00692 }
00693
00694
00695 dev = (kb_device_config_t *)sym->value;
00696
00697 if ( dev->kclass[ device_class ].defined ) {
00698 kb_error( __FILE__ ,
00699 __LINE__ ,
00700 "kb_parse_device" ,
00701 KB_ERROR_DEVCLASSUSED ,
00702 argv[1] , argv[2] );
00703 return 0;
00704 }
00705
00706
00707 dev->kclass[ device_class ].defined = 1;
00708 dev->kclass[ device_class ].address = device_address;
00709 if ( device_name != NULL )
00710 strncpy( dev->kclass[ device_class ].device_name ,
00711 device_name , KB_SYMBOL_NAME_SIZE );
00712 }
00713 else {
00714
00715
00716 kb_section_config_t * section;
00717
00718 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00719 return kb_error( __FILE__ ,
00720 __LINE__ ,
00721 "kb_parse_device" ,
00722 KB_ERROR_NOSECTION ,
00723 "device" , argv[1] );
00724 }
00725
00726 dev = KB_ALLOC( kb_device_config_t , 1 );
00727
00728 dev->kclass[ device_class ].defined = 1;
00729 dev->kclass[ device_class ].address = device_address;
00730 if ( device_name != NULL )
00731 strncpy( dev->kclass[ device_class ].device_name ,
00732 device_name , KB_SYMBOL_NAME_SIZE );
00733 dev->next = NULL;
00734
00735 sym = KB_ALLOC( kb_symbol_t , 1 );
00736 sym->type = KB_SYMBOL_TYPE_DEVICE;
00737 sym->value = (unsigned int) dev;
00738 sym->alloc = 1;
00739 sym->next = NULL;
00740 strcpy( sym->name , sym_name );
00741
00742 dev->next = section->devices;
00743 dev->section = section;
00744 section->devices = sym;
00745 section->device_count++;
00746
00747 kb_add_symbol( &kb_config_table , sym );
00748 }
00749 #endif
00750 return 1;
00751 }
00752
00753
00766 static int kb_parse_register( int argc , char * argv[] , void * data)
00767 {
00768 long value;
00769 char * sym_name;
00770 kb_symbol_t * sym;
00771 kb_register_config_t * reg;
00772 kb_section_config_t * section;
00773
00774
00775 if ( kb_is_valid_identifier( argv[1] ) < 0 )
00776 return 0;
00777
00778 if ((value = strtol( argv[3] , NULL , 0 )) < 0) {
00779 kb_error( __FILE__ ,
00780 __LINE__ ,
00781 "kb_parse_register" ,
00782 KB_ERROR_INVNUM , argv[3] );
00783 return 0;
00784 }
00785
00786 sym_name = kb_build_scoped_name( NULL , argv[1] );
00787
00788 if (( sym = kb_lookup_symbol( &kb_config_table , sym_name )) != NULL ) {
00789 kb_error( __FILE__ ,
00790 __LINE__ ,
00791 "kb_parse_register" ,
00792 KB_ERROR_SYMDEF , sym_name );
00793 return 0;
00794 }
00795
00796
00797 if ( !kb_config_scope || !(section = (kb_section_config_t *)kb_config_scope->value)) {
00798 return kb_error( __FILE__ ,
00799 __LINE__ ,
00800 "kb_parse_register" ,
00801 KB_ERROR_NOSECTION ,
00802 "register" , argv[1] );
00803 }
00804
00805 reg = KB_ALLOC( kb_register_config_t , 1 );
00806 reg->value = value;
00807 reg->next = NULL;
00808
00809 sym = KB_ALLOC(kb_symbol_t,1);
00810 sym->type = KB_SYMBOL_TYPE_REGISTER;
00811 sym->alloc = 1;
00812 strcpy( sym->name , sym_name );
00813 sym->value = (unsigned int)reg;
00814 sym->next = NULL;
00815
00816 reg->next = section->registers;
00817 section->registers = sym;
00818 section->register_count++;
00819
00820 kb_add_symbol( &kb_config_table , sym );
00821
00822 return 0;
00823 }
00824
00825
00836 int kb_parse_config_file( const char * file )
00837 {
00838 FILE * in;
00839 char * buf;
00840 int rc , len;
00841
00842
00843 if ((in = fopen( file , "r")) == NULL ) {
00844 return kb_error( __FILE__ ,
00845 __LINE__ ,
00846 "kb_parse_config_file" ,
00847 KB_ERROR_FILEOPEN ,
00848 file );
00849 }
00850
00851 buf = KB_ALLOC( char , 1024 );
00852
00853 kb_set_error_handler( kb_config_error );
00854
00855 kb_config_line = 0;
00856 kb_config_file = file;
00857 kb_config_scope = NULL;
00858
00859 while(fgets(buf,1024, in) != NULL) {
00860
00861 kb_config_line++;
00862
00863
00864 len = strlen( buf );
00865 if ( len > 0 )
00866 buf[len-1] = '\0';
00867
00868
00869 if (buf[0]=='#' || buf[0]=='\0')
00870 continue;
00871
00872 if ((rc = kb_parse_command( buf , kb_config_cmds ,NULL))<0) {
00873 if ( rc != -KB_ERROR_UNKCMD )
00874 break;
00875 }
00876 rc = 0;
00877
00878 }
00879 kb_set_error_handler( NULL );
00880 kb_free(buf);
00881 fclose(in);
00882 return rc;
00883 }
00884
00885
00897 int kb_enum_section( int (*func)( const char * name ,
00898 kb_section_config_t * section ,
00899 void * context ) ,
00900 void * context )
00901 {
00902 int rc, count = 0;
00903 kb_symbol_t * sym = kb_sections;
00904 kb_section_config_t * section;
00905
00906 if ( sym ) {
00907 while ( sym != NULL ) {
00908 section = (kb_section_config_t *)sym->value;
00909
00910 if ((rc = func( sym->name , section , context ))<0)
00911 return rc;
00912
00913 sym = section->next;
00914 count++;
00915 }
00916 return count;
00917 }
00918 return 0;
00919 }
00920
00921
00934 int kb_enum_alias( const char * section_name ,
00935 int (*func)( const char * name ,
00936 kb_alias_config_t * alias ,
00937 void * context ) ,
00938 void * context )
00939 {
00940 kb_symbol_t * sym;
00941 kb_section_config_t * section;
00942 kb_alias_config_t * alias;
00943 int rc;
00944
00945 sym = kb_lookup_symbol( &kb_config_table , section_name );
00946
00947 if ( sym != NULL ) {
00948
00949 if ( sym->type == KB_SYMBOL_TYPE_SECTION ) {
00950
00951 section = (kb_section_config_t *)sym->value;
00952
00953 sym = section->aliases;
00954
00955 while ( sym != NULL ) {
00956
00957 alias = (kb_alias_config_t *)sym->value;
00958
00959 if ((rc = func( sym->name ,
00960 alias ,
00961 context )) < 0 )
00962 return rc;
00963
00964 sym = alias->next;
00965 }
00966 return (int)section->alias_count;
00967 }
00968 }
00969 return 0;
00970 }
00971
00972
00985 int kb_enum_device( const char * section_name ,
00986 int (*func)( const char * name ,
00987 kb_device_config_t * device ,
00988 void * context ) ,
00989 void * context )
00990 {
00991 kb_symbol_t * sym;
00992 kb_section_config_t * section;
00993 kb_device_config_t * device;
00994 int rc;
00995
00996 sym = kb_lookup_symbol( &kb_config_table , section_name );
00997
00998 if ( sym != NULL ) {
00999
01000 if ( sym->type == KB_SYMBOL_TYPE_SECTION ) {
01001
01002 section = (kb_section_config_t *)sym->value;
01003
01004 sym = section->devices;
01005
01006 while ( sym != NULL ) {
01007
01008 device = (kb_device_config_t *)sym->value;
01009
01010 if ((rc = func( sym->name ,
01011 device ,
01012 context )) < 0 )
01013 return rc;
01014
01015 sym = device->next;
01016 }
01017 return (int)section->device_count;
01018 }
01019 }
01020 return 0;
01021 }
01022
01023
01035 int kb_enum_register( const char * section_name ,
01036 int (*func)( const char * name ,
01037 kb_register_config_t * reg ,
01038 void * context ) ,
01039 void * context )
01040 {
01041 kb_symbol_t * sym;
01042 kb_section_config_t * section;
01043 kb_register_config_t * reg;
01044 int rc;
01045
01046 sym = kb_lookup_symbol( &kb_config_table , section_name );
01047
01048 if ( sym != NULL ) {
01049
01050 if ( sym->type == KB_SYMBOL_TYPE_SECTION ) {
01051
01052 section = (kb_section_config_t *)sym->value;
01053
01054 sym = section->registers;
01055
01056 while ( sym != NULL ) {
01057
01058 reg = (kb_register_config_t *)sym->value;
01059
01060 if ((rc = func( sym->name , reg , context )) < 0 )
01061 return rc;
01062
01063 sym = reg->next;
01064 }
01065 return (int)section->register_count;
01066 }
01067 }
01068 return 0;
01069 }