• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 value of min. SDK version from an
16# application's manifest (i.e. AndroidManifest.xml). Usage:
17#
18#   awk -f <this-script> AndroidManifest.xml
19#
20
21BEGIN {
22    MIN_SDK_VERSION = "";
23    while ( xml_event() ) {
24        # simply extract the 'android:minSdkVersion' attribute value from
25        # the first <manifest><uses-sdk> element we find.
26        if ( XML_TYPE == "BEGIN" && XML_TAG == "USES-SDK" &&
27             XML_RPATH == "USES-SDK/MANIFEST/" ) {
28            MIN_SDK_VERSION = XML_ATTR["android:minsdkversion"];
29            break;
30        }
31    }
32
33    print MIN_SDK_VERSION;
34}
35
36#
37# the following is copied directly from xml.awk - see this file for
38# usage and implementation details.
39#
40function xml_event () {
41    RS=">";
42    XML_TAG=XML_TYPE="";
43    split("", XML_ATTR);
44    while ( 1 ) {
45        if (_xml_closing) { # delayed direct tag closure
46            XML_TAG = _xml_closing;
47            XML_TYPE = "END";
48            _xml_closing = "";
49            _xml_exit(XML_TAG);
50            return 1;
51        }
52        if (getline <= 0) return 0; # read new input line
53        _xml_p = index($0, "<"); # get start marker
54        if (_xml_p == 0) return 0; # end of file (or malformed input)
55        $0 = substr($0, _xml_p) # remove anything before '<'
56        # ignore CData / Comments / Processing instructions / Declarations
57        if (_xml_in_section("<!\\[[Cc][Dd][Aa][Tt][Aa]\\[", "]]") ||
58            _xml_in_section("<!--", "--") ||
59            _xml_in_section("<\\?", "\\?") ||
60            _xml_in_section("<!", "")) {
61            continue;
62        }
63        if (substr($0, 1, 2) == "</") { # is it a closing tag ?
64            XML_TYPE = "END";
65            $0 = substr($0, 3);
66        } else { # nope, it's an opening one
67            XML_TYPE = "BEGIN";
68            $0 = substr($0, 2);
69        }
70        XML_TAG = $0
71        sub("[ \r\n\t/].*$", "", XML_TAG);  # extract tag name
72        XML_TAG = toupper(XML_TAG);       # uppercase it
73        if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ )  # validate it
74            _xml_panic("Invalid tag name: " XML_TAG);
75        if (XML_TYPE == "BEGIN") {  # update reverse path
76            _xml_enter(XML_TAG);
77        } else {
78            _xml_exit(XML_TAG);
79        }
80        sub("[^ \r\n\t]*[ \r\n\t]*", "", $0); # get rid of tag and spaces
81        while ($0) { # process attributes
82            if ($0 == "/") {  # deal with direct closing tag, e.g. </foo>
83                _xml_closing = XML_TAG; # record delayed tag closure.
84                break
85            }
86            _xml_attrib = $0;
87            sub(/=.*$/,"",_xml_attrib);  # extract attribute name
88            sub(/^[^=]*/,"",$0);         # remove it from record
89            _xml_attrib = tolower(_xml_attrib);
90            if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ ) # validate it
91                _xml_panic("Invalid attribute name: " _xml_attrib);
92            if (substr($0,1,2) == "=\"") { # value is ="something"
93                _xml_value = substr($0,3);
94                sub(/".*$/,"",_xml_value);
95                sub(/^="[^"]*"/,"",$0);
96            } else if (substr($0,1,2) == "='") { # value is ='something'
97                _xml_value = substr($0,3);
98                sub(/'.*$/,"",_xml_value);
99                sub(/^='[^']*'/,"",$0);
100            } else {
101                _xml_panic("Invalid attribute value syntax for " _xml_attrib ": " $0);
102            }
103            XML_ATTR[_xml_attrib] = _xml_value;  # store attribute name/value
104            sub(/^[ \t\r\n]*/,"",$0); # get rid of remaining leading spaces
105        }
106        return 1; # now return, XML_TYPE/TAG/ATTR/RPATH are set
107    }
108}
109
110function _xml_panic (msg) {
111    print msg > "/dev/stderr"
112    exit(1)
113}
114
115function _xml_in_section (sec_begin, sec_end) {
116    if (!match( $0, "^" sec_begin )) return 0;
117    while (!match($0, sec_end "$")) {
118        if (getline <= 0) _xml_panic("Unexpected EOF: " ERRNO);
119    }
120    return 1;
121}
122
123function _xml_enter (tag) {
124    XML_RPATH = tag "/" XML_RPATH;
125}
126
127function _xml_exit (tag) {
128    _xml_p = index(XML_RPATH, "/");
129    _xml_expected = substr(XML_RPATH, 1, _xml_p-1);
130    if (_xml_expected != XML_TAG)
131        _xml_panic("Unexpected close tag: " XML_TAG ", expecting " _xml_expected);
132    XML_RPATH = substr(XML_RPATH, _xml_p+1);
133}
134