[wireless-regdb] [PATCH] crda: simplify text parsing for country/rules

Janusz Dziedzic janusz.dziedzic at tieto.com
Mon Jun 9 00:08:45 PDT 2014


Remove strange parsers.

Signed-off-by: Janusz Dziedzic <janusz.dziedzic at tieto.com>
---
 reglib.c |  351 +++++++++++---------------------------------------------------
 1 file changed, 60 insertions(+), 291 deletions(-)

diff --git a/reglib.c b/reglib.c
index 1e57634..fbce24b 100644
--- a/reglib.c
+++ b/reglib.c
@@ -40,17 +40,6 @@
 
 int debug = 0;
 
-struct reglib_rule_parse_list {
-	int n_parsers;
-	int (*rule_parsers[])(char *line, struct ieee80211_reg_rule *reg_rule);
-};
-
-struct reglib_country_parse_list {
-	int n_parsers;
-	int (*country_parsers[])(char *line, struct ieee80211_regdomain *rd);
-};
-
-
 void *
 reglib_get_file_ptr(uint8_t *db, size_t dblen, size_t structlen, uint32_t ptr)
 {
@@ -766,204 +755,61 @@ void reglib_print_regdom(const struct ieee80211_regdomain *rd)
 
 static unsigned int reglib_parse_dfs_region(char *dfs_region)
 {
-	if (strncmp(dfs_region, "DFS-FCC", 7) == 0)
+	if (!dfs_region)
+		return REGDB_DFS_UNSET;
+
+	if (strstr(dfs_region, "DFS-FCC"))
 		return REGDB_DFS_FCC;
-	if (strncmp(dfs_region, "DFS-ETSI", 8) == 0)
+	if (strstr(dfs_region, "DFS-ETSI"))
 		return REGDB_DFS_ETSI;
-	if (strncmp(dfs_region, "DFS-JP", 6) == 0)
+	if (strstr(dfs_region, "DFS-JP"))
 		return REGDB_DFS_JP;
 	return REGDB_DFS_UNSET;
 }
 
 static uint32_t reglib_parse_rule_flag(char *flag_s)
 {
-	if (strncmp(flag_s, "NO-OFDM", 7) == 0)
-		return RRF_NO_OFDM;
-	if (strncmp(flag_s, "NO-CCK", 6) == 0)
-		return RRF_NO_CCK;
-	if (strncmp(flag_s, "NO-INDOOR", 9) == 0)
-		return RRF_NO_INDOOR;
-	if (strncmp(flag_s, "NO-OUTDOOR", 10) == 0)
-		return RRF_NO_OUTDOOR;
-	if (strncmp(flag_s, "DFS", 3) == 0)
-		return RRF_DFS;
-	if (strncmp(flag_s, "PTP-ONLY", 8) == 0)
-		return RRF_PTP_ONLY;
-	if (strncmp(flag_s, "PTMP-ONLY", 9) == 0)
-		return RRF_PTMP_ONLY;
-	if (strncmp(flag_s, "NO-IR", 5) == 0)
-		return RRF_NO_IR;
-
-	return 0;
-}
-
-static int
-reglib_parse_rule_simple(char *line, struct ieee80211_reg_rule *reg_rule)
-{
-	int hits;
-	float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
-
-	hits = sscanf(line, "\t(%f - %f @ %f), (%f)\n",
-		      &start_freq_khz,
-		      &end_freq_khz,
-		      &max_bandwidth_khz,
-		      &max_eirp);
-
-	if (hits != 4)
-		return -EINVAL;
-
-	reg_rule->freq_range.start_freq_khz =
-		REGLIB_MHZ_TO_KHZ(start_freq_khz);
-	reg_rule->freq_range.end_freq_khz =
-		REGLIB_MHZ_TO_KHZ(end_freq_khz);
-	reg_rule->freq_range.max_bandwidth_khz =
-		REGLIB_MHZ_TO_KHZ(max_bandwidth_khz);
-	reg_rule->power_rule.max_eirp =
-		REGLIB_DBM_TO_MBM(max_eirp);
-
-	reg_rule->flags = 0;
-
-	if (debug)
-		printf("reglib_parse_rule_simple(): %d line: %s", hits, line);
-
-
-	return 0;
+	uint32_t flags = 0;
+
+	if (strstr(flag_s, "NO-OFDM"))
+		flags |= RRF_NO_OFDM;
+	if (strstr(flag_s, "NO-CCK"))
+		flags |= RRF_NO_CCK;
+	if (strstr(flag_s, "NO-INDOOR"))
+		flags |= RRF_NO_INDOOR;
+	if (strstr(flag_s, "NO-OUTDOOR"))
+		flags |= RRF_NO_OUTDOOR;
+	if (strstr(flag_s, "DFS"))
+		flags |= RRF_DFS;
+	if (strstr(flag_s, "PTP-ONLY"))
+		flags |= RRF_PTP_ONLY;
+	if (strstr(flag_s, "PTMP-ONLY"))
+		flags |= RRF_PTMP_ONLY;
+	if (strstr(flag_s, "NO-IR"))
+		flags |= RRF_NO_IR;
+
+	return flags;
 }
 
-static int
-reglib_parse_rule_simple_mw(char *line, struct ieee80211_reg_rule *reg_rule)
+static int reglib_parse_rule(FILE *fp, struct ieee80211_reg_rule *reg_rule)
 {
-	int hits;
+	char line[1024];
+	char *line_p;
+	int hits, r = 0;
 	float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
-	char mw[3];
-
-	hits = sscanf(line, "\t(%f - %f @ %f), (%f %2[mW])\n",
-		      &start_freq_khz,
-		      &end_freq_khz,
-		      &max_bandwidth_khz,
-		      &max_eirp, mw);
 
-	if (hits != 4)
+	memset(line, 0, sizeof(line));
+	line_p = fgets(line, sizeof(line), fp);
+	if (line_p != line)
 		return -EINVAL;
 
-
-	reg_rule->freq_range.start_freq_khz =
-		REGLIB_MHZ_TO_KHZ(start_freq_khz);
-	reg_rule->freq_range.end_freq_khz =
-		REGLIB_MHZ_TO_KHZ(end_freq_khz);
-	reg_rule->freq_range.max_bandwidth_khz =
-		REGLIB_MHZ_TO_KHZ(max_bandwidth_khz);
-	reg_rule->power_rule.max_eirp =
-		REGLIB_MW_TO_MBM(max_eirp);
-
-	reg_rule->flags = 0;
-
-	if (debug)
-		printf("reglib_parse_rule_simple_mw(): %d line: %s",
-		       hits, line);
-
-	return 0;
-}
-
-static int
-reglib_parse_rule_args(char *line, struct ieee80211_reg_rule *reg_rule)
-{
-#define IGNORE_COMMA_OR_SPACE "%*[ ,]"
-	int hits;
-	char flag_list[9][100];
-	unsigned int i = 0;
-	float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
-
-	for (i = 0; i < 9; i++)
-		memset(flag_list[i], 0, sizeof(flag_list[i]));
-
-	hits = sscanf(line, "\t(%f - %f @ %f), (%f)"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s",
+	/* First get start, end and bandwidth */
+	hits = sscanf(line_p, "\t(%f - %f @ %f),",
 		      &start_freq_khz,
 		      &end_freq_khz,
-		      &max_bandwidth_khz,
-		      &max_eirp,
-		      flag_list[0],
-		      flag_list[1],
-		      flag_list[2],
-		      flag_list[3],
-		      flag_list[4],
-		      flag_list[5],
-		      flag_list[6],
-		      flag_list[7],
-		      flag_list[8]);
-
-	if (hits < 5)
-		return -EINVAL;
-
-	reg_rule->freq_range.start_freq_khz =
-		REGLIB_MHZ_TO_KHZ(start_freq_khz);
-	reg_rule->freq_range.end_freq_khz =
-		REGLIB_MHZ_TO_KHZ(end_freq_khz);
-	reg_rule->freq_range.max_bandwidth_khz =
-		REGLIB_MHZ_TO_KHZ(max_bandwidth_khz);
-	reg_rule->power_rule.max_eirp =
-		REGLIB_DBM_TO_MBM(max_eirp);
-
-	for (i = 0; i < 8; i++)
-		reg_rule->flags |= reglib_parse_rule_flag(flag_list[i]);
-
-	if (debug)
-		printf("reglib_parse_rule_args(): %d flags: %d, line: %s",
-		       hits, reg_rule->flags, line);
-
-	return 0;
-#undef IGNORE_COMMA_OR_SPACE
-}
-
+		      &max_bandwidth_khz);
 
-static int
-reglib_parse_rule_args_mw(char *line, struct ieee80211_reg_rule *reg_rule)
-{
-#define IGNORE_COMMA_OR_SPACE "%*[ ,]"
-	int hits;
-	char flag_list[9][100];
-	unsigned int i = 0;
-	char mw[3];
-	float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
-
-	for (i = 0; i < 9; i++)
-		memset(flag_list[i], 0, sizeof(flag_list[i]));
-
-	hits = sscanf(line, "\t(%f - %f @ %f), (%f %2[mW])"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s"
-		      IGNORE_COMMA_OR_SPACE "%s",
-		      &start_freq_khz,
-		      &end_freq_khz,
-		      &max_bandwidth_khz,
-		      &max_eirp,
-		      mw,
-		      flag_list[0],
-		      flag_list[1],
-		      flag_list[2],
-		      flag_list[3],
-		      flag_list[4],
-		      flag_list[5],
-		      flag_list[6],
-		      flag_list[7],
-		      flag_list[8]);
-
-	if (hits < 5)
+	if (hits != 3)
 		return -EINVAL;
 
 	reg_rule->freq_range.start_freq_khz =
@@ -972,60 +818,32 @@ reglib_parse_rule_args_mw(char *line, struct ieee80211_reg_rule *reg_rule)
 		REGLIB_MHZ_TO_KHZ(end_freq_khz);
 	reg_rule->freq_range.max_bandwidth_khz =
 		REGLIB_MHZ_TO_KHZ(max_bandwidth_khz);
-	reg_rule->power_rule.max_eirp =
-		REGLIB_MW_TO_MBM(max_eirp);
-
-	for (i = 0; i < 8; i++)
-		reg_rule->flags |= reglib_parse_rule_flag(flag_list[i]);
 
-	if (debug)
-		printf("reglib_parse_rule_args_mw(): %d flags: %d, line: %s",
-		       hits, reg_rule->flags, line);
-	return 0;
-#undef IGNORE_COMMA_OR_SPACE
-}
-
-static int reglib_parse_rule(FILE *fp, struct ieee80211_reg_rule *reg_rule)
-{
-	char line[1024];
-	char *line_p;
-	unsigned int i;
-	int r = 0;
-	struct reglib_rule_parse_list *reglib_rule_parsers;
-	size_t size_parsers = sizeof(struct reglib_rule_parse_list) + 
-				4 * sizeof(int (*)(char *, struct ieee80211_reg_rule *));
-
-	reglib_rule_parsers = malloc(size_parsers);
-	if (!reglib_rule_parsers)
-		return -EINVAL;
-	memset(reglib_rule_parsers, 0, size_parsers);
-
-	reglib_rule_parsers->n_parsers = 4;
-
-	/*
-	 * XXX: sscanf() is a bit odd with picking up mW
-	 * case over the simple one, this order however works,
-	 * gotta figure out how to be more precise.
-	 */
-	reglib_rule_parsers->rule_parsers[0] = reglib_parse_rule_args_mw;
-	reglib_rule_parsers->rule_parsers[1] = reglib_parse_rule_args;
-	reglib_rule_parsers->rule_parsers[2] = reglib_parse_rule_simple;
-	reglib_rule_parsers->rule_parsers[3] = reglib_parse_rule_simple_mw;
-
-	memset(line, 0, sizeof(line));
-	line_p = fgets(line, sizeof(line), fp);
-	if (line_p != line) {
-		free(reglib_rule_parsers);
+	/* Next get eirp */
+	strsep(&line_p, ",");
+	if (!line_p) {
+		fprintf(stderr, "not found eirp in line: %s\n", line);
 		return -EINVAL;
 	}
 
-	for (i = 0; i < reglib_rule_parsers->n_parsers; i++) {
-		r = reglib_rule_parsers->rule_parsers[i](line, reg_rule);
-		if (r == 0)
-			break;
+	if (strstr(line_p, "mW")) {
+		hits = sscanf(line_p, " (%f mW)", &max_eirp);
+		if (hits != 1)
+			return -EINVAL;
+		reg_rule->power_rule.max_eirp =
+			REGLIB_MW_TO_MBM(max_eirp);
+	} else {
+		hits = sscanf(line_p, " (%f)", &max_eirp);
+		if (hits != 1)
+			return -EINVAL;
+		reg_rule->power_rule.max_eirp =
+			REGLIB_DBM_TO_MBM(max_eirp);
 	}
 
-	free(reglib_rule_parsers);
+	/* Next get optional arguments (flags ...) */
+	strsep(&line_p, ",");
+	if (line_p)
+		reg_rule->flags = reglib_parse_rule_flag(line_p);
 
 	return r;
 }
@@ -1120,29 +938,6 @@ reglib_parse_rules(FILE *fp, struct ieee80211_regdomain *trd)
 	return rd;
 }
 
-static int
-reglib_parse_country_simple(char *line, struct ieee80211_regdomain *rd)
-{
-	char dfs_region_alpha[9];
-	char alpha2[2];
-	int hits;
-
-	memset(rd, 0, sizeof(*rd));
-	memset(alpha2, 0, sizeof(alpha2));
-	memset(dfs_region_alpha, 0, sizeof(dfs_region_alpha));
-
-	hits = sscanf(line, "country %2[a-zA-Z0-9]:",
-		      alpha2);
-
-	if (hits != 1)
-		return -EINVAL;
-
-	rd->alpha2[0] = alpha2[0];
-	rd->alpha2[1] = alpha2[1];
-
-	return 0;
-}
-
 static int reglib_parse_country_dfs(char *line, struct ieee80211_regdomain *rd)
 {
 	char dfs_region_alpha[9];
@@ -1159,10 +954,6 @@ static int reglib_parse_country_dfs(char *line, struct ieee80211_regdomain *rd)
 	if (hits <= 0)
 		return -EINVAL;
 
-	if (hits != 2)
-		return -EINVAL;
-
-
 	rd->alpha2[0] = alpha2[0];
 	rd->alpha2[1] = alpha2[1];
 	rd->dfs_region = reglib_parse_dfs_region(dfs_region_alpha);
@@ -1176,22 +967,7 @@ struct ieee80211_regdomain *__reglib_parse_country(FILE *fp)
 	struct ieee80211_regdomain tmp_rd;
 	char line[1024];
 	char *line_p;
-	unsigned int i;
 	int r = 0;
-	struct reglib_country_parse_list *reglib_country_parsers;
-	size_t size_of_parsers = sizeof(struct reglib_country_parse_list) +
-					2 * sizeof(int (*)(char *, struct ieee80211_regdomain *));
-
-	reglib_country_parsers = malloc(size_of_parsers);
-	if (!reglib_country_parsers)
-		return NULL;
-	memset(reglib_country_parsers, 0, size_of_parsers);
-
-	reglib_country_parsers->n_parsers = 2;
-	reglib_country_parsers->country_parsers[0] =
-			reglib_parse_country_dfs;
-	reglib_country_parsers->country_parsers[1] =
-			reglib_parse_country_simple;
 
 	memset(&tmp_rd, 0, sizeof(tmp_rd));
 	memset(line, 0, sizeof(line));
@@ -1199,26 +975,19 @@ struct ieee80211_regdomain *__reglib_parse_country(FILE *fp)
 	line_p = fgets(line, sizeof(line), fp);
 
 	if (line_p != line) {
-		free(reglib_country_parsers);
 		return NULL;
 	}
 
-	for (i = 0; i < reglib_country_parsers->n_parsers; i++) {
-		r = reglib_country_parsers->country_parsers[i](line, &tmp_rd);
-		if (r == 0)
-			break;
-	}
-
+	/* Country */
+	r = reglib_parse_country_dfs(line_p, &tmp_rd);
 	if (r != 0) {
 		fprintf(stderr, "Invalid country line: %s", line);
-		free(reglib_country_parsers);
 		return NULL;
 	}
 
+	/* Rules */
 	rd = reglib_parse_rules(fp, &tmp_rd);
 
-	free(reglib_country_parsers);
-
 	return rd;
 }
 
-- 
1.7.9.5




More information about the wireless-regdb mailing list