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