Re: [ipxe-devel] [PATCH ipxe v2 3/4] [uuid] parse uuid

2017-01-22 Thread Michael Brown

On 20/01/17 18:29, David Decotigny wrote:

  src/core/settings.c   | 28 ++
  src/core/uuid.c   | 60 +++
  src/include/ipxe/uuid.h   |  1 +
  src/tests/settings_test.c |  4 


This would add a reasonable amount of extra code to the standard ROM 
builds, which I don't think can easily be justified by the benefit.


You can work around the absence of parse_uuid_setting() by setting 
uuid:hexraw, e.g.


  set uuid:hexraw 1a6a749d0eda461aa87a7cfe4fca4a57

One possible option would be to allow hex_decode() to treat the 
separator character as optional, and then treat :uuid as a variation on 
:hexhyp for parsing purposes.


Another potential problem is that there is no universal agreement on the 
endianness of UUIDs.  I suspect that the use of :hexraw might be the 
cleanest overall solution.


Thanks,

Michael
___
ipxe-devel mailing list
ipxe-devel@lists.ipxe.org
https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel


[ipxe-devel] [PATCH ipxe v2 3/4] [uuid] parse uuid

2017-01-20 Thread David Decotigny
Tested:
  valgrind ./tap.linux --settings uuid=$(uuidgen) ...


---
 src/core/settings.c   | 28 ++
 src/core/uuid.c   | 60 +++
 src/include/ipxe/uuid.h   |  1 +
 src/tests/settings_test.c |  4 
 4 files changed, 93 insertions(+)

diff --git a/src/core/settings.c b/src/core/settings.c
index b4ccedf..5db73b8 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -2200,6 +2200,33 @@ const struct setting_type setting_type_base64 
__setting_type = {
 };
 
 /**
+ * Parse UUID setting value (canonical form)
+ *
+ * @v type Setting type
+ * @v valueFormatted setting value
+ * @v buf  Buffer to contain raw value
+ * @v len  Length of buffer
+ * @ret lenLength of raw value, or negative error
+ */
+static int parse_uuid_setting ( const struct setting_type *type __unused,
+const char *value, void *buf, size_t len )
+{
+   union uuid * result = ( union uuid * ) buf;
+
+   if ( !len && !buf ) {
+   return sizeof( *result );
+   } else if ( len != sizeof( *result ) ) {
+   return -EINVAL;
+   }
+
+   if ( uuid_aton(result, value) ) {
+   return -EINVAL;
+   }
+
+   return len;
+}
+
+/**
  * Format UUID setting value
  *
  * @v type Setting type
@@ -2225,6 +2252,7 @@ static int format_uuid_setting ( const struct 
setting_type *type __unused,
 /** UUID setting type */
 const struct setting_type setting_type_uuid __setting_type = {
.name = "uuid",
+   .parse = parse_uuid_setting,
.format = format_uuid_setting,
 };
 
diff --git a/src/core/uuid.c b/src/core/uuid.c
index c43d421..1c0f2a5 100644
--- a/src/core/uuid.c
+++ b/src/core/uuid.c
@@ -53,3 +53,63 @@ const char * uuid_ntoa ( const union uuid *uuid ) {
  uuid->canonical.e[4], uuid->canonical.e[5] );
return buf;
 }
+
+
+/**
+ * Parse UUID from formatted string
+ *
+ * @v suuidUUID in canonical form (expecting the trailing \0)
+ * @ret string UUID
+ */
+int uuid_aton ( union uuid * uuid, const char * s ) {
+   static const char pattern[] = "----";
+   uint8_t s_idx, nibble_idx;
+
+   if ( !s || !uuid ) {
+   return -1;
+   }
+
+   for ( s_idx = nibble_idx = 0 ;
+ *s && ( s_idx < ( sizeof(pattern) - 1 ) ) ;
+ ++s, ++s_idx ) {
+   uint8_t * uuid_byte = & uuid->raw[ nibble_idx >> 1 ];
+
+   if ( pattern[s_idx] != '0' ) {
+   /* we were expecting a separator */
+   if ( *s != pattern[s_idx] ) {
+   return -1;
+   }
+
+   /* skip to next input char */
+   continue;
+   }
+
+   /* code below is assuming clean roll-over with the
+* shift operator, ie. for any initial value of uint8_t x,
+* { x <<= 4 ; x <<= 4 } leads to x == 0
+*/
+   ( *uuid_byte ) <<= 4;
+   if ( ( *s >= '0' ) && ( *s <= '9' ) ) {
+   ( *uuid_byte ) |= ( *s - '0' );
+   } else if ( ( *s >= 'a' ) && ( *s <= 'f' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'a' ) );
+   } else if ( ( *s >= 'A' ) && ( *s <= 'F' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'A' ) );
+   } else {
+   return -1;
+   }
+   nibble_idx ++;
+   }
+
+   if ( *s ) {
+   /* chars remaining after UUID string */
+   return -1;
+   }
+
+   if ( s_idx != ( sizeof( pattern ) - 1 ) ) {
+   /* UUID string was too short */
+   return -1;
+   }
+
+   return 0;
+}
diff --git a/src/include/ipxe/uuid.h b/src/include/ipxe/uuid.h
index 24c46ac..75f9b78 100644
--- a/src/include/ipxe/uuid.h
+++ b/src/include/ipxe/uuid.h
@@ -48,5 +48,6 @@ static inline void uuid_mangle ( union uuid *uuid ) {
 }
 
 extern const char * uuid_ntoa ( const union uuid *uuid );
+extern int uuid_aton ( union uuid * uuid, const char * s );
 
 #endif /* _IPXE_UUID_H */
diff --git a/src/tests/settings_test.c b/src/tests/settings_test.c
index 828901b..fab8a15 100644
--- a/src/tests/settings_test.c
+++ b/src/tests/settings_test.c
@@ -415,6 +415,10 @@ static void settings_test_exec ( void ) {
"gIGCg4QA/w==" );
 
/* "uuid" setting type (no store capability) */
+   storef_ok ( &test_settings, &test_uuid_setting,
+   "1a6a749d-0eda-461a-a87a-7cfe4fca4a57",
+   RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
+ 0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ) );
fetchf_ok ( &test_settings, &test_uuid_setting,
RAW ( 0x1a, 0x6a, 0x74, 0x9d,

[ipxe-devel] [PATCH ipxe v2 3/4] [uuid] parse uuid

2016-12-20 Thread David Decotigny
Tested:
  valgrind ./tap.linux --settings uuid=$(uuidgen) ...


---
 src/core/settings.c   | 28 ++
 src/core/uuid.c   | 60 +++
 src/include/ipxe/uuid.h   |  1 +
 src/tests/settings_test.c |  4 
 4 files changed, 93 insertions(+)

diff --git a/src/core/settings.c b/src/core/settings.c
index b4ccedf..5db73b8 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -2200,6 +2200,33 @@ const struct setting_type setting_type_base64 
__setting_type = {
 };
 
 /**
+ * Parse UUID setting value (canonical form)
+ *
+ * @v type Setting type
+ * @v valueFormatted setting value
+ * @v buf  Buffer to contain raw value
+ * @v len  Length of buffer
+ * @ret lenLength of raw value, or negative error
+ */
+static int parse_uuid_setting ( const struct setting_type *type __unused,
+const char *value, void *buf, size_t len )
+{
+   union uuid * result = ( union uuid * ) buf;
+
+   if ( !len && !buf ) {
+   return sizeof( *result );
+   } else if ( len != sizeof( *result ) ) {
+   return -EINVAL;
+   }
+
+   if ( uuid_aton(result, value) ) {
+   return -EINVAL;
+   }
+
+   return len;
+}
+
+/**
  * Format UUID setting value
  *
  * @v type Setting type
@@ -2225,6 +2252,7 @@ static int format_uuid_setting ( const struct 
setting_type *type __unused,
 /** UUID setting type */
 const struct setting_type setting_type_uuid __setting_type = {
.name = "uuid",
+   .parse = parse_uuid_setting,
.format = format_uuid_setting,
 };
 
diff --git a/src/core/uuid.c b/src/core/uuid.c
index c43d421..1c0f2a5 100644
--- a/src/core/uuid.c
+++ b/src/core/uuid.c
@@ -53,3 +53,63 @@ const char * uuid_ntoa ( const union uuid *uuid ) {
  uuid->canonical.e[4], uuid->canonical.e[5] );
return buf;
 }
+
+
+/**
+ * Parse UUID from formatted string
+ *
+ * @v suuidUUID in canonical form (expecting the trailing \0)
+ * @ret string UUID
+ */
+int uuid_aton ( union uuid * uuid, const char * s ) {
+   static const char pattern[] = "----";
+   uint8_t s_idx, nibble_idx;
+
+   if ( !s || !uuid ) {
+   return -1;
+   }
+
+   for ( s_idx = nibble_idx = 0 ;
+ *s && ( s_idx < ( sizeof(pattern) - 1 ) ) ;
+ ++s, ++s_idx ) {
+   uint8_t * uuid_byte = & uuid->raw[ nibble_idx >> 1 ];
+
+   if ( pattern[s_idx] != '0' ) {
+   /* we were expecting a separator */
+   if ( *s != pattern[s_idx] ) {
+   return -1;
+   }
+
+   /* skip to next input char */
+   continue;
+   }
+
+   /* code below is assuming clean roll-over with the
+* shift operator, ie. for any initial value of uint8_t x,
+* { x <<= 4 ; x <<= 4 } leads to x == 0
+*/
+   ( *uuid_byte ) <<= 4;
+   if ( ( *s >= '0' ) && ( *s <= '9' ) ) {
+   ( *uuid_byte ) |= ( *s - '0' );
+   } else if ( ( *s >= 'a' ) && ( *s <= 'f' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'a' ) );
+   } else if ( ( *s >= 'A' ) && ( *s <= 'F' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'A' ) );
+   } else {
+   return -1;
+   }
+   nibble_idx ++;
+   }
+
+   if ( *s ) {
+   /* chars remaining after UUID string */
+   return -1;
+   }
+
+   if ( s_idx != ( sizeof( pattern ) - 1 ) ) {
+   /* UUID string was too short */
+   return -1;
+   }
+
+   return 0;
+}
diff --git a/src/include/ipxe/uuid.h b/src/include/ipxe/uuid.h
index 24c46ac..75f9b78 100644
--- a/src/include/ipxe/uuid.h
+++ b/src/include/ipxe/uuid.h
@@ -48,5 +48,6 @@ static inline void uuid_mangle ( union uuid *uuid ) {
 }
 
 extern const char * uuid_ntoa ( const union uuid *uuid );
+extern int uuid_aton ( union uuid * uuid, const char * s );
 
 #endif /* _IPXE_UUID_H */
diff --git a/src/tests/settings_test.c b/src/tests/settings_test.c
index 828901b..fab8a15 100644
--- a/src/tests/settings_test.c
+++ b/src/tests/settings_test.c
@@ -415,6 +415,10 @@ static void settings_test_exec ( void ) {
"gIGCg4QA/w==" );
 
/* "uuid" setting type (no store capability) */
+   storef_ok ( &test_settings, &test_uuid_setting,
+   "1a6a749d-0eda-461a-a87a-7cfe4fca4a57",
+   RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
+ 0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ) );
fetchf_ok ( &test_settings, &test_uuid_setting,
RAW ( 0x1a, 0x6a, 0x74, 0x9d,

[ipxe-devel] [PATCH ipxe v2 3/4] [uuid] parse uuid

2016-12-05 Thread David Decotigny
Tested:
  valgrind ./tap.linux --settings uuid=$(uuidgen) ...


---
 src/core/settings.c   | 28 ++
 src/core/uuid.c   | 60 +++
 src/include/ipxe/uuid.h   |  1 +
 src/tests/settings_test.c |  4 
 4 files changed, 93 insertions(+)

diff --git a/src/core/settings.c b/src/core/settings.c
index b4ccedf..5db73b8 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -2200,6 +2200,33 @@ const struct setting_type setting_type_base64 
__setting_type = {
 };
 
 /**
+ * Parse UUID setting value (canonical form)
+ *
+ * @v type Setting type
+ * @v valueFormatted setting value
+ * @v buf  Buffer to contain raw value
+ * @v len  Length of buffer
+ * @ret lenLength of raw value, or negative error
+ */
+static int parse_uuid_setting ( const struct setting_type *type __unused,
+const char *value, void *buf, size_t len )
+{
+   union uuid * result = ( union uuid * ) buf;
+
+   if ( !len && !buf ) {
+   return sizeof( *result );
+   } else if ( len != sizeof( *result ) ) {
+   return -EINVAL;
+   }
+
+   if ( uuid_aton(result, value) ) {
+   return -EINVAL;
+   }
+
+   return len;
+}
+
+/**
  * Format UUID setting value
  *
  * @v type Setting type
@@ -2225,6 +2252,7 @@ static int format_uuid_setting ( const struct 
setting_type *type __unused,
 /** UUID setting type */
 const struct setting_type setting_type_uuid __setting_type = {
.name = "uuid",
+   .parse = parse_uuid_setting,
.format = format_uuid_setting,
 };
 
diff --git a/src/core/uuid.c b/src/core/uuid.c
index c43d421..1c0f2a5 100644
--- a/src/core/uuid.c
+++ b/src/core/uuid.c
@@ -53,3 +53,63 @@ const char * uuid_ntoa ( const union uuid *uuid ) {
  uuid->canonical.e[4], uuid->canonical.e[5] );
return buf;
 }
+
+
+/**
+ * Parse UUID from formatted string
+ *
+ * @v suuidUUID in canonical form (expecting the trailing \0)
+ * @ret string UUID
+ */
+int uuid_aton ( union uuid * uuid, const char * s ) {
+   static const char pattern[] = "----";
+   uint8_t s_idx, nibble_idx;
+
+   if ( !s || !uuid ) {
+   return -1;
+   }
+
+   for ( s_idx = nibble_idx = 0 ;
+ *s && ( s_idx < ( sizeof(pattern) - 1 ) ) ;
+ ++s, ++s_idx ) {
+   uint8_t * uuid_byte = & uuid->raw[ nibble_idx >> 1 ];
+
+   if ( pattern[s_idx] != '0' ) {
+   /* we were expecting a separator */
+   if ( *s != pattern[s_idx] ) {
+   return -1;
+   }
+
+   /* skip to next input char */
+   continue;
+   }
+
+   /* code below is assuming clean roll-over with the
+* shift operator, ie. for any initial value of uint8_t x,
+* { x <<= 4 ; x <<= 4 } leads to x == 0
+*/
+   ( *uuid_byte ) <<= 4;
+   if ( ( *s >= '0' ) && ( *s <= '9' ) ) {
+   ( *uuid_byte ) |= ( *s - '0' );
+   } else if ( ( *s >= 'a' ) && ( *s <= 'f' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'a' ) );
+   } else if ( ( *s >= 'A' ) && ( *s <= 'F' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'A' ) );
+   } else {
+   return -1;
+   }
+   nibble_idx ++;
+   }
+
+   if ( *s ) {
+   /* chars remaining after UUID string */
+   return -1;
+   }
+
+   if ( s_idx != ( sizeof( pattern ) - 1 ) ) {
+   /* UUID string was too short */
+   return -1;
+   }
+
+   return 0;
+}
diff --git a/src/include/ipxe/uuid.h b/src/include/ipxe/uuid.h
index 24c46ac..75f9b78 100644
--- a/src/include/ipxe/uuid.h
+++ b/src/include/ipxe/uuid.h
@@ -48,5 +48,6 @@ static inline void uuid_mangle ( union uuid *uuid ) {
 }
 
 extern const char * uuid_ntoa ( const union uuid *uuid );
+extern int uuid_aton ( union uuid * uuid, const char * s );
 
 #endif /* _IPXE_UUID_H */
diff --git a/src/tests/settings_test.c b/src/tests/settings_test.c
index 828901b..fab8a15 100644
--- a/src/tests/settings_test.c
+++ b/src/tests/settings_test.c
@@ -415,6 +415,10 @@ static void settings_test_exec ( void ) {
"gIGCg4QA/w==" );
 
/* "uuid" setting type (no store capability) */
+   storef_ok ( &test_settings, &test_uuid_setting,
+   "1a6a749d-0eda-461a-a87a-7cfe4fca4a57",
+   RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
+ 0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ) );
fetchf_ok ( &test_settings, &test_uuid_setting,
RAW ( 0x1a, 0x6a, 0x74, 0x9d,

[ipxe-devel] [PATCH ipxe v2 3/4] [uuid] parse uuid

2016-11-14 Thread David Decotigny
Tested:
  valgrind ./tap.linux --settings uuid=$(uuidgen) ...


---
 src/core/settings.c   | 28 ++
 src/core/uuid.c   | 60 +++
 src/include/ipxe/uuid.h   |  1 +
 src/tests/settings_test.c |  4 
 4 files changed, 93 insertions(+)

diff --git a/src/core/settings.c b/src/core/settings.c
index b4ccedf..5db73b8 100644
--- a/src/core/settings.c
+++ b/src/core/settings.c
@@ -2200,6 +2200,33 @@ const struct setting_type setting_type_base64 
__setting_type = {
 };
 
 /**
+ * Parse UUID setting value (canonical form)
+ *
+ * @v type Setting type
+ * @v valueFormatted setting value
+ * @v buf  Buffer to contain raw value
+ * @v len  Length of buffer
+ * @ret lenLength of raw value, or negative error
+ */
+static int parse_uuid_setting ( const struct setting_type *type __unused,
+const char *value, void *buf, size_t len )
+{
+   union uuid * result = ( union uuid * ) buf;
+
+   if ( !len && !buf ) {
+   return sizeof( *result );
+   } else if ( len != sizeof( *result ) ) {
+   return -EINVAL;
+   }
+
+   if ( uuid_aton(result, value) ) {
+   return -EINVAL;
+   }
+
+   return len;
+}
+
+/**
  * Format UUID setting value
  *
  * @v type Setting type
@@ -2225,6 +2252,7 @@ static int format_uuid_setting ( const struct 
setting_type *type __unused,
 /** UUID setting type */
 const struct setting_type setting_type_uuid __setting_type = {
.name = "uuid",
+   .parse = parse_uuid_setting,
.format = format_uuid_setting,
 };
 
diff --git a/src/core/uuid.c b/src/core/uuid.c
index c43d421..1c0f2a5 100644
--- a/src/core/uuid.c
+++ b/src/core/uuid.c
@@ -53,3 +53,63 @@ const char * uuid_ntoa ( const union uuid *uuid ) {
  uuid->canonical.e[4], uuid->canonical.e[5] );
return buf;
 }
+
+
+/**
+ * Parse UUID from formatted string
+ *
+ * @v suuidUUID in canonical form (expecting the trailing \0)
+ * @ret string UUID
+ */
+int uuid_aton ( union uuid * uuid, const char * s ) {
+   static const char pattern[] = "----";
+   uint8_t s_idx, nibble_idx;
+
+   if ( !s || !uuid ) {
+   return -1;
+   }
+
+   for ( s_idx = nibble_idx = 0 ;
+ *s && ( s_idx < ( sizeof(pattern) - 1 ) ) ;
+ ++s, ++s_idx ) {
+   uint8_t * uuid_byte = & uuid->raw[ nibble_idx >> 1 ];
+
+   if ( pattern[s_idx] != '0' ) {
+   /* we were expecting a separator */
+   if ( *s != pattern[s_idx] ) {
+   return -1;
+   }
+
+   /* skip to next input char */
+   continue;
+   }
+
+   /* code below is assuming clean roll-over with the
+* shift operator, ie. for any initial value of uint8_t x,
+* { x <<= 4 ; x <<= 4 } leads to x == 0
+*/
+   ( *uuid_byte ) <<= 4;
+   if ( ( *s >= '0' ) && ( *s <= '9' ) ) {
+   ( *uuid_byte ) |= ( *s - '0' );
+   } else if ( ( *s >= 'a' ) && ( *s <= 'f' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'a' ) );
+   } else if ( ( *s >= 'A' ) && ( *s <= 'F' ) ) {
+   ( *uuid_byte ) |= ( 0xa + ( *s - 'A' ) );
+   } else {
+   return -1;
+   }
+   nibble_idx ++;
+   }
+
+   if ( *s ) {
+   /* chars remaining after UUID string */
+   return -1;
+   }
+
+   if ( s_idx != ( sizeof( pattern ) - 1 ) ) {
+   /* UUID string was too short */
+   return -1;
+   }
+
+   return 0;
+}
diff --git a/src/include/ipxe/uuid.h b/src/include/ipxe/uuid.h
index 24c46ac..75f9b78 100644
--- a/src/include/ipxe/uuid.h
+++ b/src/include/ipxe/uuid.h
@@ -48,5 +48,6 @@ static inline void uuid_mangle ( union uuid *uuid ) {
 }
 
 extern const char * uuid_ntoa ( const union uuid *uuid );
+extern int uuid_aton ( union uuid * uuid, const char * s );
 
 #endif /* _IPXE_UUID_H */
diff --git a/src/tests/settings_test.c b/src/tests/settings_test.c
index 828901b..fab8a15 100644
--- a/src/tests/settings_test.c
+++ b/src/tests/settings_test.c
@@ -415,6 +415,10 @@ static void settings_test_exec ( void ) {
"gIGCg4QA/w==" );
 
/* "uuid" setting type (no store capability) */
+   storef_ok ( &test_settings, &test_uuid_setting,
+   "1a6a749d-0eda-461a-a87a-7cfe4fca4a57",
+   RAW ( 0x1a, 0x6a, 0x74, 0x9d, 0x0e, 0xda, 0x46, 0x1a,0xa8,
+ 0x7a, 0x7c, 0xfe, 0x4f, 0xca, 0x4a, 0x57 ) );
fetchf_ok ( &test_settings, &test_uuid_setting,
RAW ( 0x1a, 0x6a, 0x74, 0x9d,