Home | History | Annotate | Download | only in awk
      1 # Copyright (C) 2010 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 #
     15 # A nawk/gawk script used to extract the debuggable flag from an
     16 # application's manifest (i.e. AndroidManifest.xml). Usage:
     17 #
     18 #   awk -f <this-script> AndroidManifest.xml
     19 #
     20 
     21 BEGIN {
     22     DEBUGGABLE = "";
     23     while ( xml_event() ) {
     24         # simply extract the 'android:debuggable' attribute value from
     25         # the first <manifest><application> element we find.
     26         if ( XML_TYPE == "BEGIN" && XML_TAG == "APPLICATION" &&
     27              XML_RPATH == "APPLICATION/MANIFEST/" ) {
     28             DEBUGGABLE = XML_ATTR["android:debuggable"];
     29             break;
     30         }
     31     }
     32     # ensure the value is either "true" or "false"
     33     if ( DEBUGGABLE != "true" )
     34         DEBUGGABLE = "false";
     35 
     36     print DEBUGGABLE;
     37 }
     38 
     39 #
     40 # the following is copied directly from xml.awk - see this file for
     41 # usage and implementation details.
     42 #
     43 function xml_event () {
     44     RS=">";
     45     XML_TAG=XML_TYPE="";
     46     split("", XML_ATTR);
     47     while ( 1 ) {
     48         if (_xml_closing) { # delayed direct tag closure
     49             XML_TAG = _xml_closing;
     50             XML_TYPE = "END";
     51             _xml_closing = "";
     52             _xml_exit(XML_TAG);
     53             return 1;
     54         }
     55         if (getline <= 0) return 0; # read new input line
     56         _xml_p = index($0, "<"); # get start marker
     57         if (_xml_p == 0) return 0; # end of file (or malformed input)
     58         $0 = substr($0, _xml_p) # remove anything before '<'
     59         # ignore CData / Comments / Processing instructions / Declarations
     60         if (_xml_in_section("<!\\[[Cc][Dd][Aa][Tt][Aa]\\[", "]]") ||
     61             _xml_in_section("<!--", "--") ||
     62             _xml_in_section("<\\?", "\\?") ||
     63             _xml_in_section("<!", "")) {
     64             continue;
     65         }
     66         if (substr($0, 1, 2) == "</") { # is it a closing tag ?
     67             XML_TYPE = "END";
     68             $0 = substr($0, 3);
     69         } else { # nope, it's an opening one
     70             XML_TYPE = "BEGIN";
     71             $0 = substr($0, 2);
     72         }
     73         XML_TAG = $0
     74         sub("[ \n\t/].*$", "", XML_TAG);  # extract tag name
     75         XML_TAG = toupper(XML_TAG);       # uppercase it
     76         if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ )  # validate it
     77             _xml_panic("Invalid tag name: " XML_TAG);
     78         if (XML_TYPE == "BEGIN") {  # update reverse path
     79             _xml_enter(XML_TAG);
     80         } else {
     81             _xml_exit(XML_TAG);
     82         }
     83         sub("[^ \n\t]*[ \n\t]*", "", $0); # get rid of tag and spaces
     84         while ($0) { # process attributes
     85             if ($0 == "/") {  # deal with direct closing tag, e.g. </foo>
     86                 _xml_closing = XML_TAG; # record delayed tag closure.
     87                 break
     88             }
     89             _xml_attrib = $0;
     90             sub(/=.*$/,"",_xml_attrib);  # extract attribute name
     91             sub(/^[^=]*/,"",$0);         # remove it from record
     92             _xml_attrib = tolower(_xml_attrib);
     93             if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ ) # validate it
     94                 _xml_panic("Invalid attribute name: " _xml_attrib);
     95             if (substr($0,1,2) == "=\"") { # value is ="something"
     96                 _xml_value = substr($0,3);
     97                 sub(/".*$/,"",_xml_value);
     98                 sub(/^="[^"]*"/,"",$0);
     99             } else if (substr($0,1,2) == "='") { # value is ='something'
    100                 _xml_value = substr($0,3);
    101                 sub(/'.*$/,"",_xml_value);
    102                 sub(/^='[^']*'/,"",$0);
    103             } else {
    104                 _xml_panic("Invalid attribute value syntax for " _xml_attrib ": " $0);
    105             }
    106             XML_ATTR[_xml_attrib] = _xml_value;  # store attribute name/value
    107             sub(/^[ \t\n]*/,"",$0); # get rid of remaining leading spaces
    108         }
    109         return 1; # now return, XML_TYPE/TAG/ATTR/RPATH are set
    110     }
    111 }
    112 
    113 function _xml_panic (msg) {
    114     print msg > "/dev/stderr"
    115     exit(1)
    116 }
    117 
    118 function _xml_in_section (sec_begin, sec_end) {
    119     if (!match( $0, "^" sec_begin )) return 0;
    120     while (!match($0, sec_end "$")) {
    121         if (getline <= 0) _xml_panic("Unexpected EOF: " ERRNO);
    122     }
    123     return 1;
    124 }
    125 
    126 function _xml_enter (tag) {
    127     XML_RPATH = tag "/" XML_RPATH;
    128 }
    129 
    130 function _xml_exit (tag) {
    131     _xml_p = index(XML_RPATH, "/");
    132     _xml_expected = substr(XML_RPATH, 1, _xml_p-1);
    133     if (_xml_expected != XML_TAG)
    134         _xml_panic("Unexpected close tag: " XML_TAG ", expecting " _xml_expected);
    135     XML_RPATH = substr(XML_RPATH, _xml_p+1);
    136 }
    137