Browse Source

[settings] Introduce the generalised concept of a numeric setting

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
c70d4cb1b3
4 changed files with 542 additions and 183 deletions
  1. 1
    1
      src/arch/i386/interface/vmware/guestinfo.c
  2. 412
    175
      src/core/settings.c
  3. 40
    5
      src/include/ipxe/settings.h
  4. 89
    2
      src/tests/settings_test.c

+ 1
- 1
src/arch/i386/interface/vmware/guestinfo.c View File

114
 		settings, &command[9] /* Skip "info-get " */, info );
114
 		settings, &command[9] /* Skip "info-get " */, info );
115
 
115
 
116
 	/* Parse GuestInfo value according to type */
116
 	/* Parse GuestInfo value according to type */
117
-	ret = type->parse ( info, data, len );
117
+	ret = setting_parse ( type, info, data, len );
118
 	if ( ret < 0 ) {
118
 	if ( ret < 0 ) {
119
 		DBGC ( settings, "GuestInfo %p could not parse \"%s\" as %s: "
119
 		DBGC ( settings, "GuestInfo %p could not parse \"%s\" as %s: "
120
 		       "%s\n", settings, info, type->name, strerror ( ret ) );
120
 		       "%s\n", settings, info, type->name, strerror ( ret ) );

+ 412
- 175
src/core/settings.c View File

850
 /**
850
 /**
851
  * Extract numeric value of setting
851
  * Extract numeric value of setting
852
  *
852
  *
853
+ * @v is_signed		Treat value as a signed integer
853
  * @v raw		Raw setting data
854
  * @v raw		Raw setting data
854
  * @v len		Length of raw setting data
855
  * @v len		Length of raw setting data
855
- * @ret signed_value	Value, when interpreted as a signed integer
856
- * @ret unsigned_value	Value, when interpreted as an unsigned integer
856
+ * @ret value		Numeric value
857
  * @ret len		Length of setting, or negative error
857
  * @ret len		Length of setting, or negative error
858
  */
858
  */
859
-static int numeric_setting_value ( const void *raw, size_t len,
860
-				   signed long *signed_value,
861
-				   unsigned long *unsigned_value ) {
859
+static int numeric_setting_value ( int is_signed, const void *raw, size_t len,
860
+				   unsigned long *value ) {
862
 	const uint8_t *unsigned_bytes = raw;
861
 	const uint8_t *unsigned_bytes = raw;
863
 	const int8_t *signed_bytes = raw;
862
 	const int8_t *signed_bytes = raw;
864
 	int is_negative;
863
 	int is_negative;
871
 
870
 
872
 	/* Convert to host-ordered longs */
871
 	/* Convert to host-ordered longs */
873
 	is_negative = ( len && ( signed_bytes[0] < 0 ) );
872
 	is_negative = ( len && ( signed_bytes[0] < 0 ) );
874
-	*signed_value = ( is_negative ? -1L : 0 );
875
-	*unsigned_value = 0;
873
+	*value = ( ( is_signed && is_negative ) ? -1L : 0 );
876
 	for ( i = 0 ; i < len ; i++ ) {
874
 	for ( i = 0 ; i < len ; i++ ) {
877
 		byte = unsigned_bytes[i];
875
 		byte = unsigned_bytes[i];
878
-		*signed_value = ( ( *signed_value << 8 ) | byte );
879
-		*unsigned_value = ( ( *unsigned_value << 8 ) | byte );
876
+		*value = ( ( *value << 8 ) | byte );
880
 	}
877
 	}
881
 
878
 
882
 	return len;
879
 	return len;
883
 }
880
 }
884
 
881
 
885
 /**
882
 /**
886
- * Fetch value of signed integer setting
883
+ * Fetch value of numeric setting
887
  *
884
  *
888
  * @v settings		Settings block, or NULL to search all blocks
885
  * @v settings		Settings block, or NULL to search all blocks
889
  * @v setting		Setting to fetch
886
  * @v setting		Setting to fetch
890
  * @v value		Integer value to fill in
887
  * @v value		Integer value to fill in
891
  * @ret len		Length of setting, or negative error
888
  * @ret len		Length of setting, or negative error
892
  */
889
  */
893
-int fetch_int_setting ( struct settings *settings, struct setting *setting,
894
-			long *value ) {
895
-	unsigned long dummy;
896
-	long tmp;
890
+int fetch_numeric_setting ( struct settings *settings, struct setting *setting,
891
+			    unsigned long *value, int is_signed ) {
892
+	unsigned long tmp;
897
 	int len;
893
 	int len;
898
 
894
 
899
 	/* Avoid returning uninitialised data on error */
895
 	/* Avoid returning uninitialised data on error */
905
 		return len;
901
 		return len;
906
 
902
 
907
 	/* Extract numeric value */
903
 	/* Extract numeric value */
908
-	return numeric_setting_value ( &tmp, len, value, &dummy );
904
+	return numeric_setting_value ( is_signed, &tmp, len, value );
905
+}
906
+
907
+/**
908
+ * Fetch value of signed integer setting
909
+ *
910
+ * @v settings		Settings block, or NULL to search all blocks
911
+ * @v setting		Setting to fetch
912
+ * @v value		Integer value to fill in
913
+ * @ret len		Length of setting, or negative error
914
+ */
915
+int fetch_int_setting ( struct settings *settings, struct setting *setting,
916
+			long *value ) {
917
+
918
+	return fetch_numeric_setting ( settings, setting,
919
+				       ( ( unsigned long * ) value ), 1 );
909
 }
920
 }
910
 
921
 
911
 /**
922
 /**
918
  */
929
  */
919
 int fetch_uint_setting ( struct settings *settings, struct setting *setting,
930
 int fetch_uint_setting ( struct settings *settings, struct setting *setting,
920
 			 unsigned long *value ) {
931
 			 unsigned long *value ) {
921
-	signed long dummy;
922
-	long tmp;
923
-	int len;
924
 
932
 
925
-	/* Avoid returning uninitialised data on error */
926
-	*value = 0;
927
-
928
-	/* Fetch raw (network-ordered, variable-length) setting */
929
-	len = fetch_setting ( settings, setting, &tmp, sizeof ( tmp ) );
930
-	if ( len < 0 )
931
-		return len;
932
-
933
-	/* Extract numeric value */
934
-	return numeric_setting_value ( &tmp, len, &dummy, value );
933
+	return fetch_numeric_setting ( settings, setting, value, 0 );
935
 }
934
 }
936
 
935
 
937
 /**
936
 /**
942
  * @ret value		Setting value, or zero
941
  * @ret value		Setting value, or zero
943
  */
942
  */
944
 long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
943
 long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
945
-	long value;
944
+	unsigned long value;
946
 
945
 
947
-	fetch_int_setting ( settings, setting, &value );
946
+	fetch_numeric_setting ( settings, setting, &value, 1 );
948
 	return value;
947
 	return value;
949
 }
948
 }
950
 
949
 
959
 				    struct setting *setting ) {
958
 				    struct setting *setting ) {
960
 	unsigned long value;
959
 	unsigned long value;
961
 
960
 
962
-	fetch_uint_setting ( settings, setting, &value );
961
+	fetch_numeric_setting ( settings, setting, &value, 0 );
963
 	return value;
962
 	return value;
964
 }
963
 }
965
 
964
 
1027
  ******************************************************************************
1026
  ******************************************************************************
1028
  */
1027
  */
1029
 
1028
 
1029
+/**
1030
+ * Format setting value as a string
1031
+ *
1032
+ * @v type		Setting type
1033
+ * @v raw		Raw setting value
1034
+ * @v raw_len		Length of raw setting value
1035
+ * @v buf		Buffer to contain formatted value
1036
+ * @v len		Length of buffer
1037
+ * @ret len		Length of formatted value, or negative error
1038
+ */
1039
+int setting_format ( struct setting_type *type, const void *raw,
1040
+		     size_t raw_len, char *buf, size_t len ) {
1041
+
1042
+	/* Sanity check */
1043
+	if ( ! type->format )
1044
+		return -ENOTSUP;
1045
+
1046
+	return type->format ( type, raw, raw_len, buf, len );
1047
+}
1048
+
1049
+/**
1050
+ * Parse formatted string to setting value
1051
+ *
1052
+ * @v type		Setting type
1053
+ * @v value		Formatted setting value
1054
+ * @v buf		Buffer to contain raw value
1055
+ * @v len		Length of buffer
1056
+ * @ret len		Length of raw value, or negative error
1057
+ */
1058
+int setting_parse ( struct setting_type *type, const char *value,
1059
+		    void *buf, size_t len ) {
1060
+
1061
+	/* Sanity check */
1062
+	if ( ! type->parse )
1063
+		return -ENOTSUP;
1064
+
1065
+	return type->parse ( type, value, buf, len );
1066
+}
1067
+
1068
+/**
1069
+ * Convert setting value to number
1070
+ *
1071
+ * @v type		Setting type
1072
+ * @v raw		Raw setting value
1073
+ * @v raw_len		Length of raw setting value
1074
+ * @ret value		Numeric value
1075
+ * @ret rc		Return status code
1076
+ */
1077
+int setting_numerate ( struct setting_type *type, const void *raw,
1078
+		       size_t raw_len, unsigned long *value ) {
1079
+
1080
+	/* Sanity check */
1081
+	if ( ! type->numerate )
1082
+		return -ENOTSUP;
1083
+
1084
+	return type->numerate ( type, raw, raw_len, value );
1085
+}
1086
+
1087
+/**
1088
+ * Convert number to setting value
1089
+ *
1090
+ * @v type		Setting type
1091
+ * @v value		Numeric value
1092
+ * @v buf		Buffer to contain raw value
1093
+ * @v len		Length of buffer
1094
+ * @ret len		Length of raw value, or negative error
1095
+ */
1096
+int setting_denumerate ( struct setting_type *type, unsigned long value,
1097
+			 void *buf, size_t len ) {
1098
+
1099
+	/* Sanity check */
1100
+	if ( ! type->denumerate )
1101
+		return -ENOTSUP;
1102
+
1103
+	return type->denumerate ( type, value, buf, len );
1104
+}
1105
+
1030
 /**
1106
 /**
1031
  * Fetch formatted value of setting
1107
  * Fetch formatted value of setting
1032
  *
1108
  *
1033
  * @v settings		Settings block, or NULL to search all blocks
1109
  * @v settings		Settings block, or NULL to search all blocks
1034
  * @v setting		Setting to fetch
1110
  * @v setting		Setting to fetch
1035
- * @v type		Settings type
1036
  * @v buf		Buffer to contain formatted value
1111
  * @v buf		Buffer to contain formatted value
1037
  * @v len		Length of buffer
1112
  * @v len		Length of buffer
1038
  * @ret len		Length of formatted value, or negative error
1113
  * @ret len		Length of formatted value, or negative error
1052
 
1127
 
1053
 	/* Sanity check */
1128
 	/* Sanity check */
1054
 	assert ( setting->type != NULL );
1129
 	assert ( setting->type != NULL );
1055
-	assert ( setting->type->format != NULL );
1056
 
1130
 
1057
 	/* Format setting */
1131
 	/* Format setting */
1058
-	if ( ( ret = setting->type->format ( raw, raw_len, buf, len ) ) < 0 )
1132
+	if ( ( ret = setting_format ( setting->type, raw, raw_len, buf,
1133
+				      len ) ) < 0 )
1059
 		goto err_format;
1134
 		goto err_format;
1060
 
1135
 
1061
  err_format:
1136
  err_format:
1069
  *
1144
  *
1070
  * @v settings		Settings block, or NULL to search all blocks
1145
  * @v settings		Settings block, or NULL to search all blocks
1071
  * @v setting		Setting to fetch
1146
  * @v setting		Setting to fetch
1072
- * @v type		Settings type
1073
  * @v value		Buffer to allocate and fill with formatted value
1147
  * @v value		Buffer to allocate and fill with formatted value
1074
  * @ret len		Length of formatted value, or negative error
1148
  * @ret len		Length of formatted value, or negative error
1075
  *
1149
  *
1122
 
1196
 
1123
 	/* Sanity check */
1197
 	/* Sanity check */
1124
 	assert ( setting->type != NULL );
1198
 	assert ( setting->type != NULL );
1125
-	assert ( setting->type->parse != NULL );
1126
 
1199
 
1127
 	/* Get raw value length */
1200
 	/* Get raw value length */
1128
-	raw_len = setting->type->parse ( value, NULL, 0 );
1201
+	raw_len = setting_parse ( setting->type, value, NULL, 0 );
1129
 	if ( raw_len < 0 ) {
1202
 	if ( raw_len < 0 ) {
1130
 		rc = raw_len;
1203
 		rc = raw_len;
1131
-		goto err_parse_len;
1204
+		goto err_raw_len;
1132
 	}
1205
 	}
1133
 
1206
 
1134
 	/* Allocate buffer for raw value */
1207
 	/* Allocate buffer for raw value */
1139
 	}
1212
 	}
1140
 
1213
 
1141
 	/* Parse formatted value */
1214
 	/* Parse formatted value */
1142
-	check_len = setting->type->parse ( value, raw, raw_len );
1215
+	check_len = setting_parse ( setting->type, value, raw, raw_len );
1216
+	assert ( check_len == raw_len );
1217
+
1218
+	/* Store raw value */
1219
+	if ( ( rc = store_setting ( settings, setting, raw, raw_len ) ) != 0 )
1220
+		goto err_store;
1221
+
1222
+ err_store:
1223
+	free ( raw );
1224
+ err_alloc_raw:
1225
+ err_raw_len:
1226
+	return rc;
1227
+}
1228
+
1229
+/**
1230
+ * Fetch numeric value of setting
1231
+ *
1232
+ * @v settings		Settings block, or NULL to search all blocks
1233
+ * @v setting		Setting to fetch
1234
+ * @v value		Numeric value to fill in
1235
+ * @ret rc		Return status code
1236
+ */
1237
+int fetchn_setting ( struct settings *settings, struct setting *setting,
1238
+		     unsigned long *value ) {
1239
+	void *raw;
1240
+	int raw_len;
1241
+	int rc;
1242
+
1243
+	/* Fetch raw value */
1244
+	raw_len = fetch_setting_copy ( settings, setting, &raw );
1245
+	if ( raw_len < 0 ) {
1246
+		rc = raw_len;
1247
+		goto err_fetch_copy;
1248
+	}
1249
+
1250
+	/* Sanity check */
1251
+	assert ( setting->type != NULL );
1252
+
1253
+	/* Numerate setting */
1254
+	if ( ( rc = setting_numerate ( setting->type, raw, raw_len,
1255
+				       value ) ) < 0 )
1256
+		goto err_numerate;
1257
+
1258
+ err_numerate:
1259
+	free ( raw );
1260
+ err_fetch_copy:
1261
+	return rc;
1262
+}
1263
+
1264
+/**
1265
+ * Store numeric value of setting
1266
+ *
1267
+ * @v settings		Settings block
1268
+ * @v setting		Setting
1269
+ * @v value		Numeric value
1270
+ * @ret rc		Return status code
1271
+ */
1272
+int storen_setting ( struct settings *settings, struct setting *setting,
1273
+		     unsigned long value ) {
1274
+	void *raw;
1275
+	int raw_len;
1276
+	int check_len;
1277
+	int rc;
1278
+
1279
+	/* Sanity check */
1280
+	assert ( setting->type != NULL );
1281
+
1282
+	/* Get raw value length */
1283
+	raw_len = setting_denumerate ( setting->type, value, NULL, 0 );
1284
+	if ( raw_len < 0 ) {
1285
+		rc = raw_len;
1286
+		goto err_raw_len;
1287
+	}
1288
+
1289
+	/* Allocate buffer for raw value */
1290
+	raw = malloc ( raw_len );
1291
+	if ( ! raw ) {
1292
+		rc = -ENOMEM;
1293
+		goto err_alloc_raw;
1294
+	}
1295
+
1296
+	/* Denumerate value */
1297
+	check_len = setting_denumerate ( setting->type, value, raw, raw_len );
1143
 	assert ( check_len == raw_len );
1298
 	assert ( check_len == raw_len );
1144
 
1299
 
1145
 	/* Store raw value */
1300
 	/* Store raw value */
1149
  err_store:
1304
  err_store:
1150
 	free ( raw );
1305
 	free ( raw );
1151
  err_alloc_raw:
1306
  err_alloc_raw:
1152
- err_parse_len:
1307
+ err_raw_len:
1153
 	return rc;
1308
 	return rc;
1154
 }
1309
 }
1155
 
1310
 
1326
 /**
1481
 /**
1327
  * Parse string setting value
1482
  * Parse string setting value
1328
  *
1483
  *
1484
+ * @v type		Setting type
1329
  * @v value		Formatted setting value
1485
  * @v value		Formatted setting value
1330
  * @v buf		Buffer to contain raw value
1486
  * @v buf		Buffer to contain raw value
1331
  * @v len		Length of buffer
1487
  * @v len		Length of buffer
1332
  * @ret len		Length of raw value, or negative error
1488
  * @ret len		Length of raw value, or negative error
1333
  */
1489
  */
1334
-static int parse_string_setting ( const char *value, void *buf, size_t len ) {
1490
+static int parse_string_setting ( struct setting_type *type __unused,
1491
+				  const char *value, void *buf, size_t len ) {
1335
 	size_t raw_len = strlen ( value ); /* Exclude terminating NUL */
1492
 	size_t raw_len = strlen ( value ); /* Exclude terminating NUL */
1336
 
1493
 
1337
 	/* Copy string to buffer */
1494
 	/* Copy string to buffer */
1345
 /**
1502
 /**
1346
  * Format string setting value
1503
  * Format string setting value
1347
  *
1504
  *
1505
+ * @v type		Setting type
1348
  * @v raw		Raw setting value
1506
  * @v raw		Raw setting value
1349
  * @v raw_len		Length of raw setting value
1507
  * @v raw_len		Length of raw setting value
1350
  * @v buf		Buffer to contain formatted value
1508
  * @v buf		Buffer to contain formatted value
1351
  * @v len		Length of buffer
1509
  * @v len		Length of buffer
1352
  * @ret len		Length of formatted value, or negative error
1510
  * @ret len		Length of formatted value, or negative error
1353
  */
1511
  */
1354
-static int format_string_setting ( const void *raw, size_t raw_len, char *buf,
1512
+static int format_string_setting ( struct setting_type *type __unused,
1513
+				   const void *raw, size_t raw_len, char *buf,
1355
 				   size_t len ) {
1514
 				   size_t len ) {
1356
 
1515
 
1357
 	/* Copy string to buffer, and terminate */
1516
 	/* Copy string to buffer, and terminate */
1373
 /**
1532
 /**
1374
  * Parse URI-encoded string setting value
1533
  * Parse URI-encoded string setting value
1375
  *
1534
  *
1535
+ * @v type		Setting type
1376
  * @v value		Formatted setting value
1536
  * @v value		Formatted setting value
1377
  * @v buf		Buffer to contain raw value
1537
  * @v buf		Buffer to contain raw value
1378
  * @v len		Length of buffer
1538
  * @v len		Length of buffer
1379
  * @ret len		Length of raw value, or negative error
1539
  * @ret len		Length of raw value, or negative error
1380
  */
1540
  */
1381
-static int parse_uristring_setting ( const char *value, void *buf,
1382
-				     size_t len ) {
1541
+static int parse_uristring_setting ( struct setting_type *type __unused,
1542
+				     const char *value, void *buf, size_t len ){
1383
 	char tmp[ len + 1 /* NUL */ ];
1543
 	char tmp[ len + 1 /* NUL */ ];
1384
 	size_t raw_len;
1544
 	size_t raw_len;
1385
 
1545
 
1397
 /**
1557
 /**
1398
  * Format URI-encoded string setting value
1558
  * Format URI-encoded string setting value
1399
  *
1559
  *
1560
+ * @v type		Setting type
1400
  * @v raw		Raw setting value
1561
  * @v raw		Raw setting value
1401
  * @v raw_len		Length of raw setting value
1562
  * @v raw_len		Length of raw setting value
1402
  * @v buf		Buffer to contain formatted value
1563
  * @v buf		Buffer to contain formatted value
1403
  * @v len		Length of buffer
1564
  * @v len		Length of buffer
1404
  * @ret len		Length of formatted value, or negative error
1565
  * @ret len		Length of formatted value, or negative error
1405
  */
1566
  */
1406
-static int format_uristring_setting ( const void *raw, size_t raw_len,
1567
+static int format_uristring_setting ( struct setting_type *type __unused,
1568
+				      const void *raw, size_t raw_len,
1407
 				      char *buf, size_t len ) {
1569
 				      char *buf, size_t len ) {
1408
 	char tmp[ raw_len + 1 /* NUL */ ];
1570
 	char tmp[ raw_len + 1 /* NUL */ ];
1409
 
1571
 
1425
 /**
1587
 /**
1426
  * Parse IPv4 address setting value
1588
  * Parse IPv4 address setting value
1427
  *
1589
  *
1590
+ * @v type		Setting type
1428
  * @v value		Formatted setting value
1591
  * @v value		Formatted setting value
1429
  * @v buf		Buffer to contain raw value
1592
  * @v buf		Buffer to contain raw value
1430
  * @v len		Length of buffer
1593
  * @v len		Length of buffer
1431
  * @ret len		Length of raw value, or negative error
1594
  * @ret len		Length of raw value, or negative error
1432
  */
1595
  */
1433
-static int parse_ipv4_setting ( const char *value, void *buf, size_t len ) {
1596
+static int parse_ipv4_setting ( struct setting_type *type __unused,
1597
+				const char *value, void *buf, size_t len ) {
1434
 	struct in_addr ipv4;
1598
 	struct in_addr ipv4;
1435
 
1599
 
1436
 	/* Parse IPv4 address */
1600
 	/* Parse IPv4 address */
1448
 /**
1612
 /**
1449
  * Format IPv4 address setting value
1613
  * Format IPv4 address setting value
1450
  *
1614
  *
1615
+ * @v type		Setting type
1451
  * @v raw		Raw setting value
1616
  * @v raw		Raw setting value
1452
  * @v raw_len		Length of raw setting value
1617
  * @v raw_len		Length of raw setting value
1453
  * @v buf		Buffer to contain formatted value
1618
  * @v buf		Buffer to contain formatted value
1454
  * @v len		Length of buffer
1619
  * @v len		Length of buffer
1455
  * @ret len		Length of formatted value, or negative error
1620
  * @ret len		Length of formatted value, or negative error
1456
  */
1621
  */
1457
-static int format_ipv4_setting ( const void *raw, size_t raw_len, char *buf,
1622
+static int format_ipv4_setting ( struct setting_type *type __unused,
1623
+				 const void *raw, size_t raw_len, char *buf,
1458
 				 size_t len ) {
1624
 				 size_t len ) {
1459
 	const struct in_addr *ipv4 = raw;
1625
 	const struct in_addr *ipv4 = raw;
1460
 
1626
 
1471
 };
1637
 };
1472
 
1638
 
1473
 /**
1639
 /**
1474
- * Parse integer setting value
1640
+ * Integer setting type indices
1475
  *
1641
  *
1476
- * @v value		Formatted setting value
1642
+ * These indexes are defined such that (1<<index) gives the width of
1643
+ * the integer, in bytes.
1644
+ */
1645
+enum setting_type_int_index {
1646
+	SETTING_TYPE_INT8 = 0,
1647
+	SETTING_TYPE_INT16 = 1,
1648
+	SETTING_TYPE_INT32 = 2,
1649
+};
1650
+
1651
+/**
1652
+ * Integer setting type names
1653
+ *
1654
+ * These names exist as a static array in order to allow the type's
1655
+ * integer size and signedness to be determined from the type's name.
1656
+ * Note that there are no separate entries for the signed integer
1657
+ * types: the name pointers simply point to the second character of
1658
+ * the relevant string.
1659
+ */
1660
+static const char setting_type_int_name[][8] = {
1661
+	[SETTING_TYPE_INT8] = "uint8",
1662
+	[SETTING_TYPE_INT16] = "uint16",
1663
+	[SETTING_TYPE_INT32] = "uint32",
1664
+};
1665
+
1666
+/**
1667
+ * Get unsigned integer setting type name
1668
+ *
1669
+ * @v index		Integer setting type index
1670
+ * @ret name		Setting type name
1671
+ */
1672
+#define SETTING_TYPE_UINT_NAME( index ) setting_type_int_name[index]
1673
+
1674
+/**
1675
+ * Get signed integer setting type name
1676
+ *
1677
+ * @v index		Integer setting type index
1678
+ * @ret name		Setting type name
1679
+ */
1680
+#define SETTING_TYPE_INT_NAME( index ) ( setting_type_int_name[index] + 1 )
1681
+
1682
+/**
1683
+ * Get integer setting type index
1684
+ *
1685
+ * @v type		Setting type
1686
+ * @ret index		Integer setting type index
1687
+ */
1688
+static unsigned int setting_type_int_index ( struct setting_type *type ) {
1689
+
1690
+	return ( ( type->name - setting_type_int_name[0] ) /
1691
+		 sizeof ( setting_type_int_name[0] ) );
1692
+}
1693
+
1694
+/**
1695
+ * Get integer setting type width
1696
+ *
1697
+ * @v type		Setting type
1698
+ * @ret index		Integer setting type width
1699
+ */
1700
+static unsigned int setting_type_int_width ( struct setting_type *type ) {
1701
+
1702
+	return ( 1 << setting_type_int_index ( type ) );
1703
+}
1704
+
1705
+/**
1706
+ * Get integer setting type signedness
1707
+ *
1708
+ * @v type		Setting type
1709
+ * @ret is_signed	Integer setting type is signed
1710
+ */
1711
+static int setting_type_int_is_signed ( struct setting_type *type ) {
1712
+	return ( ( type->name - setting_type_int_name[0] ) & 1 );
1713
+}
1714
+
1715
+/**
1716
+ * Convert number to setting value
1717
+ *
1718
+ * @v type		Setting type
1719
+ * @v value		Numeric value
1477
  * @v buf		Buffer to contain raw value
1720
  * @v buf		Buffer to contain raw value
1478
  * @v len		Length of buffer
1721
  * @v len		Length of buffer
1479
- * @v size		Integer size, in bytes
1480
  * @ret len		Length of raw value, or negative error
1722
  * @ret len		Length of raw value, or negative error
1481
  */
1723
  */
1482
-static int parse_int_setting ( const char *value, void *buf, size_t len,
1483
-			       unsigned int size ) {
1724
+static int denumerate_int_setting ( struct setting_type *type,
1725
+				    unsigned long value, void *buf,
1726
+				    size_t len ) {
1727
+	unsigned int size = setting_type_int_width ( type );
1484
 	union {
1728
 	union {
1485
 		uint32_t num;
1729
 		uint32_t num;
1486
 		uint8_t bytes[4];
1730
 		uint8_t bytes[4];
1487
 	} u;
1731
 	} u;
1488
-	char *endp;
1489
-
1490
-	/* Parse value */
1491
-	u.num = htonl ( strtoul ( value, &endp, 0 ) );
1492
-	if ( *endp )
1493
-		return -EINVAL;
1494
 
1732
 
1495
-	/* Copy to buffer */
1733
+	u.num = htonl ( value );
1496
 	if ( len > size )
1734
 	if ( len > size )
1497
 		len = size;
1735
 		len = size;
1498
 	memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len );
1736
 	memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len );
1501
 }
1739
 }
1502
 
1740
 
1503
 /**
1741
 /**
1504
- * Parse 8-bit integer setting value
1742
+ * Convert setting value to number
1505
  *
1743
  *
1506
- * @v value		Formatted setting value
1507
- * @v buf		Buffer to contain raw value
1508
- * @v len		Length of buffer
1509
- * @v size		Integer size, in bytes
1510
- * @ret len		Length of raw value, or negative error
1744
+ * @v type		Setting type
1745
+ * @v raw		Raw setting value
1746
+ * @v raw_len		Length of raw setting value
1747
+ * @v value		Numeric value to fill in
1748
+ * @ret rc		Return status code
1511
  */
1749
  */
1512
-static int parse_int8_setting ( const char *value, void *buf, size_t len ) {
1513
-	return parse_int_setting ( value, buf, len, sizeof ( uint8_t ) );
1514
-}
1750
+static int numerate_int_setting ( struct setting_type *type,
1751
+				  const void *raw, size_t raw_len,
1752
+				  unsigned long *value ) {
1753
+	int is_signed = setting_type_int_is_signed ( type );
1754
+	int check_len;
1515
 
1755
 
1516
-/**
1517
- * Parse 16-bit integer setting value
1518
- *
1519
- * @v value		Formatted setting value
1520
- * @v buf		Buffer to contain raw value
1521
- * @v len		Length of buffer
1522
- * @v size		Integer size, in bytes
1523
- * @ret len		Length of raw value, or negative error
1524
- */
1525
-static int parse_int16_setting ( const char *value, void *buf, size_t len ) {
1526
-	return parse_int_setting ( value, buf, len, sizeof ( uint16_t ) );
1756
+	/* Extract numeric value */
1757
+	check_len = numeric_setting_value ( is_signed, raw, raw_len, value );
1758
+	if ( check_len < 0 )
1759
+		return check_len;
1760
+	assert ( check_len == ( int ) raw_len );
1761
+
1762
+	return 0;
1527
 }
1763
 }
1528
 
1764
 
1529
 /**
1765
 /**
1530
- * Parse 32-bit integer setting value
1766
+ * Parse integer setting value
1531
  *
1767
  *
1768
+ * @v type		Setting type
1532
  * @v value		Formatted setting value
1769
  * @v value		Formatted setting value
1533
  * @v buf		Buffer to contain raw value
1770
  * @v buf		Buffer to contain raw value
1534
  * @v len		Length of buffer
1771
  * @v len		Length of buffer
1535
- * @v size		Integer size, in bytes
1536
  * @ret len		Length of raw value, or negative error
1772
  * @ret len		Length of raw value, or negative error
1537
  */
1773
  */
1538
-static int parse_int32_setting ( const char *value, void *buf, size_t len ) {
1539
-	return parse_int_setting ( value, buf, len, sizeof ( uint32_t ) );
1774
+static int parse_int_setting ( struct setting_type *type, const char *value,
1775
+			       void *buf, size_t len ) {
1776
+	char *endp;
1777
+	unsigned long num_value;
1778
+
1779
+	/* Parse value */
1780
+	num_value = strtoul ( value, &endp, 0 );
1781
+	if ( *endp )
1782
+		return -EINVAL;
1783
+
1784
+	return type->denumerate ( type, num_value, buf, len );
1540
 }
1785
 }
1541
 
1786
 
1542
 /**
1787
 /**
1543
  * Format signed integer setting value
1788
  * Format signed integer setting value
1544
  *
1789
  *
1790
+ * @v type		Setting type
1545
  * @v raw		Raw setting value
1791
  * @v raw		Raw setting value
1546
  * @v raw_len		Length of raw setting value
1792
  * @v raw_len		Length of raw setting value
1547
  * @v buf		Buffer to contain formatted value
1793
  * @v buf		Buffer to contain formatted value
1548
  * @v len		Length of buffer
1794
  * @v len		Length of buffer
1549
  * @ret len		Length of formatted value, or negative error
1795
  * @ret len		Length of formatted value, or negative error
1550
  */
1796
  */
1551
-static int format_int_setting ( const void *raw, size_t raw_len, char *buf,
1552
-				size_t len ) {
1553
-	signed long value;
1554
-	unsigned long dummy;
1555
-	int check_len;
1797
+static int format_int_setting ( struct setting_type *type, const void *raw,
1798
+				size_t raw_len, char *buf, size_t len ) {
1799
+	unsigned long value;
1800
+	int ret;
1556
 
1801
 
1557
 	/* Extract numeric value */
1802
 	/* Extract numeric value */
1558
-	check_len = numeric_setting_value ( raw, raw_len, &value, &dummy );
1559
-	if ( check_len < 0 )
1560
-		return check_len;
1561
-	assert ( check_len == ( int ) raw_len );
1803
+	if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1804
+		return ret;
1562
 
1805
 
1563
 	/* Format value */
1806
 	/* Format value */
1564
 	return snprintf ( buf, len, "%ld", value );
1807
 	return snprintf ( buf, len, "%ld", value );
1567
 /**
1810
 /**
1568
  * Format unsigned integer setting value
1811
  * Format unsigned integer setting value
1569
  *
1812
  *
1813
+ * @v type		Setting type
1570
  * @v raw		Raw setting value
1814
  * @v raw		Raw setting value
1571
  * @v raw_len		Length of raw setting value
1815
  * @v raw_len		Length of raw setting value
1572
  * @v buf		Buffer to contain formatted value
1816
  * @v buf		Buffer to contain formatted value
1573
  * @v len		Length of buffer
1817
  * @v len		Length of buffer
1574
  * @ret len		Length of formatted value, or negative error
1818
  * @ret len		Length of formatted value, or negative error
1575
  */
1819
  */
1576
-static int format_uint_setting ( const void *raw, size_t raw_len, char *buf,
1577
-				 size_t len ) {
1578
-	signed long dummy;
1820
+static int format_uint_setting ( struct setting_type *type, const void *raw,
1821
+				 size_t raw_len, char *buf, size_t len ) {
1579
 	unsigned long value;
1822
 	unsigned long value;
1580
-	int check_len;
1823
+	int ret;
1581
 
1824
 
1582
 	/* Extract numeric value */
1825
 	/* Extract numeric value */
1583
-	check_len = numeric_setting_value ( raw, raw_len, &dummy, &value );
1584
-	if ( check_len < 0 )
1585
-		return check_len;
1586
-	assert ( check_len == ( int ) raw_len );
1826
+	if ( ( ret = type->numerate ( type, raw, raw_len, &value ) ) < 0 )
1827
+		return ret;
1587
 
1828
 
1588
 	/* Format value */
1829
 	/* Format value */
1589
 	return snprintf ( buf, len, "%#lx", value );
1830
 	return snprintf ( buf, len, "%#lx", value );
1590
 }
1831
 }
1591
 
1832
 
1833
+/**
1834
+ * Define a signed integer setting type
1835
+ *
1836
+ * @v index		Integer setting type index
1837
+ * @ret type		Setting type
1838
+ */
1839
+#define SETTING_TYPE_INT( index ) {				\
1840
+	.name = SETTING_TYPE_INT_NAME ( index ),		\
1841
+	.parse = parse_int_setting,				\
1842
+	.format = format_int_setting,				\
1843
+	.denumerate = denumerate_int_setting,			\
1844
+	.numerate = numerate_int_setting,			\
1845
+}
1846
+
1847
+/**
1848
+ * Define an unsigned integer setting type
1849
+ *
1850
+ * @v index		Integer setting type index
1851
+ * @ret type		Setting type
1852
+ */
1853
+#define SETTING_TYPE_UINT( index ) {				\
1854
+	.name = SETTING_TYPE_UINT_NAME ( index ),		\
1855
+	.parse = parse_int_setting,				\
1856
+	.format = format_uint_setting,				\
1857
+	.denumerate = denumerate_int_setting,			\
1858
+	.numerate = numerate_int_setting,			\
1859
+}
1860
+
1592
 /** A signed 8-bit integer setting type */
1861
 /** A signed 8-bit integer setting type */
1593
-struct setting_type setting_type_int8 __setting_type = {
1594
-	.name = "int8",
1595
-	.parse = parse_int8_setting,
1596
-	.format = format_int_setting,
1597
-};
1862
+struct setting_type setting_type_int8 __setting_type =
1863
+	SETTING_TYPE_INT ( SETTING_TYPE_INT8 );
1598
 
1864
 
1599
 /** A signed 16-bit integer setting type */
1865
 /** A signed 16-bit integer setting type */
1600
-struct setting_type setting_type_int16 __setting_type = {
1601
-	.name = "int16",
1602
-	.parse = parse_int16_setting,
1603
-	.format = format_int_setting,
1604
-};
1866
+struct setting_type setting_type_int16 __setting_type =
1867
+	SETTING_TYPE_INT ( SETTING_TYPE_INT16 );
1605
 
1868
 
1606
 /** A signed 32-bit integer setting type */
1869
 /** A signed 32-bit integer setting type */
1607
-struct setting_type setting_type_int32 __setting_type = {
1608
-	.name = "int32",
1609
-	.parse = parse_int32_setting,
1610
-	.format = format_int_setting,
1611
-};
1870
+struct setting_type setting_type_int32 __setting_type =
1871
+	SETTING_TYPE_INT ( SETTING_TYPE_INT32 );
1612
 
1872
 
1613
 /** An unsigned 8-bit integer setting type */
1873
 /** An unsigned 8-bit integer setting type */
1614
-struct setting_type setting_type_uint8 __setting_type = {
1615
-	.name = "uint8",
1616
-	.parse = parse_int8_setting,
1617
-	.format = format_uint_setting,
1618
-};
1874
+struct setting_type setting_type_uint8 __setting_type =
1875
+	SETTING_TYPE_UINT ( SETTING_TYPE_INT8 );
1619
 
1876
 
1620
 /** An unsigned 16-bit integer setting type */
1877
 /** An unsigned 16-bit integer setting type */
1621
-struct setting_type setting_type_uint16 __setting_type = {
1622
-	.name = "uint16",
1623
-	.parse = parse_int16_setting,
1624
-	.format = format_uint_setting,
1625
-};
1878
+struct setting_type setting_type_uint16 __setting_type =
1879
+	SETTING_TYPE_UINT ( SETTING_TYPE_INT16 );
1626
 
1880
 
1627
 /** An unsigned 32-bit integer setting type */
1881
 /** An unsigned 32-bit integer setting type */
1628
-struct setting_type setting_type_uint32 __setting_type = {
1629
-	.name = "uint32",
1630
-	.parse = parse_int32_setting,
1631
-	.format = format_uint_setting,
1632
-};
1882
+struct setting_type setting_type_uint32 __setting_type =
1883
+	SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
1633
 
1884
 
1634
 /**
1885
 /**
1635
  * Format hex string setting value
1886
  * Format hex string setting value
1636
  *
1887
  *
1888
+ * @v delimiter		Byte delimiter
1637
  * @v raw		Raw setting value
1889
  * @v raw		Raw setting value
1638
  * @v raw_len		Length of raw setting value
1890
  * @v raw_len		Length of raw setting value
1639
  * @v buf		Buffer to contain formatted value
1891
  * @v buf		Buffer to contain formatted value
1640
  * @v len		Length of buffer
1892
  * @v len		Length of buffer
1641
- * @v delimiter		Byte delimiter
1642
  * @ret len		Length of formatted value, or negative error
1893
  * @ret len		Length of formatted value, or negative error
1643
  */
1894
  */
1644
-static int format_hex_setting ( const void *raw, size_t raw_len, char *buf,
1645
-				size_t len, const char *delimiter ) {
1895
+static int format_hex_setting ( const char *delimiter, const void *raw,
1896
+				size_t raw_len, char *buf, size_t len ) {
1646
 	const uint8_t *bytes = raw;
1897
 	const uint8_t *bytes = raw;
1647
 	int used = 0;
1898
 	int used = 0;
1648
 	unsigned int i;
1899
 	unsigned int i;
1660
 /**
1911
 /**
1661
  * Parse hex string setting value (using colon delimiter)
1912
  * Parse hex string setting value (using colon delimiter)
1662
  *
1913
  *
1914
+ * @v type		Setting type
1663
  * @v value		Formatted setting value
1915
  * @v value		Formatted setting value
1664
  * @v buf		Buffer to contain raw value
1916
  * @v buf		Buffer to contain raw value
1665
  * @v len		Length of buffer
1917
  * @v len		Length of buffer
1666
  * @v size		Integer size, in bytes
1918
  * @v size		Integer size, in bytes
1667
  * @ret len		Length of raw value, or negative error
1919
  * @ret len		Length of raw value, or negative error
1668
  */
1920
  */
1669
-static int parse_hex_setting ( const char *value, void *buf, size_t len ) {
1921
+static int parse_hex_setting ( struct setting_type *type __unused,
1922
+			       const char *value, void *buf, size_t len ) {
1670
 	return hex_decode ( value, ':', buf, len );
1923
 	return hex_decode ( value, ':', buf, len );
1671
 }
1924
 }
1672
 
1925
 
1673
 /**
1926
 /**
1674
  * Format hex string setting value (using colon delimiter)
1927
  * Format hex string setting value (using colon delimiter)
1675
  *
1928
  *
1929
+ * @v type		Setting type
1676
  * @v raw		Raw setting value
1930
  * @v raw		Raw setting value
1677
  * @v raw_len		Length of raw setting value
1931
  * @v raw_len		Length of raw setting value
1678
  * @v buf		Buffer to contain formatted value
1932
  * @v buf		Buffer to contain formatted value
1679
  * @v len		Length of buffer
1933
  * @v len		Length of buffer
1680
  * @ret len		Length of formatted value, or negative error
1934
  * @ret len		Length of formatted value, or negative error
1681
  */
1935
  */
1682
-static int format_hex_colon_setting ( const void *raw, size_t raw_len,
1936
+static int format_hex_colon_setting ( struct setting_type *type __unused,
1937
+				      const void *raw, size_t raw_len,
1683
 				      char *buf, size_t len ) {
1938
 				      char *buf, size_t len ) {
1684
-	return format_hex_setting ( raw, raw_len, buf, len, ":" );
1939
+	return format_hex_setting ( ":", raw, raw_len, buf, len );
1685
 }
1940
 }
1686
 
1941
 
1687
 /**
1942
 /**
1688
  * Parse hex string setting value (using hyphen delimiter)
1943
  * Parse hex string setting value (using hyphen delimiter)
1689
  *
1944
  *
1945
+ * @v type		Setting type
1690
  * @v value		Formatted setting value
1946
  * @v value		Formatted setting value
1691
  * @v buf		Buffer to contain raw value
1947
  * @v buf		Buffer to contain raw value
1692
  * @v len		Length of buffer
1948
  * @v len		Length of buffer
1693
  * @v size		Integer size, in bytes
1949
  * @v size		Integer size, in bytes
1694
  * @ret len		Length of raw value, or negative error
1950
  * @ret len		Length of raw value, or negative error
1695
  */
1951
  */
1696
-static int parse_hex_hyphen_setting ( const char *value, void *buf,
1952
+static int parse_hex_hyphen_setting ( struct setting_type *type __unused,
1953
+				      const char *value, void *buf,
1697
 				      size_t len ) {
1954
 				      size_t len ) {
1698
 	return hex_decode ( value, '-', buf, len );
1955
 	return hex_decode ( value, '-', buf, len );
1699
 }
1956
 }
1701
 /**
1958
 /**
1702
  * Format hex string setting value (using hyphen delimiter)
1959
  * Format hex string setting value (using hyphen delimiter)
1703
  *
1960
  *
1961
+ * @v type		Setting type
1704
  * @v raw		Raw setting value
1962
  * @v raw		Raw setting value
1705
  * @v raw_len		Length of raw setting value
1963
  * @v raw_len		Length of raw setting value
1706
  * @v buf		Buffer to contain formatted value
1964
  * @v buf		Buffer to contain formatted value
1707
  * @v len		Length of buffer
1965
  * @v len		Length of buffer
1708
  * @ret len		Length of formatted value, or negative error
1966
  * @ret len		Length of formatted value, or negative error
1709
  */
1967
  */
1710
-static int format_hex_hyphen_setting ( const void *raw, size_t raw_len,
1968
+static int format_hex_hyphen_setting ( struct setting_type *type __unused,
1969
+				       const void *raw, size_t raw_len,
1711
 				       char *buf, size_t len ) {
1970
 				       char *buf, size_t len ) {
1712
-	return format_hex_setting ( raw, raw_len, buf, len, "-" );
1971
+	return format_hex_setting ( "-", raw, raw_len, buf, len );
1713
 }
1972
 }
1714
 
1973
 
1715
 /**
1974
 /**
1716
  * Parse hex string setting value (using no delimiter)
1975
  * Parse hex string setting value (using no delimiter)
1717
  *
1976
  *
1977
+ * @v type		Setting type
1718
  * @v value		Formatted setting value
1978
  * @v value		Formatted setting value
1719
  * @v buf		Buffer to contain raw value
1979
  * @v buf		Buffer to contain raw value
1720
  * @v len		Length of buffer
1980
  * @v len		Length of buffer
1721
  * @v size		Integer size, in bytes
1981
  * @v size		Integer size, in bytes
1722
  * @ret len		Length of raw value, or negative error
1982
  * @ret len		Length of raw value, or negative error
1723
  */
1983
  */
1724
-static int parse_hex_raw_setting ( const char *value, void *buf,
1725
-				   size_t len ) {
1984
+static int parse_hex_raw_setting ( struct setting_type *type __unused,
1985
+				   const char *value, void *buf, size_t len ) {
1726
 	return hex_decode ( value, 0, buf, len );
1986
 	return hex_decode ( value, 0, buf, len );
1727
 }
1987
 }
1728
 
1988
 
1729
 /**
1989
 /**
1730
  * Format hex string setting value (using no delimiter)
1990
  * Format hex string setting value (using no delimiter)
1731
  *
1991
  *
1992
+ * @v type		Setting type
1732
  * @v raw		Raw setting value
1993
  * @v raw		Raw setting value
1733
  * @v raw_len		Length of raw setting value
1994
  * @v raw_len		Length of raw setting value
1734
  * @v buf		Buffer to contain formatted value
1995
  * @v buf		Buffer to contain formatted value
1735
  * @v len		Length of buffer
1996
  * @v len		Length of buffer
1736
  * @ret len		Length of formatted value, or negative error
1997
  * @ret len		Length of formatted value, or negative error
1737
  */
1998
  */
1738
-static int format_hex_raw_setting ( const void *raw, size_t raw_len,
1999
+static int format_hex_raw_setting ( struct setting_type *type __unused,
2000
+				    const void *raw, size_t raw_len,
1739
 				    char *buf, size_t len ) {
2001
 				    char *buf, size_t len ) {
1740
-	return format_hex_setting ( raw, raw_len, buf, len, "" );
2002
+	return format_hex_setting ( "", raw, raw_len, buf, len );
1741
 }
2003
 }
1742
 
2004
 
1743
 /** A hex-string setting (colon-delimited) */
2005
 /** A hex-string setting (colon-delimited) */
1761
 	.format = format_hex_raw_setting,
2023
 	.format = format_hex_raw_setting,
1762
 };
2024
 };
1763
 
2025
 
1764
-/**
1765
- * Parse UUID setting value
1766
- *
1767
- * @v value		Formatted setting value
1768
- * @v buf		Buffer to contain raw value
1769
- * @v len		Length of buffer
1770
- * @ret len		Length of raw value, or negative error
1771
- */
1772
-static int parse_uuid_setting ( const char *value __unused,
1773
-				void *buf __unused, size_t len __unused ) {
1774
-	return -ENOTSUP;
1775
-}
1776
-
1777
 /**
2026
 /**
1778
  * Format UUID setting value
2027
  * Format UUID setting value
1779
  *
2028
  *
2029
+ * @v type		Setting type
1780
  * @v raw		Raw setting value
2030
  * @v raw		Raw setting value
1781
  * @v raw_len		Length of raw setting value
2031
  * @v raw_len		Length of raw setting value
1782
  * @v buf		Buffer to contain formatted value
2032
  * @v buf		Buffer to contain formatted value
1783
  * @v len		Length of buffer
2033
  * @v len		Length of buffer
1784
  * @ret len		Length of formatted value, or negative error
2034
  * @ret len		Length of formatted value, or negative error
1785
  */
2035
  */
1786
-static int format_uuid_setting ( const void *raw, size_t raw_len, char *buf,
2036
+static int format_uuid_setting ( struct setting_type *type __unused,
2037
+				 const void *raw, size_t raw_len, char *buf,
1787
 				 size_t len ) {
2038
 				 size_t len ) {
1788
 	const union uuid *uuid = raw;
2039
 	const union uuid *uuid = raw;
1789
 
2040
 
1798
 /** UUID setting type */
2049
 /** UUID setting type */
1799
 struct setting_type setting_type_uuid __setting_type = {
2050
 struct setting_type setting_type_uuid __setting_type = {
1800
 	.name = "uuid",
2051
 	.name = "uuid",
1801
-	.parse = parse_uuid_setting,
1802
 	.format = format_uuid_setting,
2052
 	.format = format_uuid_setting,
1803
 };
2053
 };
1804
 
2054
 
1805
-/**
1806
- * Parse PCI bus:dev.fn setting value
1807
- *
1808
- * @v value		Formatted setting value
1809
- * @v buf		Buffer to contain raw value
1810
- * @v len		Length of buffer
1811
- * @ret len		Length of raw value, or negative error
1812
- */
1813
-static int parse_busdevfn_setting ( const char *value __unused,
1814
-				    void *buf __unused, size_t len __unused ) {
1815
-	return -ENOTSUP;
1816
-}
1817
-
1818
 /**
2055
 /**
1819
  * Format PCI bus:dev.fn setting value
2056
  * Format PCI bus:dev.fn setting value
1820
  *
2057
  *
2058
+ * @v type		Setting type
1821
  * @v raw		Raw setting value
2059
  * @v raw		Raw setting value
1822
  * @v raw_len		Length of raw setting value
2060
  * @v raw_len		Length of raw setting value
1823
  * @v buf		Buffer to contain formatted value
2061
  * @v buf		Buffer to contain formatted value
1824
  * @v len		Length of buffer
2062
  * @v len		Length of buffer
1825
  * @ret len		Length of formatted value, or negative error
2063
  * @ret len		Length of formatted value, or negative error
1826
  */
2064
  */
1827
-static int format_busdevfn_setting ( const void *raw, size_t raw_len, char *buf,
2065
+static int format_busdevfn_setting ( struct setting_type *type __unused,
2066
+				     const void *raw, size_t raw_len, char *buf,
1828
 				     size_t len ) {
2067
 				     size_t len ) {
1829
-	signed long dummy;
1830
 	unsigned long busdevfn;
2068
 	unsigned long busdevfn;
1831
 	int check_len;
2069
 	int check_len;
1832
 
2070
 
1833
 	/* Extract numeric value */
2071
 	/* Extract numeric value */
1834
-	check_len = numeric_setting_value ( raw, raw_len, &dummy, &busdevfn );
2072
+	check_len = numeric_setting_value ( 0, raw, raw_len, &busdevfn );
1835
 	if ( check_len < 0 )
2073
 	if ( check_len < 0 )
1836
 		return check_len;
2074
 		return check_len;
1837
 	assert ( check_len == ( int ) raw_len );
2075
 	assert ( check_len == ( int ) raw_len );
1844
 /** PCI bus:dev.fn setting type */
2082
 /** PCI bus:dev.fn setting type */
1845
 struct setting_type setting_type_busdevfn __setting_type = {
2083
 struct setting_type setting_type_busdevfn __setting_type = {
1846
 	.name = "busdevfn",
2084
 	.name = "busdevfn",
1847
-	.parse = parse_busdevfn_setting,
1848
 	.format = format_busdevfn_setting,
2085
 	.format = format_busdevfn_setting,
1849
 };
2086
 };
1850
 
2087
 

+ 40
- 5
src/include/ipxe/settings.h View File

185
 	 * This is the name exposed to the user (e.g. "string").
185
 	 * This is the name exposed to the user (e.g. "string").
186
 	 */
186
 	 */
187
 	const char *name;
187
 	const char *name;
188
-	/** Parse formatted setting value
188
+	/** Parse formatted string to setting value
189
 	 *
189
 	 *
190
+	 * @v type		Setting type
190
 	 * @v value		Formatted setting value
191
 	 * @v value		Formatted setting value
191
 	 * @v buf		Buffer to contain raw value
192
 	 * @v buf		Buffer to contain raw value
192
 	 * @v len		Length of buffer
193
 	 * @v len		Length of buffer
193
 	 * @ret len		Length of raw value, or negative error
194
 	 * @ret len		Length of raw value, or negative error
194
 	 */
195
 	 */
195
-	int ( * parse ) ( const char *value, void *buf, size_t len );
196
-	/** Format setting value
196
+	int ( * parse ) ( struct setting_type *type, const char *value,
197
+			  void *buf, size_t len );
198
+	/** Format setting value as a string
197
 	 *
199
 	 *
200
+	 * @v type		Setting type
198
 	 * @v raw		Raw setting value
201
 	 * @v raw		Raw setting value
199
 	 * @v raw_len		Length of raw setting value
202
 	 * @v raw_len		Length of raw setting value
200
 	 * @v buf		Buffer to contain formatted value
203
 	 * @v buf		Buffer to contain formatted value
201
 	 * @v len		Length of buffer
204
 	 * @v len		Length of buffer
202
 	 * @ret len		Length of formatted value, or negative error
205
 	 * @ret len		Length of formatted value, or negative error
203
 	 */
206
 	 */
204
-	int ( * format ) ( const void *raw, size_t raw_len, char *buf,
205
-			   size_t len );
207
+	int ( * format ) ( struct setting_type *type, const void *raw,
208
+			   size_t raw_len, char *buf, size_t len );
209
+	/** Convert number to setting value
210
+	 *
211
+	 * @v type		Setting type
212
+	 * @v value		Numeric value
213
+	 * @v buf		Buffer to contain raw value
214
+	 * @v len		Length of buffer
215
+	 * @ret len		Length of raw value, or negative error
216
+	 */
217
+	int ( * denumerate ) ( struct setting_type *type, unsigned long value,
218
+			       void *buf, size_t len );
219
+	/** Convert setting value to number
220
+	 *
221
+	 * @v type		Setting type
222
+	 * @v raw		Raw setting value
223
+	 * @v raw_len		Length of raw setting value
224
+	 * @v value		Numeric value to fill in
225
+	 * @ret rc		Return status code
226
+	 */
227
+	int ( * numerate ) ( struct setting_type *type, const void *raw,
228
+			     size_t raw_len, unsigned long *value );
206
 };
229
 };
207
 
230
 
208
 /** Configuration setting type table */
231
 /** Configuration setting type table */
308
 				struct setting *setting );
331
 				struct setting *setting );
309
 extern int setting_name ( struct settings *settings, struct setting *setting,
332
 extern int setting_name ( struct settings *settings, struct setting *setting,
310
 			  char *buf, size_t len );
333
 			  char *buf, size_t len );
334
+extern int setting_format ( struct setting_type *type, const void *raw,
335
+			    size_t raw_len, char *buf, size_t len );
336
+extern int setting_parse ( struct setting_type *type, const char *value,
337
+			   void *buf, size_t len );
338
+extern int setting_numerate ( struct setting_type *type, const void *raw,
339
+			      size_t raw_len, unsigned long *value );
340
+extern int setting_denumerate ( struct setting_type *type, unsigned long value,
341
+				void *buf, size_t len );
311
 extern int fetchf_setting ( struct settings *settings, struct setting *setting,
342
 extern int fetchf_setting ( struct settings *settings, struct setting *setting,
312
 			    char *buf, size_t len );
343
 			    char *buf, size_t len );
313
 extern int fetchf_setting_copy ( struct settings *settings,
344
 extern int fetchf_setting_copy ( struct settings *settings,
315
 extern int storef_setting ( struct settings *settings,
346
 extern int storef_setting ( struct settings *settings,
316
 			    struct setting *setting,
347
 			    struct setting *setting,
317
 			    const char *value );
348
 			    const char *value );
349
+extern int fetchn_setting ( struct settings *settings, struct setting *setting,
350
+			    unsigned long *value );
351
+extern int storen_setting ( struct settings *settings, struct setting *setting,
352
+			    unsigned long value );
318
 extern char * expand_settings ( const char *string );
353
 extern char * expand_settings ( const char *string );
319
 
354
 
320
 extern struct setting_type setting_type_string __setting_type;
355
 extern struct setting_type setting_type_string __setting_type;

+ 89
- 2
src/tests/settings_test.c View File

82
 	len = fetchf_setting ( settings, setting, actual,		\
82
 	len = fetchf_setting ( settings, setting, actual,		\
83
 			       sizeof ( actual ) );			\
83
 			       sizeof ( actual ) );			\
84
 	DBGC ( settings, "Fetched %s \"%s\" from:\n",			\
84
 	DBGC ( settings, "Fetched %s \"%s\" from:\n",			\
85
-	       (setting)->type->name, formatted );			\
85
+	       (setting)->type->name, actual );				\
86
 	DBGC_HDA ( settings, 0, raw, sizeof ( raw ) );			\
86
 	DBGC_HDA ( settings, 0, raw, sizeof ( raw ) );			\
87
 	ok ( len == ( int ) ( sizeof ( actual ) - 1 ) );		\
87
 	ok ( len == ( int ) ( sizeof ( actual ) - 1 ) );		\
88
 	ok ( strcmp ( actual, formatted ) == 0 );			\
88
 	ok ( strcmp ( actual, formatted ) == 0 );			\
89
 	} while ( 0 )
89
 	} while ( 0 )
90
 
90
 
91
+/**
92
+ * Report a numeric-store test result
93
+ *
94
+ * @v settings		Settings block
95
+ * @v setting		Setting
96
+ * @v numeric		Numeric value
97
+ * @v raw_array		Expected raw value
98
+ */
99
+#define storen_ok( settings, setting, numeric, raw_array ) do {		\
100
+	const uint8_t expected[] = raw_array;				\
101
+	uint8_t actual[ sizeof ( expected ) ];				\
102
+	int len;							\
103
+									\
104
+	ok ( storen_setting ( settings, setting, numeric ) == 0 );	\
105
+	len = fetch_setting ( settings, setting, actual,		\
106
+			      sizeof ( actual ) );			\
107
+	if ( len >= 0 ) {						\
108
+		DBGC ( settings, "Stored %s %#lx, got:\n",		\
109
+		       (setting)->type->name,				\
110
+		       ( unsigned long ) numeric );			\
111
+		DBGC_HDA ( settings, 0, actual, len );			\
112
+	} else {							\
113
+		DBGC ( settings, "Stored %s %#lx, got error %s\n",	\
114
+		       (setting)->type->name,				\
115
+		       ( unsigned long ) numeric, strerror ( len ) );	\
116
+	}								\
117
+	ok ( len == ( int ) sizeof ( actual ) );			\
118
+	ok ( memcmp ( actual, expected, sizeof ( actual ) ) == 0 );	\
119
+	} while ( 0 )
120
+
121
+/**
122
+ * Report a numeric-fetch test result
123
+ *
124
+ * @v settings		Settings block
125
+ * @v setting		Setting
126
+ * @v raw_array		Raw array
127
+ * @v numeric		Expected numeric value
128
+ */
129
+#define fetchn_ok( settings, setting, raw_array, numeric ) do {		\
130
+	const uint8_t raw[] = raw_array;				\
131
+	unsigned long actual;						\
132
+									\
133
+	ok ( store_setting ( settings, setting, raw,			\
134
+			     sizeof ( raw ) ) == 0 );			\
135
+	ok ( fetchn_setting ( settings, setting, &actual ) == 0 );	\
136
+	DBGC ( settings, "Fetched %s %#lx from:\n",			\
137
+	       (setting)->type->name, actual );				\
138
+	DBGC_HDA ( settings, 0, raw, sizeof ( raw ) );			\
139
+	ok ( actual == ( unsigned long ) numeric );			\
140
+	} while ( 0 )
141
+
91
 /** Test generic settings block */
142
 /** Test generic settings block */
92
 struct generic_settings test_generic_settings = {
143
 struct generic_settings test_generic_settings = {
93
 	.settings = {
144
 	.settings = {
216
 	fetchf_ok ( &test_settings, &test_ipv4_setting,
267
 	fetchf_ok ( &test_settings, &test_ipv4_setting,
217
 		    RAW ( 212, 13, 204, 60 ), "212.13.204.60" );
268
 		    RAW ( 212, 13, 204, 60 ), "212.13.204.60" );
218
 
269
 
219
-	/* Integer setting types */
270
+	/* Integer setting types (as formatted strings) */
220
 	storef_ok ( &test_settings, &test_int8_setting,
271
 	storef_ok ( &test_settings, &test_int8_setting,
221
 		    "54", RAW ( 54 ) );
272
 		    "54", RAW ( 54 ) );
222
 	storef_ok ( &test_settings, &test_int8_setting,
273
 	storef_ok ( &test_settings, &test_int8_setting,
256
 	fetchf_ok ( &test_settings, &test_uint32_setting,
307
 	fetchf_ok ( &test_settings, &test_uint32_setting,
257
 		    RAW ( 0xf2, 0x37, 0xb2, 0x18 ), "0xf237b218" );
308
 		    RAW ( 0xf2, 0x37, 0xb2, 0x18 ), "0xf237b218" );
258
 
309
 
310
+	/* Integer setting types (as numeric values) */
311
+	storen_ok ( &test_settings, &test_int8_setting,
312
+		    72, RAW ( 72 ) );
313
+	storen_ok ( &test_settings, &test_int8_setting,
314
+		    0xabcd, RAW ( 0xcd ) );
315
+	fetchn_ok ( &test_settings, &test_int8_setting,
316
+		    RAW ( 0xfe ), -2 );
317
+	storen_ok ( &test_settings, &test_uint8_setting,
318
+		    84, RAW ( 84 ) );
319
+	fetchn_ok ( &test_settings, &test_uint8_setting,
320
+		    RAW ( 0xfe ), 0xfe );
321
+	storen_ok ( &test_settings, &test_int16_setting,
322
+		    0x87bd, RAW ( 0x87, 0xbd ) );
323
+	fetchn_ok ( &test_settings, &test_int16_setting,
324
+		    RAW ( 0x3d, 0x14 ), 0x3d14 );
325
+	fetchn_ok ( &test_settings, &test_int16_setting,
326
+		    RAW ( 0x80 ), -128 );
327
+	storen_ok ( &test_settings, &test_uint16_setting,
328
+		    1, RAW ( 0x00, 0x01 ) );
329
+	fetchn_ok ( &test_settings, &test_uint16_setting,
330
+		    RAW ( 0xbd, 0x87 ), 0xbd87 );
331
+	fetchn_ok ( &test_settings, &test_uint16_setting,
332
+		    RAW ( 0x80 ), 0x0080 );
333
+	storen_ok ( &test_settings, &test_int32_setting,
334
+		    0x0812bfd2, RAW ( 0x08, 0x12, 0xbf, 0xd2 ) );
335
+	fetchn_ok ( &test_settings, &test_int32_setting,
336
+		    RAW ( 0x43, 0x87, 0x91, 0xb4 ), 0x438791b4 );
337
+	fetchn_ok ( &test_settings, &test_int32_setting,
338
+		    RAW ( 0xff, 0xff, 0xfe ), -2 );
339
+	storen_ok ( &test_settings, &test_uint32_setting,
340
+		    0xb5927ab8, RAW ( 0xb5, 0x92, 0x7a, 0xb8 ) );
341
+	fetchn_ok ( &test_settings, &test_uint32_setting,
342
+		    RAW ( 0x98, 0xab, 0x41, 0x81 ), 0x98ab4181 );
343
+	fetchn_ok ( &test_settings, &test_uint32_setting,
344
+		    RAW ( 0xff, 0xff, 0xfe ), 0x00fffffe );
345
+
259
 	/* "hex" setting type */
346
 	/* "hex" setting type */
260
 	storef_ok ( &test_settings, &test_hex_setting,
347
 	storef_ok ( &test_settings, &test_hex_setting,
261
 		    "08:12:f5:22:90:1b:4b:47:a8:30:cb:4d:67:4c:d6:76",
348
 		    "08:12:f5:22:90:1b:4b:47:a8:30:cb:4d:67:4c:d6:76",

Loading…
Cancel
Save