Ryan O'Leary has uploaded this change for review.

View Change

Match -c parameter against patterns in chip names

This includes patterns such as "EN29GL064H/L", "Am29F002(N)BB" and
"A25LQ032/A25LQ32A".

This was inspired by a breakage in one of my scripts. The script
hard-coded "-c CHIPX". When upstream changed the chip name to
"CHIPX/CHIPY", my script broke. By recognizing this pattern, the -c
parameter is more resilient to these types of changes.

Since an exact match on the whole name takes priority (the current
behavior), this should not break anyone's workflow.

Change-Id: Iae00bb1108f2d5a0c10977cff63f9348b9fc017f
Signed-off-by: Ryan O'Leary <ryanoleary@google.com>
---
M cli_classic.c
1 file changed, 69 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/23/37723/1
diff --git a/cli_classic.c b/cli_classic.c
index 73cc417..43aac0b 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -103,6 +103,68 @@
return 0;
}

+/*
+ * Return 1 if the chip name matches the pattern, otherwise 0.
+ *
+ * The pattern may be:
+ * 1. A single slash followed by a single character.
+ * Ex: "EN29GL064H/L" matches "EN29GL064H" and "EN29GL064L".
+ * 2. One character in parens.
+ * Ex: "Am29F002(N)BB" matches "Am29F002BB" and "Am29F002NBB".
+ * Ex: "EN29F002(A)(N)B" matches four different chip names.
+ * 3. A slash-separated list.
+ * Ex: "A25LQ032/A25LQ32A" matches "A25LQ032" and "A25LQ32A".
+ * Ex: "MX25L12835F/MX25L12845E/MX25L12865E" matches "MX25L12835F", "MX25L12845E" and "MX25L12865E".
+ *
+ * #2 may be nested in #3, for example "W29C010(M)/W29C011A/W29EE011/W29EE012".
+ */
+static int chip_name_match_pattern(const char *pattern, const char *chip) {
+ int plen = strlen(pattern);
+ int clen = strlen(chip);
+
+ if (plen < 3 || clen < 3) {
+ return 0;
+ }
+
+ /* Single slash followed by single character. */
+ if (pattern[plen-2] == '/') {
+ for (int pidx = 0; pidx < plen - 2; pidx++)
+ if (pattern[pidx] == '/')
+ return 0;
+ return plen - 2 == clen &&
+ strncmp(pattern, chip, plen - 3) == 0 &&
+ (pattern[plen-1] == chip[clen-1] ||
+ pattern[plen-3] == chip[clen-1]);
+ }
+
+ int cidx = 0;
+ for (int pidx = 0; pidx < plen; pidx++) {
+ if (pattern[pidx] == '/') {
+ /* Check for termination. */
+ if (cidx == clen)
+ break;
+ cidx = 0; /* Reset. */
+ } else if (pattern[pidx] == '(') {
+ if (pidx + 2 >= plen ||
+ pattern[pidx+1] == ')' ||
+ pattern[pidx+1] == '(' ||
+ pattern[pidx+2] != ')')
+ return 0; /* Invalid pattern. */
+ if (pattern[pidx+1] == chip[cidx])
+ cidx++;
+ pidx += 2;
+ } else if (pattern[pidx] == chip[cidx]) {
+ cidx++;
+ } else {
+ /* Reset to next slash. */
+ while (pidx < plen && pattern[pidx] != '/')
+ pidx++;
+ cidx = 0;
+ }
+ }
+ return cidx == clen;
+}
+
int main(int argc, char *argv[])
{
const struct flashchip *chip = NULL;
@@ -421,15 +483,22 @@
}
/* Does a chip with the requested name exist in the flashchips array? */
if (chip_to_probe) {
+ /* First check for exact match. */
for (chip = flashchips; chip && chip->name; chip++)
if (!strcmp(chip->name, chip_to_probe))
break;
+ /* Failing that, perform a pattern match. */
+ if (!chip || !chip->name)
+ for (chip = flashchips; chip && chip->name; chip++)
+ if (chip_name_match_pattern(chip->name, chip_to_probe))
+ break;
if (!chip || !chip->name) {
msg_cerr("Error: Unknown chip '%s' specified.\n", chip_to_probe);
msg_gerr("Run flashrom -L to view the hardware supported in this flashrom version.\n");
ret = 1;
goto out;
}
+ msg_gdbg("Using chip \"%s\".\n", chip->name);
/* Keep chip around for later usage in case a forced read is requested. */
}


To view, visit change 37723. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: Iae00bb1108f2d5a0c10977cff63f9348b9fc017f
Gerrit-Change-Number: 37723
Gerrit-PatchSet: 1
Gerrit-Owner: Ryan O'Leary <ryanoleary@google.com>
Gerrit-MessageType: newchange