Skip to content

Commit

Permalink
[Settings] Add int16, int32 and hex-string configuration setting types
Browse files Browse the repository at this point in the history
Add parse and display routines for 16-bit and 32-bit integer configuration
settings.

Add parse and display routines for hex-string configuration settings.

Assume hex-string as a configuration setting type if no type is explicitly
specified.
  • Loading branch information
Michael Brown committed Mar 18, 2008
1 parent 6fe5856 commit e2613e8
Showing 1 changed file with 131 additions and 5 deletions.
136 changes: 131 additions & 5 deletions src/core/settings.c
Expand Up @@ -25,6 +25,7 @@
#include <errno.h>
#include <assert.h>
#include <gpxe/in.h>
#include <gpxe/vsprintf.h>
#include <gpxe/settings.h>

/** @file
Expand All @@ -45,6 +46,8 @@ static struct config_setting config_settings[0]
static struct config_setting config_settings_end[0]
__table_end ( struct config_setting, config_settings );

struct config_setting_type config_setting_type_hex __config_setting_type;

/**
* Find configuration setting type
*
Expand Down Expand Up @@ -108,9 +111,16 @@ find_or_build_config_setting ( const char *name,
memset ( setting, 0, sizeof ( *setting ) );
setting->name = name;
setting->tag = strtoul ( name, &separator, 10 );
if ( *separator != '.' )
return NULL;
setting->type = find_config_setting_type ( separator + 1 );
switch ( *separator ) {
case '.' :
setting->type = find_config_setting_type ( separator + 1 );
break;
case '\0' :
setting->type = &config_setting_type_hex;
break;
default :
break;
}
if ( ! setting->type )
return NULL;
return setting;
Expand Down Expand Up @@ -340,11 +350,41 @@ static int set_int ( struct config_context *context,
* @ret rc Return status code
*/
static int set_int8 ( struct config_context *context,
struct config_setting *setting,
const char *value ) {
struct config_setting *setting,
const char *value ) {
return set_int ( context, setting, value, 1 );
}

/**
* Set value of 16-bit integer setting
*
* @v context Configuration context
* @v setting Configuration setting
* @v value Setting value (as a string)
* @v size Size of integer (in bytes)
* @ret rc Return status code
*/
static int set_int16 ( struct config_context *context,
struct config_setting *setting,
const char *value ) {
return set_int ( context, setting, value, 2 );
}

/**
* Set value of 32-bit integer setting
*
* @v context Configuration context
* @v setting Configuration setting
* @v value Setting value (as a string)
* @v size Size of integer (in bytes)
* @ret rc Return status code
*/
static int set_int32 ( struct config_context *context,
struct config_setting *setting,
const char *value ) {
return set_int ( context, setting, value, 4 );
}

/** An 8-bit integer configuration setting */
struct config_setting_type config_setting_type_int8 __config_setting_type = {
.name = "int8",
Expand All @@ -353,6 +393,92 @@ struct config_setting_type config_setting_type_int8 __config_setting_type = {
.set = set_int8,
};

/** A 16-bit integer configuration setting */
struct config_setting_type config_setting_type_int16 __config_setting_type = {
.name = "int16",
.description = "16-bit integer",
.show = show_int,
.set = set_int16,
};

/** A 32-bit integer configuration setting */
struct config_setting_type config_setting_type_int32 __config_setting_type = {
.name = "int32",
.description = "32-bit integer",
.show = show_int,
.set = set_int32,
};

/**
* Set value of hex-string setting
*
* @v context Configuration context
* @v setting Configuration setting
* @v value Setting value (as a string)
* @ret rc Return status code
*/
static int set_hex ( struct config_context *context,
struct config_setting *setting,
const char *value ) {
struct dhcp_option *option;
char *ptr = ( char * ) value;
uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
unsigned int len = 0;

while ( 1 ) {
bytes[len++] = strtoul ( ptr, &ptr, 16 );
switch ( *ptr ) {
case '\0' :
option = set_dhcp_option ( context->options,
setting->tag, bytes, len );
if ( ! option )
return -ENOSPC;
return 0;
case ':' :
ptr++;
break;
default :
return -EINVAL;
}
}
}

/**
* Show value of hex-string setting
*
* @v context Configuration context
* @v setting Configuration setting
* @v buf Buffer to contain value
* @v len Length of buffer
* @ret len Length of formatted value, or negative error
*/
static int show_hex ( struct config_context *context,
struct config_setting *setting,
char *buf, size_t len ) {
struct dhcp_option *option;
int used = 0;
int i;

option = find_dhcp_option ( context->options, setting->tag );
if ( ! option )
return -ENODATA;

for ( i = 0 ; i < option->len ; i++ ) {
used += ssnprintf ( ( buf + used ), ( len - used ),
"%s%02x", ( used ? ":" : "" ),
option->data.bytes[i] );
}
return used;
}

/** A hex-string configuration setting */
struct config_setting_type config_setting_type_hex __config_setting_type = {
.name = "hex",
.description = "Hex string",
.show = show_hex,
.set = set_hex,
};

/** Some basic setting definitions */
struct config_setting basic_config_settings[] __config_setting = {
{
Expand Down

0 comments on commit e2613e8

Please sign in to comment.