gwenhywfar  5.14.1
tm2c_tree2.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Thu Jul 02 2009
3  copyright : (C) 2025 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * Please see toplevel file COPYING for license details *
8  ***************************************************************************/
9 
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13 
14 
15 #include "tm2c_tree2.h"
16 #include "tm2c_misc.h"
17 
18 #include <gwenhywfar/debug.h>
19 
20 #include <ctype.h>
21 
22 
23 #define GBAA GWEN_Buffer_AppendArgs
24 #define GBAS GWEN_Buffer_AppendString
25 
26 
30 
34 static void _addCompareMemberProtoType(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, int ascending);
36 static void _addCompareMemberDeclaration(TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, GWEN_BUFFER *tbuf, int ascending);
37 
38 
39 
40 
42 {
43  int rv;
44 
45  _addGetByMemberProtoType(tb, ty, tm);
46  rv=_addGetByMemberImplementation(tb, ty, tm);
47  if (rv<0) {
48  DBG_INFO(NULL, "here (%d)", rv);
49  return rv;
50  }
51 
52  return 0;
53 }
54 
55 
56 
58 {
59  int rv;
60 
61  _addSortByMemberProtoType(tb, ty, tm);
62  _addCompareMemberProtoType(tb, ty, tm, 1); /* ascending */
63  _addCompareMemberProtoType(tb, ty, tm, 0); /* descending */
64 
66  rv=_addCompareMemberImplementation(tb, ty, tm, 1); /* ascending */
67  if (rv<0) {
68  DBG_INFO(NULL, "here (%d)", rv);
69  return rv;
70  }
71  rv=_addCompareMemberImplementation(tb, ty, tm, 0); /* descending */
72  if (rv<0) {
73  DBG_INFO(NULL, "here (%d)", rv);
74  return rv;
75  }
76 
77  return 0;
78 }
79 
80 
81 
83 {
84  GWEN_BUFFER *tbuf;
85  const char *s;
87  TYPEMAKER2_TYPE *mty;
88 
91  assert(mty);
92 
93  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
94 
96  if (s)
97  GBAA(tbuf, "%s ", s);
98  _addGetByMemberDeclaration(ty, tm, tbuf);
99  GBAS(tbuf, ";\n");
100 
102  GWEN_Buffer_free(tbuf);
103 }
104 
105 
106 
108 {
109  GWEN_BUFFER *tbuf;
110  TYPEMAKER2_TYPE *mty;
111  const char *sTypeId;
112  const char *sTypePrefix;
113  const char *sMemberName;
114 
116  assert(mty);
117 
118  sTypeId=Typemaker2_Type_GetIdentifier(ty);
119  sTypePrefix=Typemaker2_Type_GetPrefix(ty);
120  sMemberName=Typemaker2_Member_GetName(tm);
121 
122  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
123 
124  _addGetByMemberDeclaration(ty, tm, tbuf);
125  GBAS(tbuf, "{\n");
126 
127  GBAA(tbuf, " %s *p_struct;\n\n", sTypeId);
128  GBAS(tbuf, " assert(p_object);\n");
129  GBAA(tbuf, " p_struct = %s_Tree2_GetFirstChild(p_object);\n", sTypePrefix);
130  GBAS(tbuf, " while(p_struct) {\n");
131  GBAS(tbuf, " int p_rv;\n");
132  GBAS(tbuf, "\n");
133 
134  GBAS(tbuf, " ");
135  if (1) {
136  GWEN_BUFFER *dstbuf;
137  GWEN_BUFFER *srcbuf;
138  int rv;
139 
140  srcbuf=GWEN_Buffer_new(0, 256, 0, 1);
141  GBAS(srcbuf, "p_cmp");
142 
143  dstbuf=GWEN_Buffer_new(0, 256, 0, 1);
144  GBAA(dstbuf, "p_struct->%s", sMemberName);
145 
147  GWEN_Buffer_GetStart(srcbuf),
148  GWEN_Buffer_GetStart(dstbuf),
149  tbuf);
150  GWEN_Buffer_free(srcbuf);
151  GWEN_Buffer_free(dstbuf);
152  if (rv<0) {
153  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
154  GWEN_Buffer_free(tbuf);
155  return rv;
156  }
157  GBAS(tbuf, "\n");
158  }
159 
160 
161  GBAS(tbuf, " if (p_rv == 0)\n");
162  GBAS(tbuf, " return p_struct;\n");
163  GBAA(tbuf, " p_struct = %s_Tree2_GetBelow(p_struct);\n", sTypePrefix);
164  GBAS(tbuf, " }\n");
165 
166  GBAS(tbuf, " return NULL;\n");
167  GBAS(tbuf, "}\n");
168 
170  GWEN_Buffer_free(tbuf);
171 
172  return 0;
173 }
174 
175 
176 
178 {
179  TYPEMAKER2_TYPE *mty;
180  const char *sTypeId;
181  const char *sTypePrefix;
182  const char *sMemberName;
183  const char *sMemberTypeId;
184 
186  assert(mty);
187 
188  sTypeId=Typemaker2_Type_GetIdentifier(ty);
189  sTypePrefix=Typemaker2_Type_GetPrefix(ty);
190  sMemberName=Typemaker2_Member_GetName(tm);
191  sMemberTypeId=Typemaker2_Type_GetIdentifier(mty);
192 
193  GBAA(tbuf,
194  "%s *%s_Tree2_GetBy%c%s(const %s *p_object, ",
195  sTypeId,
196  sTypePrefix,
197  toupper(*sMemberName),
198  sMemberName+1,
199  sTypeId);
202  GBAA(tbuf, " const %s *", sMemberTypeId);
203  else
204  GBAA(tbuf, "%s ", sMemberTypeId);
205  GBAS(tbuf, "p_cmp)");
206 }
207 
208 
209 
210 
211 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
212  * sort
213  * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
214  */
215 
216 
218 {
219  GWEN_BUFFER *tbuf;
220  const char *s;
222  TYPEMAKER2_TYPE *mty;
223 
226  assert(mty);
227 
228  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
229 
231  if (s)
232  GBAA(tbuf, "%s ", s);
233  _addSortByMemberDeclaration(ty, tm, tbuf);
234  GBAS(tbuf, ";\n");
235 
237  GWEN_Buffer_free(tbuf);
238 }
239 
240 
241 
243 {
244  GWEN_BUFFER *tbuf;
245  TYPEMAKER2_TYPE *mty;
246  const char *sTypePrefix;
247  const char *sMemberName;
248 
250  assert(mty);
251 
252  sTypePrefix=Typemaker2_Type_GetPrefix(ty);
253  sMemberName=Typemaker2_Member_GetName(tm);
254 
255  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
256 
257  _addSortByMemberDeclaration(ty, tm, tbuf);
258  GBAS(tbuf, "{\n");
259 
260  GBAA(tbuf, " %s_Tree2_SortChildren(p_tree2, (GWEN_TREE2_COMPARE_CB)(p_ascending?%s_Tree2_Compare_%c%s_asc:%s_Tree2_Compare_%c%s_desc));\n",
261  sTypePrefix,
262  sTypePrefix, toupper(*sMemberName), sMemberName+1,
263  sTypePrefix, toupper(*sMemberName), sMemberName+1);
264  GBAS(tbuf, "}\n");
265 
267  GWEN_Buffer_free(tbuf);
268 }
269 
270 
271 
273 {
274  TYPEMAKER2_TYPE *mty;
275  const char *sTypeId;
276  const char *sTypePrefix;
277  const char *sMemberName;
278 
280  assert(mty);
281 
282  sTypeId=Typemaker2_Type_GetIdentifier(ty);
283  sTypePrefix=Typemaker2_Type_GetPrefix(ty);
284  sMemberName=Typemaker2_Member_GetName(tm);
285 
286  GBAA(tbuf,
287  "void %s_Tree2_SortChildrenBy%c%s(%s *p_tree2, int p_ascending)",
288  sTypePrefix,
289  toupper(*sMemberName),
290  sMemberName+1,
291  sTypeId);
292 }
293 
294 
295 
297 {
298  GWEN_BUFFER *tbuf;
299 
300  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
301 
302  GBAS(tbuf, "static ");
303  _addCompareMemberDeclaration(ty, tm, tbuf, ascending);
304  GBAS(tbuf, ";\n");
305 
307  GWEN_Buffer_free(tbuf);
308 }
309 
310 
311 
313 {
314  GWEN_BUFFER *tbuf;
315  TYPEMAKER2_TYPE *mty;
316  const char *sMemberName;
317 
319  assert(mty);
320 
321  sMemberName=Typemaker2_Member_GetName(tm);
322 
323  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
324 
325  _addCompareMemberDeclaration(ty, tm, tbuf, ascending);
326  GBAS(tbuf, "{\n");
327  GBAS(tbuf, " int p_rv;\n");
328  GBAS(tbuf, "\n");
329 
330  if (1) {
331  GWEN_BUFFER *dstbuf;
332  GWEN_BUFFER *srcbuf;
333  int rv;
334 
335  srcbuf=GWEN_Buffer_new(0, 256, 0, 1);
336  GBAA(srcbuf, "p_a->%s", sMemberName);
337 
338  dstbuf=GWEN_Buffer_new(0, 256, 0, 1);
339  GBAA(dstbuf, "p_b->%s", sMemberName);
340 
342  GWEN_Buffer_GetStart(srcbuf),
343  GWEN_Buffer_GetStart(dstbuf),
344  tbuf);
345  GWEN_Buffer_free(srcbuf);
346  GWEN_Buffer_free(dstbuf);
347  if (rv<0) {
348  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
349  GWEN_Buffer_free(tbuf);
350  return rv;
351  }
352  GBAS(tbuf, "\n");
353  }
354 
355  if (ascending)
356  GBAS(tbuf, " return p_rv;\n");
357  else
358  GBAS(tbuf, " return -p_rv;\n");
359  GBAS(tbuf, "}\n");
360 
362  GWEN_Buffer_free(tbuf);
363 
364  return 0;
365 }
366 
367 
368 
370 {
371  TYPEMAKER2_TYPE *mty;
372  const char *sTypeId;
373  const char *sTypePrefix;
374  const char *sMemberName;
375 
377  assert(mty);
378 
379  sTypeId=Typemaker2_Type_GetIdentifier(ty);
380  sTypePrefix=Typemaker2_Type_GetPrefix(ty);
381  sMemberName=Typemaker2_Member_GetName(tm);
382 
383  GBAA(tbuf,
384  "int GWENHYWFAR_CB %s_Tree2_Compare_%c%s_%s(const %s *p_a, const %s *p_b)",
385  sTypePrefix,
386  toupper(*sMemberName),
387  sMemberName+1,
388  ascending?"asc":"desc",
389  sTypeId,
390  sTypeId);
391 }
392 
393 
394 
int Typemaker2_Builder_Invoke_CompareFn(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, const char *src, const char *dst, GWEN_BUFFER *dbuf)
TYPEMAKER2_TYPEMANAGER * Typemaker2_Builder_GetTypeManager(const TYPEMAKER2_BUILDER *tb)
Definition: tm_builder.c:133
TYPEMAKER2_TYPE * Typemaker2_Member_GetTypePtr(const TYPEMAKER2_MEMBER *tm)
Definition: tm_member.c:467
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
static void _addGetByMemberDeclaration(TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, GWEN_BUFFER *tbuf)
Definition: tm2c_tree2.c:177
static int _addCompareMemberImplementation(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, int ascending)
Definition: tm2c_tree2.c:312
static void _addCompareMemberDeclaration(TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, GWEN_BUFFER *tbuf, int ascending)
Definition: tm2c_tree2.c:369
static void _addCompareMemberProtoType(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, int ascending)
Definition: tm2c_tree2.c:296
#define NULL
Definition: binreloc.c:300
#define GWEN_LOGDOMAIN
Definition: logger.h:32
int TM2C_BuildTree2SortByMember(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm)
Definition: tm2c_tree2.c:57
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
static void _addSortByMemberDeclaration(TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm, GWEN_BUFFER *tbuf)
Definition: tm2c_tree2.c:272
void Typemaker2_Builder_AddPrivateDeclaration(TYPEMAKER2_BUILDER *tb, const char *s)
Definition: tm_builder.c:196
static void _addSortByMemberImplementation(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm)
Definition: tm2c_tree2.c:242
#define GBAS
Definition: tm2c_tree2.c:24
#define GBAA
Definition: tm2c_tree2.c:23
const char * Typemaker2_Type_GetIdentifier(const TYPEMAKER2_TYPE *ty)
Definition: tm_type.c:585
struct TYPEMAKER2_BUILDER TYPEMAKER2_BUILDER
Definition: tm_builder.h:26
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
int TM2C_BuildTree2GetByMember(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm)
Definition: tm2c_tree2.c:41
void Typemaker2_Builder_AddCode(TYPEMAKER2_BUILDER *tb, const char *s)
Definition: tm_builder.c:204
struct TYPEMAKER2_TYPE TYPEMAKER2_TYPE
Definition: tm_type.h:21
void Typemaker2_Builder_AddPublicDeclaration(TYPEMAKER2_BUILDER *tb, const char *s)
Definition: tm_builder.c:172
struct TYPEMAKER2_TYPEMANAGER TYPEMAKER2_TYPEMANAGER
const char * Typemaker2_Type_GetPrefix(const TYPEMAKER2_TYPE *ty)
Definition: tm_type.c:607
int Typemaker2_Type_GetType(const TYPEMAKER2_TYPE *ty)
Definition: tm_type.c:171
static void _addGetByMemberProtoType(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm)
Definition: tm2c_tree2.c:82
const char * Typemaker2_TypeManager_GetApiDeclaration(const TYPEMAKER2_TYPEMANAGER *tym)
struct TYPEMAKER2_MEMBER TYPEMAKER2_MEMBER
Definition: tm_member.h:21
static int _addGetByMemberImplementation(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm)
Definition: tm2c_tree2.c:107
#define DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
static void _addSortByMemberProtoType(TYPEMAKER2_BUILDER *tb, TYPEMAKER2_TYPE *ty, TYPEMAKER2_MEMBER *tm)
Definition: tm2c_tree2.c:217
const char * Typemaker2_Member_GetName(const TYPEMAKER2_MEMBER *tm)
Definition: tm_member.c:83