]> granicus.if.org Git - strace/commitdiff
mpers: implement gawk 3 support
authorEugene Syromyatnikov <evgsyr@gmail.com>
Thu, 18 Jan 2018 07:49:57 +0000 (08:49 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 21 Jan 2018 01:46:04 +0000 (01:46 +0000)
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.
* NEWS: Mention it.

NEWS
mpers.awk

diff --git a/NEWS b/NEWS
index 0b30ec3206cd711ddf4c1e6ea52885cf2710b61d..148ac5b62319f3379dcf34f32bbe7eb0e3c540eb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -48,6 +48,8 @@ Noteworthy changes in release ?.?? (????-??-??)
   * Inability to configure multiple personality support on architectures where
     multiple personalities are supported leads to configuration failure during
     build now.  Use --enable-mpers=check to revert to the old behaviour.
+  * Build-time requirement for the mpers support has been lowered from gawk 4
+    to gawk 3.
 
 Noteworthy changes in release 4.20 (2017-11-13)
 ===============================================
index 9f8cb6489f0c225fd210bbf38f9b7776a703c72e..0d0ffb2ee00f0cfc09b93b00cb03a1f65fc033aa 100644 (file)
--- a/mpers.awk
+++ b/mpers.awk
 # (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_idxarray_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)