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