1 2 /****************************************************************************** 3 * $Id: add_javadoc.c 355b41831cd2685c85d1aabe5b95665a2c6e99b7 2019-06-19 17:07:04 +0200 Even Rouault $ 4 * 5 * Project: GDAL/OGR Java bindings 6 * Purpose: Add javadoc located in a special file into generated SWIG Java files 7 * Author: Even Rouault <even dot rouault at spatialys.com> 8 * 9 ******************************************************************************* 10 * Copyright (c) 2009, Even Rouault <even dot rouault at spatialys.com> 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a 13 * copy of this software and associated documentation files (the "Software"), 14 * to deal in the Software without restriction, including without limitation 15 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 16 * and/or sell copies of the Software, and to permit persons to whom the 17 * Software is furnished to do so, subject to the following conditions: 18 * 19 * The above copyright notice and this permission notice shall be included 20 * in all copies or substantial portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 28 * DEALINGS IN THE SOFTWARE. 29 *******************************************************************************/ 30 31 /* NOTE : this is really a quick and very dirty hack to put the javadoc contained */ 32 /* in a special formatted file, javadoc.java, into the SWIG generated java files */ 33 /* This program leaks memory and would crash easily on unexpected inputs */ 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 39 #define TRUE 1 40 #define FALSE 0 41 42 typedef struct 43 { 44 char* methodName; 45 char* compactMethodName; 46 char* javadoc; 47 int bUsed; 48 int bHide; 49 } JavaDocInstance; 50 51 char* stripline(char* pszBuf) 52 { 53 int i = 0; 54 while(pszBuf[i] == ' ' && pszBuf[i] != 0) 55 i ++; 56 memmove(pszBuf, pszBuf + i, strlen(pszBuf) - i + 1); 57 58 i = strlen(pszBuf) - 1; 59 while(i > 0 && (pszBuf[i] == '{' || pszBuf[i] == '\n' || pszBuf[i] == ' ')) 60 { 61 pszBuf[i] = 0; 62 i--; 63 } 64 65 return pszBuf; 66 } 67 68 /* Remove argument names from function prototype, so that we used the */ 69 /* argument names from javadoc.java instead of the ones provided by default by the */ 70 /* bindings */ 71 char* removeargnames(char* pszBuf) 72 { 73 if (strstr(pszBuf, "=")) 74 { 75 *strstr(pszBuf, "=") = 0; 76 stripline(pszBuf); 77 } 78 79 if (strstr(pszBuf, "(") == NULL) 80 return pszBuf; 81 82 //fprintf(stderr, "%s\n", pszBuf); 83 84 if (strstr(pszBuf, "{")) 85 { 86 *strstr(pszBuf, "{") = 0; 87 stripline(pszBuf); 88 } 89 else 90 { 91 int i = strstr(pszBuf, ")") - pszBuf - 1; 92 char* lastOK = strstr(pszBuf, ")"); 93 while(i>0 && pszBuf[i] == ' ') 94 i --; 95 while(i>0) 96 { 97 if (pszBuf[i] == '(') 98 break; 99 if (pszBuf[i] == ' ' || pszBuf[i] == ']') 100 { 101 if (pszBuf[i] == ' ') 102 memmove(pszBuf + i + 1, lastOK, strlen(lastOK) + 1); 103 else 104 memmove(pszBuf + i, lastOK, strlen(lastOK) + 1); 105 while(pszBuf[i] != ',' && pszBuf[i] != '(') 106 i --; 107 if (pszBuf[i] == ',') 108 lastOK = pszBuf + i; 109 else 110 break; 111 } 112 i --; 113 } 114 i = strstr(pszBuf, "(") - pszBuf; 115 while(pszBuf[i]) 116 { 117 if (pszBuf[i] == ' ') 118 memmove(pszBuf + i, pszBuf + i + 1, strlen(pszBuf + i + 1) + 1); 119 else 120 i++; 121 } 122 } 123 //fprintf(stderr, "after : %s\n", pszBuf); 124 return pszBuf; 125 } 126 127 128 int main(int argc, char* argv[]) 129 { 130 const char* patch_filename = argv[1]; 131 132 FILE* fSrc = fopen(patch_filename, "rt"); 133 FILE* fDst; 134 JavaDocInstance* instances = (JavaDocInstance*)calloc(sizeof(JavaDocInstance), 3000); 135 int nInstances = 0; 136 char szLine[256]; 137 char szClass[256]; 138 char javadoc[16384]; 139 szClass[0] = 0; 140 while(fgets(szLine, 255, fSrc)) 141 { 142 if (strstr(szLine, "/**") == NULL) continue; 143 begin: 144 strcpy(javadoc, szLine); 145 while(fgets(szLine, 255, fSrc)) 146 { 147 strcat(javadoc, szLine); 148 if (strstr(szLine, "*/")) 149 break; 150 } 151 while(fgets(szLine, 255, fSrc)) 152 { 153 if (szLine[0] == 10) 154 continue; 155 else if (strstr(szLine, "*") == NULL) 156 { 157 instances[nInstances].javadoc = strdup(javadoc); 158 159 char* pszLine = szLine; 160 if (strncmp(pszLine, "@hide ", 6) == 0) 161 { 162 instances[nInstances].bHide = 1; 163 pszLine += 6; 164 } 165 else 166 instances[nInstances].bHide = 0; 167 168 instances[nInstances].methodName = strdup(stripline(pszLine)); 169 instances[nInstances].compactMethodName = strdup(removeargnames(stripline(pszLine))); 170 nInstances++; 171 } 172 else 173 break; 174 } 175 if (strstr(szLine, "/**") != NULL) 176 goto begin; 177 } 178 //fprintf(stderr, "nInstances=%d\n", nInstances); 179 fclose(fSrc); 180 181 int i; 182 for(i=3;i<argc;i++) 183 { 184 fSrc = fopen(argv[i], "rt"); 185 if (fSrc == NULL) continue; 186 char szDstName[1024]; 187 sprintf(szDstName, "%s/%s", argv[2], argv[i]); 188 fDst = fopen(szDstName, "wt"); 189 if (fDst == NULL) continue; 190 szClass[0] = 0; 191 char szPackage[256]; 192 szPackage[0] = 0; 193 194 while(fgets(szLine, 255, fSrc)) 195 { 196 char szMethodName[1024]; 197 char* szOriLine = strdup(szLine); 198 if (strstr(szLine, "package")) 199 { 200 strcpy(szPackage, szLine); 201 } 202 else if (strstr(szLine, "public class") || strstr(szLine, "public interface")) 203 { 204 strcpy(szClass, stripline(szLine)); 205 if (strstr(szClass, "extends")) 206 { 207 *strstr(szClass, "extends") = 0; 208 stripline(szClass); 209 } 210 if (strstr(szClass, "implements")) 211 { 212 *strstr(szClass, "implements") = 0; 213 stripline(szClass); 214 } 215 if (strstr(szLine, "Driver")) 216 { 217 if (strstr(szPackage, "org.gdal.gdal")) 218 strcpy(szLine, "public class org.gdal.gdal.Driver"); 219 else 220 strcpy(szLine, "public class org.gdal.ogr.Driver"); 221 strcpy(szClass, szLine); 222 } 223 } 224 if (strstr(szLine, "synchronized ")) 225 { 226 char* c = strstr(szLine, "synchronized "); 227 *c = 0; 228 strcat(szLine, c + 13); 229 } 230 if (strstr(szLine, "public") && !strstr(szLine, "native")) 231 { 232 if (strchr(szLine, '(') && !strchr(szLine,')')) 233 { 234 strcpy(szMethodName, szLine); 235 do 236 { 237 fgets(szLine, 255, fSrc); 238 strcpy(szMethodName + strlen(szMethodName) - 1, szLine); 239 } while (!strchr(szMethodName,')')); 240 strcpy(szLine, szMethodName); 241 free(szOriLine); 242 szOriLine = strdup(szMethodName); 243 //fprintf(stderr, "%s\n", szOriLine); 244 } 245 if (strchr(szLine, '(') || strchr(szLine, '=')) 246 sprintf(szMethodName, "%s:%s", szClass, removeargnames(stripline(szLine))); 247 else 248 strcpy(szMethodName, szClass); 249 //fprintf(stderr, "%s\n", szMethodName); 250 int j; 251 for(j=0;j<nInstances;j++) 252 { 253 if (strcmp(instances[j].compactMethodName, szMethodName) == 0) 254 { 255 instances[j].bUsed = TRUE; 256 257 //fprintf(stderr, "found match for %s\n", szMethodName); 258 if (instances[j].bHide) 259 { 260 if (strstr(szLine, "final static") == NULL) 261 { 262 do 263 { 264 fgets(szLine, 255, fSrc); 265 } while (!strchr(szLine,'}')); 266 } 267 break; 268 } 269 270 fprintf(fDst, "%s", instances[j].javadoc); 271 if (strchr(szMethodName, '(')) 272 { 273 fprintf(fDst, "%s;\n", strchr(instances[j].methodName, ':')+1); 274 int nBrackets = 0; 275 int bFoundOpen = FALSE; 276 strcpy(szLine, szOriLine); 277 do 278 { 279 int j; 280 for(j=0;szLine[j];j++) 281 { 282 if (szLine[j] == '{') 283 { 284 bFoundOpen = TRUE; 285 nBrackets ++; 286 } 287 else if (szLine[j] == '}') 288 { 289 nBrackets --; 290 } 291 } 292 fgets(szLine, 255, fSrc); 293 } while(bFoundOpen == FALSE || nBrackets > 0); 294 } 295 else 296 fprintf(fDst, "%s", szOriLine); 297 break; 298 } 299 } 300 if (j == nInstances) 301 { 302 if (strstr(szOriLine, "public") && (strstr(szOriLine, "getCPtr") || strstr(szOriLine, "long cPtr"))) 303 { 304 char* c = strstr(szOriLine, "public"); 305 *c = 0; 306 fprintf(fDst, "%s private %s", szOriLine, c + 6); 307 } 308 else 309 fprintf(fDst, "%s", szOriLine); 310 } 311 } 312 else 313 fprintf(fDst, "%s", szOriLine); 314 free(szOriLine); 315 } 316 317 fclose(fSrc); 318 fclose(fDst); 319 } 320 321 int j; 322 for(j=0;j<nInstances;j++) 323 { 324 if (!instances[j].bUsed) 325 fprintf(stderr, "WARNING: did not find occurrence of %s\n", instances[j].methodName); 326 } 327 328 return 0; 329 } 330