Skip to contentSkip to conversation

cleanup mult field string handling

PATCH Applied Kay Sievers 2 participants 2 messages Mar 3, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 cleanup mult field string handling

Here I try to cleanup our various multifield iteration over the strings. Inspired by our nice list.h we now have a macro to iterate over the string and process the parts of it:
It makes the code more readable and we don't change the string while we process it like the former strsep() does.

Example:

  foreach_strpart(dev->symlink, " ", pos, len) {
  	if (strncmp(&dev->symlink[pos], find_name, len) != 0)
  		continue;

  	...
  }

For the callout part selector %c{2} we separate now not only by space but also newline and return characters, cause some programs may give multiline values back. A possible RESULT match must contain wildcards for these characters.

Also a bug in the recent udevinfo symlink query feature is fixed.

thanks,
Kay

===== namedev.c 1.121 vs edited =====

namedev.c +8 -13
@@ -214,14 +214,12 @@
 			 struct sysfs_device *sysfs_device)
 {
 	char temp[NAME_SIZE];
-	char temp1[NAME_SIZE];
 	char *tail;
 	char *pos;
-	char *pos2;
-	char *pos3;
 	char *attr;
 	int len;
 	int i;
+	int spos, slen;
 	char c;
 	struct sysfs_attribute *tmpattr;
 
@@ -278,20 +276,17 @@
 			if (attr != NULL)
 				i = atoi(attr);
 			if (i > 0) {
-				strfieldcpy(temp1, udev->program_result);
-				pos2 = temp1;
-				while (i) {
+				foreach_strpart(udev->program_result, " \n\r", spos, slen) {
 					i--;
-					pos3 = strsep(&pos2, " ");
-					if (pos3 == NULL) {
-						dbg("requested part of result string not found");
+					if (i == 0)
 						break;
-					}
 				}
-				if (pos3) {
-					strnfieldcat(string, pos3, maxsize);
-					dbg("substitute part of result string '%s'", pos3);
+				if (i > 0) {
+					dbg("requested part of result string not found");
+					break;
 				}
+				strnfieldcat(string, udev->program_result + spos, slen+1);
+				dbg("substitute part of result string '%s'", pos);
 			} else {
 				strnfieldcat(string, udev->program_result, maxsize);
 				dbg("substitute result string '%s'", udev->program_result);

===== udev-add.c 1.57 vs edited =====

udev-add.c +37 -43

100 lines not on this page · raw message

===== udev-remove.c 1.22 vs edited =====

udev-remove.c +20 -26

60 lines not on this page · raw message

===== udev.h 1.48 vs edited =====

udev.h +6 -0
@@ -97,6 +97,12 @@
 	snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \
 } while (0)
 
+#define foreach_strpart(str, separator, pos, len) \
+	for(pos = 0, len = strcspn(str, separator); \
+	    (pos) < strlen(str); \
+	    pos = pos + (len) + 1, len = strcspn((str) + pos, separator)) \
+		if (len > 0)
+
 static inline char *get_action(void)
 {
 	char *action;

===== udevdb.c 1.24 vs edited =====

udevdb.c +14 -15
@@ -179,7 +179,8 @@
 
 static int find_device_by_name(char *path, struct udevice *dev)
 {
-	int l, i, j;
+	int pos, len;
+
 	if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) {
 		memcpy(find_dev, dev, sizeof(struct udevice));
 		strnfieldcpy(find_path, path, NAME_SIZE);
@@ -188,20 +189,18 @@
 		return 1;
 	}
 	/* look for matching symlink*/
-	l = strlen(dev->symlink);
-	if (!l)
-		return 0;
-	i = j = 0;
-	do {
-		j = strcspn(&dev->symlink[i], " ");
-		if (j && strncmp(&dev->symlink[i], find_name, j) == 0) {
-			memcpy(find_dev, dev, sizeof(struct udevice));
-			strnfieldcpy(find_path, path, NAME_SIZE);
-			find_found = 1;
-			return 1;
-		}
-		i = i + j + 1;
-	} while (i < l);
+	foreach_strpart(dev->symlink, " ", pos, len) {
+		if (strncmp(&dev->symlink[pos], find_name, len) != 0)
+			continue;
+
+		if (len != strlen(find_name))
+			continue;
+
+		memcpy(find_dev, dev, sizeof(struct udevice));
+		strnfieldcpy(find_path, path, NAME_SIZE);
+		find_found = 1;
+		return 1;
+	}
 	return 0;
 }
 

===== udevinfo.8 1.7 vs edited =====

udevinfo.8 +2 -0
@@ -35,6 +35,8 @@
 .TP
 .BI \-n " name"
 Specify the name of the node or the symlink for the device to query.
+Partition names generated with the NAME{all_partitons} option can not be
+queried, the main device must be used instead.
 .TP
 .B \-a
 Print all
Applied
#1 lore raw
Quoted 6 lines · Kay Sievers

Here I try to cleanup our various multifield iteration over the strings. Inspired by our nice list.h we now have a macro to iterate over the string and process the parts of it:
It makes the code more readable and we don't change the string while we process it like the former strsep() does.

Quoted 8 lines

Example:

  foreach_strpart(dev->symlink, " ", pos, len) {
  	if (strncmp(&dev->symlink[pos], find_name, len) != 0)
  		continue;

  	...
  }

Ah, much saner, very nice.

Applied, thanks.

greg k-h

-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now. Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id56&alloc_id438&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel