[PATCH v2] mpers: implement gawk 3 support

Eugene Syromyatnikov evgsyr at gmail.com
Sun Jan 21 21:17:07 UTC 2018


Some old systems that still make some sense to be supported have only
gawk 3, so let's support them for now.

In order to achieve that, multiple changes have been implemented:
 - Multidimensional arrays are replaced with single-dimensional ones.
   In most places it's a "][" -> ", " replacement, as awk allows some
   kind of emulation of multidimensional arrays that way, but in several
   occasions (specifically for storing name and special fields) we have
   to iterate over them later, so we store that information in
   additional arrays in order to get the keys.
 - "switch" statements are replaced with sets of "if ... else if ...
   else" statements.  This change is trivial, except we've added
   a temporary variable in what_is order to store expression value, for
   readability purposes.
 - No support for array iteration ordering.  This one is most ugly of
   them all.  Luckily, not that ugly, we've just had to process index a
   bit in order to make it lexicographically sortable and add two
   temporary arrays containing sorted indices in order to sort over them
   instead of those two arrays that we've added in order to work around
   lack of multidimensional array support.

* mpers.awk (compare_indices): Remove unused function.
(array_get, update_upper_bound, /^DW_AT_data_member_location/,
/^DW_AT_byte_size/, /^DW_AT_encoding/): Replace multidimensional array
access with comma-concatenated index.
(norm_idx): New function.
(array_seq): Replace multidimensional array access with
comma-concatenated index.  Use comma-concatenated pair of (array_idx,
"seq") in order to check presence of the item in an array.
(what_is): Add enc and i local variables.  Store the value of
array[what_idx, "encoding"] in it.  Replace "switch" statements with
sets of "if ... else if ... else" statements.  Replace multidimensional
array access with comma-concatenated index. Use for (... ; ...; ...)
iteration over aparents_keys instead of iteration over array.
(/^<[[:xdigit:]]+>/): Store idx as norm_idx(matches[2]).  Replace
multidimensional array access with comma-concatenated index.  Store an
additional flag in array_names array.
(/^DW_AT_name/): Replace multidimensional array access with
comma-concatenated index.  Add a flag to array_names for that idx.
(/^DW_AT_type/): Do not capture "0x" as a part of a group, normalise
the captured group.  Replace multidimensional array access with
comma-concatenated index.
(/^Abbrev Number:[^(]+\(DW_TAG_/): Replace multidimensional array access
with comma-concatenated index.  Store additional flags in
array_special and array_parents arrays.
(END): Remove PROCINFO["sorted_in"] setup.  Sort array_parents.  Replace
multidimensional array access with comma-concatenated index.  Iterate
over array_special to go over all the items that have "special" field.
Iterate over array_names to go over all items that have "name" field.
---
 mpers.awk | 129 +++++++++++++++++++++++++++-----------------------------------
 1 file changed, 56 insertions(+), 73 deletions(-)

diff --git a/mpers.awk b/mpers.awk
index 9f8cb64..0d0ffb2 100644
--- a/mpers.awk
+++ b/mpers.awk
@@ -27,19 +27,10 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-function compare_indices(i1, v1, i2, v2, \
-			 c1, c2)
-{
-	c1 = strtonum(sprintf("%s", i1))
-	c2 = strtonum(sprintf("%s", i2))
-	if (c1 < c2)
-		return -1
-	return (c1 != c2)
-}
 function array_get(array_idx, array_member, \
 		   array_return)
 {
-	array_return = array[array_idx][array_member]
+	array_return = array[array_idx, array_member]
 	if ("" == array_return) {
 		printf("%s: index [%s] without %s\n",
 		       FILENAME, array_idx, array_member) > "/dev/stderr"
@@ -47,12 +38,16 @@ function array_get(array_idx, array_member, \
 	}
 	return array_return
 }
+function norm_idx(idx)
+{
+	return sprintf("%016s", idx)
+}
 function array_seq(array_idx)
 {
-	if ("seq" in array[array_idx])
-		return array[array_idx]["seq"]
+	if ((array_idx, "seq") in array)
+		return array[array_idx, "seq"]
 	index_seq++
-	array[array_idx]["seq"] = index_seq
+	array[array_idx, "seq"] = index_seq
 	return index_seq
 }
 function enter(array_idx,
@@ -75,72 +70,63 @@ function leave(array_idx, to_return)
 function update_upper_bound(idx, val, \
 			    count)
 {
-	count = array[idx]["count"]
+	count = array[idx, "count"]
 	if (count == "")
 		count = 1
-	array[idx]["count"] = count * val
-	array[idx]["upper_bound"] = array[idx]["upper_bound"] "[" val "]"
+	array[idx, "count"] = count * val
+	array[idx, "upper_bound"] = array[idx, "upper_bound"] "[" val "]"
 }
 function what_is(what_idx, \
 		 item, loc_diff, location, prev_location, prev_returned_size, \
-		 special, to_return, type_idx)
+		 special, to_return, type_idx, enc, i)
 {
 	enter(what_idx)
 	special = array_get(what_idx, "special")
-	switch (special) {
-	case "base_type":
-		switch (array_get(what_idx, "encoding")) {
-		case 5: # signed
+	if (special == "base_type") {
+		enc = array_get(what_idx, "encoding")
+		if (enc == 5) { # signed
 			printf("int%s_t ",
 			       8 * array_get(what_idx, "byte_size"))
-			break
-		case 7: # unsigned
+		} else if (enc == 7) { # unsigned
 			printf("uint%s_t ",
 			       8 * array_get(what_idx, "byte_size"))
-			break
-		default: # float, signed/unsigned char
+		} else { # float, signed/unsigned char
 			printf("%s ", array_get(what_idx, "name"))
-			break
 		}
 		returned_size = array_get(what_idx, "byte_size")
-		break
-	case "enumeration_type":
+	} else if (special == "enumeration_type") {
 		returned_size = array_get(what_idx, "byte_size")
 		printf("uint%s_t ", 8 * returned_size)
-		break
-	case "pointer_type":
+	} else if (special == "pointer_type") {
 		printf("mpers_ptr_t ")
 		returned_size = array_get(what_idx, "byte_size")
-		break
-	case "array_type":
+	} else if (special == "array_type") {
 		type_idx = array_get(what_idx, "type")
 		what_is(type_idx)
-		to_return = array[what_idx]["upper_bound"]
+		to_return = array[what_idx, "upper_bound"]
 		if ("" == to_return)
 			to_return = "[0]"
-		returned_size = array[what_idx]["count"] * returned_size
+		returned_size = array[what_idx, "count"] * returned_size
 		return leave(what_idx, to_return)
-		break
-	case "structure_type":
+	} else if (special == "structure_type") {
 		print "struct {"
 		prev_location = 0
 		location = 0
 		returned_size = 0
 		prev_returned_size = 0
-		for (item in array) {
-			if ("parent" in array[item] && \
-				array_get(item, "parent") == what_idx) {
-				location = array_get(item, "location")
+		for (i = 1; i <= parents_cnt; i += 1) {
+			if (array_parents[aparents_keys[i]] == what_idx) {
+				location = array_get(aparents_keys[i], "location")
 				loc_diff = location - prev_location - \
 					prev_returned_size
 				if (loc_diff != 0) {
 					printf("unsigned char mpers_%s_%s[%s];\n",
-					       "filler", array_seq(item), loc_diff)
+					       "filler", array_seq(aparents_keys[i]), loc_diff)
 				}
 				prev_location = location
-				returned = what_is(item)
+				returned = what_is(aparents_keys[i])
 				prev_returned_size = returned_size
-				printf("%s%s;\n", array[item]["name"], returned)
+				printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
 			}
 		}
 		returned_size = array_get(what_idx, "byte_size")
@@ -150,31 +136,25 @@ function what_is(what_idx, \
 			       "end_filler", array_seq(item), loc_diff)
 		}
 		printf("} ATTRIBUTE_PACKED ")
-		break
-	case "union_type":
+	} else if (special == "union_type") {
 		print "union {"
-		for (item in array) {
-			if ("parent" in array[item] && \
-				array_get(item, "parent") == what_idx) {
-				returned = what_is(item)
-				printf("%s%s;\n", array[item]["name"], returned)
+		for (i = 1; i <= parents_cnt; i += 1) {
+			if (array_parents[aparents_keys[i]] == what_idx) {
+				returned = what_is(aparents_keys[i])
+				printf("%s%s;\n", array[aparents_keys[i], "name"], returned)
 			}
 		}
 		printf("} ")
 		returned_size = array_get(what_idx, "byte_size")
-		break
-	case "typedef":
+	} else if (special == "typedef") {
 		type_idx = array_get(what_idx, "type")
 		return leave(what_idx, what_is(type_idx))
-		break
-	case "member":
+	} else if (special == "member") {
 		type_idx = array_get(what_idx, "type")
 		return leave(what_idx, what_is(type_idx))
-		break
-	default:
+	} else {
 		type_idx = array_get(what_idx, "type")
 		what_is(type_idx)
-		break
 	}
 	return leave(what_idx, "")
 }
@@ -186,31 +166,32 @@ BEGIN {
 /^<[[:xdigit:]]+>/ {
 	match($0, /([[:alnum:]]+)><([[:alnum:]]+)/, matches)
 	level = matches[1]
-	idx = "0x" matches[2]
-	array[idx]["idx"] = idx
+	idx = norm_idx(matches[2])
+	array[idx, "idx"] = idx
 	parent[level] = idx
 }
 /^DW_AT_data_member_location/ {
 	if (!match($0, /\(DW_OP_plus_uconst:[[:space:]]+([[:digit:]]+)\)/, temparray))
 		match($0, /([[:digit:]]+)/, temparray)
-	array[idx]["location"] = temparray[1]
+	array[idx, "location"] = temparray[1]
 }
 /^DW_AT_name/ {
 	match($0, /:[[:space:]]+([[:alpha:]_][[:alnum:]_[:space:]]*)/, \
 		temparray)
-	array[idx]["name"] = temparray[1]
+	array_names[idx] = 1
+	array[idx, "name"] = temparray[1]
 }
 /^DW_AT_byte_size/ {
 	match($0, /[[:digit:]]+/, temparray)
-	array[idx]["byte_size"] = temparray[0]
+	array[idx, "byte_size"] = temparray[0]
 }
 /^DW_AT_encoding/ {
 	match($0, /[[:digit:]]+/, temparray)
-	array[idx]["encoding"] = temparray[0]
+	array[idx, "encoding"] = temparray[0]
 }
 /^DW_AT_type/ {
-	match($0, /:[[:space:]]+<(0x[[:xdigit:]]*)>$/, temparray)
-	array[idx]["type"] = temparray[1]
+	match($0, /:[[:space:]]+<0x([[:xdigit:]]*)>$/, temparray)
+	array[idx, "type"] = norm_idx(temparray[1])
 }
 /^DW_AT_upper_bound/ {
 	match($0, /[[:digit:]]+/, temparray)
@@ -223,17 +204,19 @@ BEGIN {
 /^Abbrev Number:[^(]+\(DW_TAG_/ {
 	if (match($0, /typedef|union_type|structure_type|pointer_type\
 |enumeration_type|array_type|base_type|member/, temparray)) {
-		array[idx]["special"] = temparray[0]
+		array_special[idx] = temparray[0]
+		array[idx, "special"] = temparray[0]
 		if ("pointer_type" == temparray[0])
-			array[idx]["byte_size"] = default_pointer_size
+			array[idx, "byte_size"] = default_pointer_size
 		if (level > 1 && "member" == temparray[0])
-			array[idx]["parent"] = parent[level-1]
+			array_parents[idx] = parent[level-1]
 	}
 }
 END {
-	PROCINFO["sorted_in"] = "compare_indices"
-	for (item in array) {
-		if (array[item]["special"] == "pointer_type") {
+	parents_cnt = asorti(array_parents, aparents_keys)
+
+	for (item in array_special) {
+		if (array[item, "special"] == "pointer_type") {
 			mpers_ptr_t = \
 				"uint" 8 * array_get(item, "byte_size") "_t"
 			print "#ifndef mpers_ptr_t_is_" mpers_ptr_t
@@ -243,8 +226,8 @@ END {
 			break
 		}
 	}
-	for (item in array) {
-		if (array[item]["name"] == VAR_NAME) {
+	for (item in array_names) {
+		if (array[item, "name"] == VAR_NAME) {
 			type = array_get(item, "type")
 			print "typedef"
 			what_is(type)
-- 
2.1.4





More information about the Strace-devel mailing list