1# Copyright 2020 gRPC authors. 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# the spaces in the parameter list are necessary to separate out local variables 16function sed_gensub(regexp, replacement, how, target, cmd_, ret_) { # arguments and local variables 17 if (!target) { 18 target = $0 19 } 20 gsub(/'/, "'\"'\"'", target); 21 gsub(/\\\\/, "\\", regexp); 22 23 cmd_ = "printf '" target "' | sed -nE 's/" regexp "/" replacement "/" tolower(how) "p'"; 24 if (cmd_ | getline ret_ != 1) { 25 close(cmd_); 26 error = "ERROR: running command: " cmd_ ", ret_: " ret_; 27 exit; 28 } 29 close(cmd_); 30 return ret_; 31} 32 33BEGIN { 34 namespace = "Grpc"; 35 className = ""; 36 classDocComment = ""; 37 38 delete methodNames; # i => methodName 39 delete methodArgs; # methodName => concatenatedArgsStr 40 delete methodDocs; # methodName => methodDocCommentStr 41 delete methodStatics; # methodName => 1 if static 42 methodsCount = 0; 43 44 delete constantNames; # i => constantName 45 delete constantDocs; # constantName => constantDocCommentStr 46 constantsCount = 0; 47 48 # * class className 49 classLineRegex = "^ \\* class ([^ \t]+)$"; 50 # @param type name [= default] 51 paramLineRegex = "^.*@param[ \t]+[^ \t]+[ \t]+(\\$[^ \t]+([ \t]+=[ \t]+[^ \t]+)?)[ \t]+.*$"; 52 # PHP_METHOD(class, function) 53 phpMethodLineRegex = "^PHP_METHOD\\(([^ \t]+),[ \t]*([^ \t]+)\\).*$"; 54 55 # PHP_ME(class, function, arginfo, flags) 56 phpMeLineRegex = "^[ \t]*PHP_ME\\(([^ \t]+),[ \t]*([^ \t]+),.*$"; 57 58 # REGISTER_LONG_CONSTANT("namespace\\constant", grpcConstant, ..) 59 phpConstantLineRegs = "^[ \t]*REGISTER_LONG_CONSTANT\\(\"Grpc\\\\\\\\([^ \t]+)\",.*$"; 60 61 error = ""; 62 63 # extension testing methods 64 hideMethods["Channel::getChannelInfo"] = 1; 65 hideMethods["Channel::cleanPersistentList"] = 1; 66 hideMethods["Channel::getPersistentList"] = 1; 67} 68 69# '/**' document comment start 70/^[ \t]*\/\*\*/ { 71 inDocComment = 1; 72 docComment = ""; 73 delete args; 74 argsCount = 0; 75} 76 77# collect document comment 78inDocComment==1 { 79 docComment = docComment"\n"$0 80} 81 82# class document, must match ' * class <clasName>' 83inDocComment==1 && $0 ~ classLineRegex { 84 className = sed_gensub(classLineRegex, "\\1", "g"); 85} 86 87# end of class document 88inDocComment==1 && /\*\// && className && classDocComment == "" { 89 classDocComment = docComment; 90 docComment = ""; 91} 92 93# param line 94inDocComment==1 && $0 ~ paramLineRegex { 95 arg = sed_gensub(paramLineRegex, "\\1", "g"); 96 args[argsCount++]=arg; 97} 98 99# '*/' document comment end 100inDocComment==1 && /\*\// { 101 inDocComment = 0; 102} 103 104# PHP_METHOD 105$0 ~ phpMethodLineRegex { 106 class = sed_gensub(phpMethodLineRegex, "\\1", "g"); 107 if (class != className) { 108 error = "ERROR: Missing or mismatch class names, in class comment block: " \ 109 className ", in PHP_METHOD: " class; 110 exit; 111 }; 112 113 method = sed_gensub(phpMethodLineRegex, "\\2", "g"); 114 methodNames[methodsCount++] = method; 115 methodDocs[method] = docComment; 116 117 # concat args 118 if (argsCount > 0) { 119 methodArgs[method] = args[0]; 120 for (i = 1; i < argsCount; i++) { 121 methodArgs[method] = methodArgs[method] ", " args[i]; 122 } 123 } 124 125 docComment = ""; 126} 127 128# PHP_ME(class, function,... 129$0 ~ phpMeLineRegex { 130 inPhpMe = 1; 131 132 class = sed_gensub(phpMeLineRegex, "\\1", "g"); 133 if (class != className) { 134 error = "ERROR: Missing or mismatch class names, in class comment block: " \ 135 className ", in PHP_ME: " class; 136 exit; 137 }; 138 method = sed_gensub(phpMeLineRegex, "\\2", "g"); 139} 140 141# ZEND_ACC_STATIC 142inPhpMe && /ZEND_ACC_STATIC/ { 143 methodStatics[method] = 1; 144} 145 146# closing bracet of PHP_ME(...) 147iinPhpMe && /\)$/ { 148 inPhpMe = 0; 149} 150 151# REGISTER_LONG_CONSTANT(constant, ... 152$0 ~ phpConstantLineRegs { 153 inPhpConstant = 1; 154 constant = sed_gensub(phpConstantLineRegs, "\\1", "g"); 155 constantNames[constantsCount++] = constant; 156 constantDocs[constant] = docComment; 157} 158 159# closing bracet of REGISTER_LONG_CONSTANT(...) 160inPhpConstant && /\)[ \t]*;[ \t]*$/ { 161 inPhpConstant = 0; 162 docComment = ""; 163} 164 165END { 166 if (error) { 167 print error > "/dev/stderr"; 168 exit 1; 169 } 170 171 print "<?php\n" 172 print "namespace " namespace "{"; 173 174 if (className != "") { 175 print classDocComment 176 print "class " className " {"; 177 for (i = 0; i < methodsCount; i++) { 178 m = methodNames[i]; 179 if (hideMethods[className"::"m]) continue; 180 181 print methodDocs[m]; 182 printf "public" 183 if (methodStatics[m]) printf " static" 184 printf " function " m "(" 185 printf methodArgs[m]; 186 print ") {}"; 187 } 188 print "\n}"; 189 } 190 191 for (i = 0; i < constantsCount; i++) { 192 print constantDocs[constantNames[i]]; 193 print "const " constantNames[i] " = 0;"; 194 } 195 196 print "\n}"; 197} 198