NCBI C++ ToolKit
ct_dynamic.c
Go to the documentation of this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

Go to the SVN repository for this file.

1 #include <config.h>
2 
3 #include <stdarg.h>
4 #include <stdio.h>
5 
6 #if HAVE_STDLIB_H
7 #include <stdlib.h>
8 #endif /* HAVE_STDLIB_H */
9 
10 #if HAVE_STRING_H
11 #include <string.h>
12 #endif /* HAVE_STRING_H */
13 
14 #include <ctpublic.h>
15 #include "common.h"
16 
17 #include <common/test_assert.h>
18 
19 static CS_RETCODE ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * errmsg);
20 static CS_RETCODE ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
21 
22 static int verbose = 0;
23 
24 static CS_CONTEXT *ctx;
26 static CS_COMMAND *cmd;
27 static CS_COMMAND *cmd2;
28 
29 static void
30 cleanup(void)
31 {
32  CS_RETCODE ret;
33 
34  if (verbose) {
35  printf("Trying logout\n");
36  }
37 
38  if (cmd2)
40 
41  ret = try_ctlogout(ctx, conn, cmd, verbose);
42  if (ret != CS_SUCCEED) {
43  fprintf(stderr, "Logout failed\n");
44  exit(1);
45  }
46 }
47 
48 static void
49 chk(int check, const char *fmt, ...)
50 {
51  va_list ap;
52 
53  if (check)
54  return;
55 
56  va_start(ap, fmt);
57  vfprintf(stderr, fmt, ap);
58  va_end(ap);
59 
60  cleanup();
61  exit(1);
62 }
63 
64 int
65 main(int argc, char *argv[])
66 {
67  int errCode = 1;
68 
69  CS_RETCODE ret;
70  CS_RETCODE results_ret;
71  CS_CHAR cmdbuf[4096];
72  CS_CHAR name[257];
73  CS_INT datalength;
74  CS_SMALLINT ind;
75  CS_INT count;
76  CS_INT num_cols;
77  CS_INT row_count = 0;
78  CS_DATAFMT datafmt;
79  CS_DATAFMT descfmt;
80  CS_INT intvar;
81  CS_INT intvarsize;
82  CS_SMALLINT intvarind;
83  CS_INT res_type;
84 
85  int i;
86 
87  if (argc > 1 && (0 == strcmp(argv[1], "-v")))
88  verbose = 1;
89 
90  printf("%s: use ct_dynamic to prepare and execute a statement\n", __FILE__);
91  if (verbose) {
92  printf("Trying login\n");
93  }
94  ret = try_ctlogin(&ctx, &conn, &cmd, verbose);
95  if (ret != CS_SUCCEED) {
96  fprintf(stderr, "Login failed\n");
97  return 1;
98  }
99 
101 
103 
104  ret = ct_cmd_alloc(conn, &cmd2);
105  chk(ret == CS_SUCCEED, "cmd2_alloc failed\n");
106 
107  /* do not test error */
108  ret = run_command(cmd, "IF OBJECT_ID('tempdb..#ct_dynamic') IS NOT NULL DROP table #ct_dynamic");
109 
110  strcpy(cmdbuf, "create table #ct_dynamic (id numeric identity not null, \
111  name varchar(30), age int, cost money, bdate datetime, fval float) ");
112 
113  ret = run_command(cmd, cmdbuf);
114  chk(ret == CS_SUCCEED, "create table failed\n");
115 
116  strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
117  strcat(cmdbuf, "values ('Bill', 44, 2000.00, 'May 21 1960', 60.97 ) ");
118 
119  ret = run_command(cmd, cmdbuf);
120  chk(ret == CS_SUCCEED, "insert table failed\n");
121 
122  strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
123  strcat(cmdbuf, "values ('Freddy', 32, 1000.00, 'Jan 21 1972', 70.97 ) ");
124 
125  ret = run_command(cmd, cmdbuf);
126  chk(ret == CS_SUCCEED, "insert table failed\n");
127 
128  strcpy(cmdbuf, "insert into #ct_dynamic ( name , age , cost , bdate , fval ) ");
129  strcat(cmdbuf, "values ('James', 42, 5000.00, 'May 21 1962', 80.97 ) ");
130 
131  ret = run_command(cmd, cmdbuf);
132  chk(ret == CS_SUCCEED, "insert table failed\n");
133 
134  strcpy(cmdbuf, "select name from #ct_dynamic where age = ?");
135 
136  ret = ct_dynamic(cmd, CS_PREPARE, "age", CS_NULLTERM, cmdbuf, CS_NULLTERM);
137  chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
138 
139  chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_PREPARE) failed\n");
140 
141  while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
142  switch ((int) res_type) {
143 
144  case CS_CMD_SUCCEED:
145  case CS_CMD_DONE:
146  break;
147 
148  case CS_CMD_FAIL:
149  break;
150 
151  default:
152  goto ERR;
153  }
154  }
155  chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
156 
158  chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
159 
160  chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_DESCRIBE_INPUT) failed\n");
161 
162  while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
163  switch ((int) res_type) {
164 
165  case CS_DESCRIBE_RESULT:
166  ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
167  chk(ret == CS_SUCCEED, "ct_res_info() failed");
168 
169  for (i = 1; i <= num_cols; i++) {
170  ret = ct_describe(cmd, i, &descfmt);
171  chk(ret == CS_SUCCEED, "ct_describe() failed");
172  fprintf(stderr, "CS_DESCRIBE_INPUT parameter %d :\n", i);
173  if (descfmt.namelen == 0)
174  fprintf(stderr, "\t\tNo name...\n");
175  else
176  fprintf(stderr, "\t\tName = %*.*s\n", descfmt.namelen, descfmt.namelen, descfmt.name);
177  fprintf(stderr, "\t\tType = %d\n", descfmt.datatype);
178  fprintf(stderr, "\t\tLength = %d\n", descfmt.maxlength);
179  }
180  break;
181 
182  case CS_CMD_SUCCEED:
183  case CS_CMD_DONE:
184  break;
185 
186  case CS_CMD_FAIL:
187  break;
188 
189  default:
190  goto ERR;
191  }
192  }
193 
195  chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
196 
197  chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_DESCRIBE_OUTPUT) failed\n");
198 
199  while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
200  switch ((int) res_type) {
201 
202  case CS_DESCRIBE_RESULT:
203  ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
204  chk(ret == CS_SUCCEED, "ct_res_info() failed");
205  chk(num_cols == 1, "CS_DESCRIBE_OUTPUT showed %d columns , expected 1\n", num_cols);
206 
207  for (i = 1; i <= num_cols; i++) {
208  ret = ct_describe(cmd, i, &descfmt);
209  chk(ret == CS_SUCCEED, "ct_describe() failed");
210 
211  if (descfmt.namelen == 0)
212  fprintf(stderr, "\t\tNo name...\n");
213  else
214  fprintf(stderr, "\t\tName = %*.*s\n", descfmt.namelen, descfmt.namelen, descfmt.name);
215  fprintf(stderr, "\t\tType = %d\n", descfmt.datatype);
216  fprintf(stderr, "\t\tLength = %d\n", descfmt.maxlength);
217  }
218  break;
219 
220  case CS_CMD_SUCCEED:
221  case CS_CMD_DONE:
222  break;
223 
224  case CS_CMD_FAIL:
225  break;
226 
227  default:
228  goto ERR;
229  }
230  }
231 
232  /* execute dynamic on a second command to check it still works */
234  chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
235 
236  intvar = 44;
237  intvarsize = 4;
238  intvarind = 0;
239 
240  datafmt.name[0] = 0;
241  datafmt.namelen = 0;
242  datafmt.datatype = CS_INT_TYPE;
243  datafmt.status = CS_INPUTVALUE;
244 
245  ret = ct_setparam(cmd2, &datafmt, (CS_VOID *) & intvar, &intvarsize, &intvarind);
246  chk(ret == CS_SUCCEED, "ct_setparam(int) failed\n");
247 
248  chk(ct_send(cmd2) == CS_SUCCEED, "ct_send(CS_EXECUTE) failed\n");
249 
250  while ((results_ret = ct_results(cmd2, &res_type)) == CS_SUCCEED) {
251  chk(res_type != CS_CMD_FAIL, "1: ct_results() result_type CS_CMD_FAIL.\n");
252  chk(res_type != CS_COMPUTE_RESULT, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
253 
254  switch ((int) res_type) {
255  case CS_CMD_SUCCEED:
256  break;
257  case CS_CMD_DONE:
258  break;
259  case CS_ROW_RESULT:
260  datafmt.datatype = CS_CHAR_TYPE;
261  datafmt.format = CS_FMT_NULLTERM;
262  datafmt.maxlength = 256;
263  datafmt.count = 1;
264  datafmt.locale = NULL;
265  ret = ct_bind(cmd2, 1, &datafmt, name, &datalength, &ind);
266  chk(ret == CS_SUCCEED, "ct_bind() failed\n");
267 
268  while (((ret = ct_fetch(cmd2, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
269  || (ret == CS_ROW_FAIL)) {
270  row_count += count;
271  chk(ret != CS_ROW_FAIL, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
272  if (ret == CS_SUCCEED) {
273  chk(!strcmp(name, "Bill"), "fetched value '%s' expected 'Bill'\n", name);
274  } else {
275  break;
276  }
277  }
278  chk(ret == CS_END_DATA, "ct_fetch() unexpected return %d.\n", (int) ret);
279  break;
280  default:
281  fprintf(stderr, "ct_results() unexpected result_type.\n");
282  return 1;
283  }
284  }
285  chk(results_ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) results_ret);
286 
287  intvar = 32;
288 
289  chk(ct_send(cmd2) == CS_SUCCEED, "ct_send(CS_EXECUTE) failed\n");
290 
291  while ((results_ret = ct_results(cmd2, &res_type)) == CS_SUCCEED) {
292  chk(res_type != CS_CMD_FAIL, "2: ct_results() result_type CS_CMD_FAIL.\n");
293  chk(res_type != CS_COMPUTE_RESULT, "ct_results() unexpected CS_COMPUTE_RESULT.\n");
294 
295  switch ((int) res_type) {
296  case CS_CMD_SUCCEED:
297  break;
298  case CS_CMD_DONE:
299  break;
300  case CS_ROW_RESULT:
301  datafmt.datatype = CS_CHAR_TYPE;
302  datafmt.format = CS_FMT_NULLTERM;
303  datafmt.maxlength = 256;
304  datafmt.count = 1;
305  datafmt.locale = NULL;
306  ret = ct_bind(cmd2, 1, &datafmt, name, &datalength, &ind);
307  chk(ret == CS_SUCCEED, "ct_bind() failed\n");
308 
309  while (((ret = ct_fetch(cmd2, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
310  || (ret == CS_ROW_FAIL)) {
311  row_count += count;
312  chk(ret != CS_ROW_FAIL, "ct_fetch() CS_ROW_FAIL on row %d.\n", row_count);
313 
314  if (ret == CS_SUCCEED) {
315  chk(!strcmp(name, "Freddy"), "fetched value '%s' expected 'Freddy'\n", name);
316  } else {
317  break;
318  }
319  }
320  chk(ret == CS_END_DATA, "ct_fetch() unexpected return %d.\n", (int) ret);
321  break;
322  default:
323  fprintf(stderr, "ct_results() unexpected result_type.\n");
324  return 1;
325  }
326  }
327  chk(results_ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) results_ret);
328 
330  chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
331 
332  chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_DEALLOC) failed\n");
333 
334  while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
335  switch ((int) res_type) {
336 
337  case CS_CMD_SUCCEED:
338  case CS_CMD_DONE:
339  break;
340 
341  case CS_CMD_FAIL:
342  break;
343 
344  default:
345  goto ERR;
346  }
347  }
348  chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
349 
350  /*
351  * check we can prepare again dynamic with same name after deallocation
352  */
353  strcpy(cmdbuf, "select name from #ct_dynamic where age = ?");
354  ret = ct_dynamic(cmd, CS_PREPARE, "age", CS_NULLTERM, cmdbuf, CS_NULLTERM);
355  chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
356 
357  chk(ct_send(cmd) == CS_SUCCEED, "ct_send(CS_PREPARE) failed\n");
358 
359  while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
360  switch ((int) res_type) {
361 
362  case CS_CMD_SUCCEED:
363  case CS_CMD_DONE:
364  break;
365 
366  case CS_CMD_FAIL:
367  break;
368 
369  default:
370  goto ERR;
371  }
372  }
373  chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
374 
376  ct_send(cmd);
377  while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED)
378  chk(res_type != CS_ROW_RESULT, "Rows not expected\n");
379  chk(ret == CS_END_RESULTS, "ct_results() unexpected return.\n", (int) ret);
380 
382  chk(ret == CS_SUCCEED, "ct_dynamic failed\n");
383 
384  intvar = 32;
385  intvarsize = 4;
386  intvarind = 0;
387 
388  datafmt.name[0] = 0;
389  datafmt.namelen = 0;
390  datafmt.datatype = CS_INT_TYPE;
391  datafmt.status = CS_INPUTVALUE;
392 
393  ret = ct_setparam(cmd2, &datafmt, (CS_VOID *) & intvar, &intvarsize, &intvarind);
394  chk(ct_send(cmd2) == CS_SUCCEED, "ct_send(CS_EXECUTE) failed\n");
395 
396  /* all tests succeeded */
397  errCode = 0;
398 
399  ERR:
400  cleanup();
401  return errCode;
402 }
403 
404 
405 static CS_RETCODE
406 ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg)
407 {
408  printf("\nOpen Client Message:\n");
409  printf("Message number: LAYER = (%d) ORIGIN = (%d) ", CS_LAYER(errmsg->msgnumber), CS_ORIGIN(errmsg->msgnumber));
410  printf("SEVERITY = (%d) NUMBER = (%d)\n", CS_SEVERITY(errmsg->msgnumber), CS_NUMBER(errmsg->msgnumber));
411  printf("Message String: %s\n", errmsg->msgstring);
412  if (errmsg->osstringlen > 0) {
413  printf("Operating System Error: %s\n", errmsg->osstring);
414  }
415  fflush(stdout);
416 
417  return CS_SUCCEED;
418 }
419 
420 static CS_RETCODE
421 ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * srvmsg)
422 {
423  printf("\nServer message:\n");
424  printf("Message number: %d, Severity %d, ", srvmsg->msgnumber, srvmsg->severity);
425  printf("State %d, Line %d\n", srvmsg->state, srvmsg->line);
426 
427  if (srvmsg->svrnlen > 0) {
428  printf("Server '%s'\n", srvmsg->svrname);
429  }
430 
431  if (srvmsg->proclen > 0) {
432  printf(" Procedure '%s'\n", srvmsg->proc);
433  }
434 
435  printf("Message String: %s\n", srvmsg->text);
436  fflush(stdout);
437 
438  return CS_SUCCEED;
439 }
#define CS_SERVERMSG_CB
Definition: cspublic.h:411
#define CS_CMD_DONE
Definition: cspublic.h:436
#define CS_CLIENTMSG_CB
Definition: cspublic.h:412
#define CS_CMD_SUCCEED
Definition: cspublic.h:437
#define CS_INPUTVALUE
Definition: cspublic.h:293
@ CS_FMT_NULLTERM
Definition: cspublic.h:399
#define CS_DESCRIBE_OUTPUT
Definition: cspublic.h:504
#define CS_NUMBER(x)
Definition: cspublic.h:66
#define CS_DEALLOC
Definition: cspublic.h:506
#define CS_CHAR_TYPE
Definition: cspublic.h:550
#define CS_INT_TYPE
Definition: cspublic.h:558
#define CS_EXECUTE
Definition: cspublic.h:502
#define CS_LAYER(x)
Definition: cspublic.h:63
#define CS_UNUSED
Definition: cspublic.h:425
#define CS_END_DATA
Definition: cspublic.h:55
#define CS_SET
Definition: cspublic.h:429
#define CS_DESCRIBE_RESULT
Definition: cspublic.h:546
#define CS_ROW_RESULT
Definition: cspublic.h:541
#define CS_COMPUTE_RESULT
Definition: cspublic.h:538
#define CS_SEVERITY(x)
Definition: cspublic.h:65
#define CS_ROW_FAIL
Definition: cspublic.h:54
#define CS_SUCCEED
Definition: cspublic.h:40
#define CS_CMD_FAIL
Definition: cspublic.h:438
#define CS_NULLTERM
Definition: cspublic.h:422
#define CS_PREPARE
Definition: cspublic.h:501
#define CS_DESCRIBE_INPUT
Definition: cspublic.h:503
#define CS_ORIGIN(x)
Definition: cspublic.h:64
#define CS_END_RESULTS
Definition: cspublic.h:56
#define CS_NUMDATA
Definition: cspublic.h:472
Int4 CS_INT
Definition: cstypes.h:41
Int2 CS_SMALLINT
Definition: cstypes.h:45
void CS_VOID
Definition: cstypes.h:53
CS_INT CS_RETCODE
Definition: cstypes.h:63
char CS_CHAR
Definition: cstypes.h:48
static CS_RETCODE ex_clientmsg_cb(CS_CONTEXT *context, CS_CONNECTION *connection, CS_CLIENTMSG *errmsg)
Definition: ct_dynamic.c:406
int main(int argc, char *argv[])
Definition: ct_dynamic.c:65
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
static CS_CONTEXT * ctx
Definition: ct_dynamic.c:24
static CS_RETCODE ex_servermsg_cb(CS_CONTEXT *context, CS_CONNECTION *connection, CS_SERVERMSG *errmsg)
Definition: ct_dynamic.c:421
static void cleanup(void)
Definition: ct_dynamic.c:30
static CS_COMMAND * cmd2
Definition: ct_dynamic.c:27
static void chk(int check, const char *fmt,...)
Definition: ct_dynamic.c:49
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
CS_RETCODE try_ctlogin(CS_CONTEXT **ctx, CS_CONNECTION **conn, CS_COMMAND **cmd, int verbose)
Definition: common.c:194
CS_RETCODE run_command(CS_COMMAND *cmd, const char *sql)
Definition: common.c:330
CS_RETCODE try_ctlogout(CS_CONTEXT *ctx, CS_CONNECTION *conn, CS_COMMAND *cmd, int verbose)
Definition: common.c:308
CS_RETCODE ct_dynamic(CS_COMMAND *cmd, CS_INT type, CS_CHAR *id, CS_INT idlen, CS_CHAR *buffer, CS_INT buflen)
Definition: ct.c:3300
CS_RETCODE ct_results(CS_COMMAND *cmd, CS_INT *result_type)
Definition: ct.c:1172
CS_RETCODE ct_res_info(CS_COMMAND *cmd, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *out_len)
Definition: ct.c:2491
CS_RETCODE ct_callback(CS_CONTEXT *ctx, CS_CONNECTION *con, CS_INT action, CS_INT type, CS_VOID *func)
Definition: ct.c:306
CS_RETCODE ct_fetch(CS_COMMAND *cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT *rows_read)
Definition: ct.c:1589
CS_RETCODE ct_cmd_drop(CS_COMMAND *cmd)
Definition: ct.c:1881
CS_RETCODE ct_cmd_alloc(CS_CONNECTION *con, CS_COMMAND **cmd)
Definition: ct.c:728
CS_RETCODE ct_send(CS_COMMAND *cmd)
Definition: ct.c:913
CS_RETCODE ct_bind(CS_COMMAND *cmd, CS_INT item, CS_DATAFMT *datafmt, CS_VOID *buffer, CS_INT *copied, CS_SMALLINT *indicator)
Definition: ct.c:1531
CS_RETCODE ct_describe(CS_COMMAND *cmd, CS_INT item, CS_DATAFMT *datafmt)
Definition: ct.c:2424
CS_RETCODE ct_setparam(CS_COMMAND *cmd, CS_DATAFMT *datafmt, CS_VOID *data, CS_INT *datalen, CS_SMALLINT *indicator)
Definition: ct.c:3491
#define check(s)
Definition: describecol2.c:21
#define NULL
Definition: ncbistd.hpp:225
exit(2)
int i
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
true_type verbose
Definition: processing.cpp:890
#define strcat(s, k)
CS_CHAR osstring[1024]
Definition: cstypes.h:191
CS_MSGNUM msgnumber
Definition: cstypes.h:187
CS_CHAR msgstring[1024]
Definition: cstypes.h:188
CS_INT osstringlen
Definition: cstypes.h:192
CS_LOCALE * locale
Definition: cstypes.h:133
CS_INT format
Definition: cstypes.h:126
CS_INT maxlength
Definition: cstypes.h:127
CS_INT count
Definition: cstypes.h:131
CS_INT datatype
Definition: cstypes.h:125
CS_INT namelen
Definition: cstypes.h:124
CS_CHAR name[132]
Definition: cstypes.h:123
CS_INT status
Definition: cstypes.h:130
CS_CHAR proc[132]
Definition: cstypes.h:207
CS_CHAR text[1024]
Definition: cstypes.h:203
CS_MSGNUM msgnumber
Definition: cstypes.h:200
CS_INT line
Definition: cstypes.h:209
CS_INT svrnlen
Definition: cstypes.h:206
CS_CHAR svrname[132]
Definition: cstypes.h:205
CS_INT severity
Definition: cstypes.h:202
CS_INT proclen
Definition: cstypes.h:208
CS_INT state
Definition: cstypes.h:201
Modified on Tue Apr 09 07:57:01 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 10 07:32:26 2024 by modify_doxy.py rev. 669887
Modified on Thu Apr 11 15:04:50 2024 by modify_doxy.py rev. 669887
Modified on Fri Apr 12 17:16:59 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 13 11:45:09 2024 by modify_doxy.py rev. 669887
Modified on Sun Apr 14 05:25:46 2024 by modify_doxy.py rev. 669887
Modified on Tue Apr 16 20:09:10 2024 by modify_doxy.py rev. 669887
Modified on Wed Apr 17 13:08:54 2024 by modify_doxy.py rev. 669887
Modified on Sat Apr 20 12:16:35 2024 by modify_doxy.py rev. 669887
Modified on Sun Apr 21 03:39:45 2024 by modify_doxy.py rev. 669887